diff --git a/doc/man7/provider-cipher.pod b/doc/man7/provider-cipher.pod index 87ab3d844d..2e2e73b68b 100644 --- a/doc/man7/provider-cipher.pod +++ b/doc/man7/provider-cipher.pod @@ -314,6 +314,10 @@ OP_cipher_final(), OP_cipher_cipher(), OP_cipher_get_params(), OP_cipher_get_ctx_params() and OP_cipher_set_ctx_params() should return 1 for success or 0 on error. +OP_cipher_gettable_params(), OP_cipher_gettable_ctx_params() and +OP_cipher_settable_ctx_params() should return a constant B +array, or NULL if none is offered. + =head1 SEE ALSO L diff --git a/include/openssl/core_numbers.h b/include/openssl/core_numbers.h index 95cfe46a2d..e39410893e 100644 --- a/include/openssl/core_numbers.h +++ b/include/openssl/core_numbers.h @@ -98,7 +98,8 @@ OSSL_CORE_MAKE_FUNC(void *, CRYPTO_realloc, (void *addr, size_t num, const char *file, int line)) #define OSSL_FUNC_CRYPTO_CLEAR_REALLOC 15 OSSL_CORE_MAKE_FUNC(void *, - CRYPTO_clear_realloc, (void *addr, size_t old_num, size_t num, const char *file, int line)) + CRYPTO_clear_realloc, (void *addr, size_t old_num, size_t num, + const char *file, int line)) #define OSSL_FUNC_CRYPTO_SECURE_MALLOC 16 OSSL_CORE_MAKE_FUNC(void *, CRYPTO_secure_malloc, (size_t num, const char *file, int line)) @@ -110,7 +111,8 @@ OSSL_CORE_MAKE_FUNC(void, CRYPTO_secure_free, (void *ptr, const char *file, int line)) #define OSSL_FUNC_CRYPTO_SECURE_CLEAR_FREE 19 OSSL_CORE_MAKE_FUNC(void, - CRYPTO_secure_clear_free, (void *ptr, size_t num, const char *file, int line)) + CRYPTO_secure_clear_free, (void *ptr, size_t num, const char *file, + int line)) #define OSSL_FUNC_CRYPTO_SECURE_ALLOCATED 20 OSSL_CORE_MAKE_FUNC(int, CRYPTO_secure_allocated, (const void *ptr)) @@ -146,9 +148,17 @@ OSSL_CORE_MAKE_FUNC(const OSSL_ALGORITHM *,provider_query_operation, OSSL_CORE_MAKE_FUNC(const OSSL_ITEM *,provider_get_reason_strings, (void *provctx)) -/* Digests */ +/* Operations */ # define OSSL_OP_DIGEST 1 +# define OSSL_OP_CIPHER 2 /* Symmetric Ciphers */ +# define OSSL_OP_MAC 3 +# define OSSL_OP_KEYMGMT 10 +# define OSSL_OP_KEYEXCH 11 +/* Highest known operation number */ +# define OSSL_OP__HIGHEST 11 + +/* Digests */ # define OSSL_FUNC_DIGEST_NEWCTX 1 # define OSSL_FUNC_DIGEST_INIT 2 @@ -189,8 +199,6 @@ OSSL_CORE_MAKE_FUNC(const OSSL_PARAM *, OP_digest_gettable_ctx_params, (void)) /* Symmetric Ciphers */ -# define OSSL_OP_CIPHER 2 - # define OSSL_FUNC_CIPHER_NEWCTX 1 # define OSSL_FUNC_CIPHER_ENCRYPT_INIT 2 # define OSSL_FUNC_CIPHER_DECRYPT_INIT 3 @@ -235,29 +243,24 @@ OSSL_CORE_MAKE_FUNC(int, OP_cipher_get_ctx_params, (void *cctx, OSSL_PARAM params[])) OSSL_CORE_MAKE_FUNC(int, OP_cipher_set_ctx_params, (void *cctx, const OSSL_PARAM params[])) -OSSL_CORE_MAKE_FUNC(const OSSL_PARAM *, OP_cipher_gettable_params, - (void)) -OSSL_CORE_MAKE_FUNC(const OSSL_PARAM *, OP_cipher_settable_ctx_params, - (void)) -OSSL_CORE_MAKE_FUNC(const OSSL_PARAM *, OP_cipher_gettable_ctx_params, - (void)) +OSSL_CORE_MAKE_FUNC(const OSSL_PARAM *, OP_cipher_gettable_params, (void)) +OSSL_CORE_MAKE_FUNC(const OSSL_PARAM *, OP_cipher_settable_ctx_params, (void)) +OSSL_CORE_MAKE_FUNC(const OSSL_PARAM *, OP_cipher_gettable_ctx_params, (void)) /* MACs */ -# define OSSL_OP_MAC 3 - # define OSSL_FUNC_MAC_NEWCTX 1 # define OSSL_FUNC_MAC_DUPCTX 2 # define OSSL_FUNC_MAC_FREECTX 3 # define OSSL_FUNC_MAC_INIT 4 # define OSSL_FUNC_MAC_UPDATE 5 # define OSSL_FUNC_MAC_FINAL 6 -# define OSSL_FUNC_MAC_GETTABLE_PARAMS 7 -# define OSSL_FUNC_MAC_GETTABLE_CTX_PARAMS 8 -# define OSSL_FUNC_MAC_SETTABLE_CTX_PARAMS 9 -# define OSSL_FUNC_MAC_GET_PARAMS 10 -# define OSSL_FUNC_MAC_GET_CTX_PARAMS 11 -# define OSSL_FUNC_MAC_SET_CTX_PARAMS 12 +# define OSSL_FUNC_MAC_GET_PARAMS 7 +# define OSSL_FUNC_MAC_GET_CTX_PARAMS 8 +# define OSSL_FUNC_MAC_SET_CTX_PARAMS 9 +# define OSSL_FUNC_MAC_GETTABLE_PARAMS 10 +# define OSSL_FUNC_MAC_GETTABLE_CTX_PARAMS 11 +# define OSSL_FUNC_MAC_SETTABLE_CTX_PARAMS 12 OSSL_CORE_MAKE_FUNC(void *, OP_mac_newctx, (void *provctx)) OSSL_CORE_MAKE_FUNC(void *, OP_mac_dupctx, (void *src)) @@ -299,8 +302,6 @@ OSSL_CORE_MAKE_FUNC(int, OP_mac_set_ctx_params, * THE CALLER MUST ENSURE THAT A CORRECT IDENTITY IS USED. */ -# define OSSL_OP_KEYMGMT 10 - /* Key domain parameter creation and destruction */ # define OSSL_FUNC_KEYMGMT_IMPORTDOMPARAMS 1 # define OSSL_FUNC_KEYMGMT_GENDOMPARAMS 2 @@ -351,8 +352,6 @@ OSSL_CORE_MAKE_FUNC(const OSSL_PARAM *, OP_keymgmt_exportkey_types, (void)) /* Key Exchange */ -# define OSSL_OP_KEYEXCH 11 - # define OSSL_FUNC_KEYEXCH_NEWCTX 1 # define OSSL_FUNC_KEYEXCH_INIT 2 # define OSSL_FUNC_KEYEXCH_DERIVE 3 @@ -371,9 +370,6 @@ OSSL_CORE_MAKE_FUNC(void *, OP_keyexch_dupctx, (void *ctx)) OSSL_CORE_MAKE_FUNC(int, OP_keyexch_set_params, (void *ctx, const OSSL_PARAM params[])) -/* Highest known operation number */ -# define OSSL_OP__HIGHEST 3 - # ifdef __cplusplus } # endif diff --git a/providers/common/ciphers/aes.c b/providers/common/ciphers/aes.c index c7ab30de23..26b8c4475a 100644 --- a/providers/common/ciphers/aes.c +++ b/providers/common/ciphers/aes.c @@ -38,7 +38,7 @@ static int PROV_AES_KEY_generic_init(PROV_AES_KEY *ctx, { if (iv != NULL && ctx->mode != EVP_CIPH_ECB_MODE) { if (ivlen != AES_BLOCK_SIZE) { - PROVerr(PROV_F_PROV_AES_KEY_GENERIC_INIT, ERR_R_INTERNAL_ERROR); + ERR_raise(ERR_LIB_PROV, ERR_R_INTERNAL_ERROR); return 0; } memcpy(ctx->iv, iv, AES_BLOCK_SIZE); @@ -54,12 +54,12 @@ static int aes_einit(void *vctx, const unsigned char *key, size_t keylen, PROV_AES_KEY *ctx = (PROV_AES_KEY *)vctx; if (!PROV_AES_KEY_generic_init(ctx, iv, ivlen, 1)) { - /* PROVerr already called */ + /* ERR_raise already called */ return 0; } if (key != NULL) { if (keylen != ctx->keylen) { - PROVerr(PROV_F_AES_EINIT, PROV_R_INVALID_KEY_LENGTH); + ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_KEY_LENGTH); return 0; } return ctx->ciph->init(ctx, key, ctx->keylen); @@ -74,12 +74,12 @@ static int aes_dinit(void *vctx, const unsigned char *key, size_t keylen, PROV_AES_KEY *ctx = (PROV_AES_KEY *)vctx; if (!PROV_AES_KEY_generic_init(ctx, iv, ivlen, 0)) { - /* PROVerr already called */ + /* ERR_raise already called */ return 0; } if (key != NULL) { if (keylen != ctx->keylen) { - PROVerr(PROV_F_AES_DINIT, PROV_R_INVALID_KEY_LENGTH); + ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_KEY_LENGTH); return 0; } return ctx->ciph->init(ctx, key, ctx->keylen); @@ -104,11 +104,11 @@ static int aes_block_update(void *vctx, unsigned char *out, size_t *outl, if (ctx->bufsz == AES_BLOCK_SIZE && (ctx->enc || inl > 0 || !ctx->pad)) { if (outsize < AES_BLOCK_SIZE) { - PROVerr(PROV_F_AES_BLOCK_UPDATE, PROV_R_OUTPUT_BUFFER_TOO_SMALL); + ERR_raise(ERR_LIB_PROV, PROV_R_OUTPUT_BUFFER_TOO_SMALL); return 0; } if (!ctx->ciph->cipher(ctx, out, ctx->buf, AES_BLOCK_SIZE)) { - PROVerr(PROV_F_AES_BLOCK_UPDATE, PROV_R_CIPHER_OPERATION_FAILED); + ERR_raise(ERR_LIB_PROV, PROV_R_CIPHER_OPERATION_FAILED); return 0; } ctx->bufsz = 0; @@ -118,25 +118,25 @@ static int aes_block_update(void *vctx, unsigned char *out, size_t *outl, if (nextblocks > 0) { if (!ctx->enc && ctx->pad && nextblocks == inl) { if (!ossl_assert(inl >= AES_BLOCK_SIZE)) { - PROVerr(PROV_F_AES_BLOCK_UPDATE, PROV_R_OUTPUT_BUFFER_TOO_SMALL); + ERR_raise(ERR_LIB_PROV, PROV_R_OUTPUT_BUFFER_TOO_SMALL); return 0; } nextblocks -= AES_BLOCK_SIZE; } outlint += nextblocks; if (outsize < outlint) { - PROVerr(PROV_F_AES_BLOCK_UPDATE, PROV_R_OUTPUT_BUFFER_TOO_SMALL); + ERR_raise(ERR_LIB_PROV, PROV_R_OUTPUT_BUFFER_TOO_SMALL); return 0; } if (!ctx->ciph->cipher(ctx, out, in, nextblocks)) { - PROVerr(PROV_F_AES_BLOCK_UPDATE, PROV_R_CIPHER_OPERATION_FAILED); + ERR_raise(ERR_LIB_PROV, PROV_R_CIPHER_OPERATION_FAILED); return 0; } in += nextblocks; inl -= nextblocks; } if (!trailingdata(ctx->buf, &ctx->bufsz, AES_BLOCK_SIZE, &in, &inl)) { - /* PROVerr already called */ + /* ERR_raise already called */ return 0; } @@ -156,16 +156,16 @@ static int aes_block_final(void *vctx, unsigned char *out, size_t *outl, *outl = 0; return 1; } else if (ctx->bufsz != AES_BLOCK_SIZE) { - PROVerr(PROV_F_AES_BLOCK_FINAL, PROV_R_WRONG_FINAL_BLOCK_LENGTH); + ERR_raise(ERR_LIB_PROV, PROV_R_WRONG_FINAL_BLOCK_LENGTH); return 0; } if (outsize < AES_BLOCK_SIZE) { - PROVerr(PROV_F_AES_BLOCK_FINAL, PROV_R_OUTPUT_BUFFER_TOO_SMALL); + ERR_raise(ERR_LIB_PROV, PROV_R_OUTPUT_BUFFER_TOO_SMALL); return 0; } if (!ctx->ciph->cipher(ctx, out, ctx->buf, AES_BLOCK_SIZE)) { - PROVerr(PROV_F_AES_BLOCK_FINAL, PROV_R_CIPHER_OPERATION_FAILED); + ERR_raise(ERR_LIB_PROV, PROV_R_CIPHER_OPERATION_FAILED); return 0; } ctx->bufsz = 0; @@ -179,22 +179,22 @@ static int aes_block_final(void *vctx, unsigned char *out, size_t *outl, *outl = 0; return 1; } - PROVerr(PROV_F_AES_BLOCK_FINAL, PROV_R_WRONG_FINAL_BLOCK_LENGTH); + ERR_raise(ERR_LIB_PROV, PROV_R_WRONG_FINAL_BLOCK_LENGTH); return 0; } if (!ctx->ciph->cipher(ctx, ctx->buf, ctx->buf, AES_BLOCK_SIZE)) { - PROVerr(PROV_F_AES_BLOCK_FINAL, PROV_R_CIPHER_OPERATION_FAILED); + ERR_raise(ERR_LIB_PROV, PROV_R_CIPHER_OPERATION_FAILED); return 0; } if (ctx->pad && !unpadblock(ctx->buf, &ctx->bufsz, AES_BLOCK_SIZE)) { - /* PROVerr already called */ + /* ERR_raise already called */ return 0; } if (outsize < ctx->bufsz) { - PROVerr(PROV_F_AES_BLOCK_FINAL, PROV_R_OUTPUT_BUFFER_TOO_SMALL); + ERR_raise(ERR_LIB_PROV, PROV_R_OUTPUT_BUFFER_TOO_SMALL); return 0; } memcpy(out, ctx->buf, ctx->bufsz); @@ -210,12 +210,12 @@ static int aes_stream_update(void *vctx, unsigned char *out, size_t *outl, PROV_AES_KEY *ctx = (PROV_AES_KEY *)vctx; if (outsize < inl) { - PROVerr(PROV_F_AES_STREAM_UPDATE, PROV_R_OUTPUT_BUFFER_TOO_SMALL); + ERR_raise(ERR_LIB_PROV, PROV_R_OUTPUT_BUFFER_TOO_SMALL); return 0; } if (!ctx->ciph->cipher(ctx, out, in, inl)) { - PROVerr(PROV_F_AES_STREAM_UPDATE, PROV_R_CIPHER_OPERATION_FAILED); + ERR_raise(ERR_LIB_PROV, PROV_R_CIPHER_OPERATION_FAILED); return 0; } @@ -236,12 +236,12 @@ static int aes_cipher(void *vctx, PROV_AES_KEY *ctx = (PROV_AES_KEY *)vctx; if (outsize < inl) { - PROVerr(PROV_F_AES_CIPHER, PROV_R_OUTPUT_BUFFER_TOO_SMALL); + ERR_raise(ERR_LIB_PROV, PROV_R_OUTPUT_BUFFER_TOO_SMALL); return 0; } if (!ctx->ciph->cipher(ctx, out, in, inl)) { - PROVerr(PROV_F_AES_CIPHER, PROV_R_CIPHER_OPERATION_FAILED); + ERR_raise(ERR_LIB_PROV, PROV_R_CIPHER_OPERATION_FAILED); return 0; } @@ -261,35 +261,97 @@ static void *aes_new_ctx(void *provctx, size_t mode, size_t kbits, return ctx; } -int aes_get_params(OSSL_PARAM params[], int md, unsigned long flags, - int kbits, int blkbits, int ivbits) +static void aes_freectx(void *vctx) { + PROV_AES_KEY *ctx = (PROV_AES_KEY *)vctx; + + OPENSSL_clear_free(ctx, sizeof(*ctx)); +} + +static void *aes_dupctx(void *ctx) +{ + PROV_AES_KEY *in = (PROV_AES_KEY *)ctx; + PROV_AES_KEY *ret = OPENSSL_malloc(sizeof(*ret)); + + if (ret == NULL) { + ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); + return NULL; + } + *ret = *in; + + return ret; +} + +static int aes_get_ctx_params(void *vctx, OSSL_PARAM params[]) +{ + PROV_AES_KEY *ctx = (PROV_AES_KEY *)vctx; OSSL_PARAM *p; - p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_MODE); - if (p != NULL) { - if (!OSSL_PARAM_set_int(p, md)) - return 0; + p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_IVLEN); + if (p != NULL && !OSSL_PARAM_set_int(p, AES_BLOCK_SIZE)) { + ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER); + return 0; } - p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_FLAGS); - if (p != NULL) { - if (!OSSL_PARAM_set_ulong(p, flags)) - return 0; + p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_PADDING); + if (p != NULL && !OSSL_PARAM_set_int(p, ctx->pad)) { + ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER); + return 0; + } + p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_IV); + if (p != NULL + && !OSSL_PARAM_set_octet_ptr(p, &ctx->iv, AES_BLOCK_SIZE) + && !OSSL_PARAM_set_octet_string(p, &ctx->iv, AES_BLOCK_SIZE)) { + ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER); + return 0; + } + p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_NUM); + if (p != NULL && !OSSL_PARAM_set_size_t(p, ctx->num)) { + ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER); + return 0; } p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_KEYLEN); - if (p != NULL) { - if (!OSSL_PARAM_set_int(p, kbits / 8)) - return 0; + if (p != NULL && !OSSL_PARAM_set_int(p, ctx->keylen)) { + ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER); + return 0; } - p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_BLOCK_SIZE); + + return 1; +} + +static int aes_set_ctx_params(void *vctx, const OSSL_PARAM params[]) +{ + PROV_AES_KEY *ctx = (PROV_AES_KEY *)vctx; + const OSSL_PARAM *p; + + p = OSSL_PARAM_locate_const(params, OSSL_CIPHER_PARAM_PADDING); if (p != NULL) { - if (!OSSL_PARAM_set_int(p, blkbits / 8)) + int pad; + + if (!OSSL_PARAM_get_int(p, &pad)) { + ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER); return 0; + } + ctx->pad = pad ? 1 : 0; } - p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_IVLEN); + p = OSSL_PARAM_locate_const(params, OSSL_CIPHER_PARAM_NUM); if (p != NULL) { - if (!OSSL_PARAM_set_int(p, ivbits / 8)) + int num; + + if (!OSSL_PARAM_get_int(p, &num)) { + ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER); return 0; + } + ctx->num = num; + } + p = OSSL_PARAM_locate_const(params, OSSL_CIPHER_PARAM_KEYLEN); + if (p != NULL) { + int keylen; + + if (!OSSL_PARAM_get_int(p, &keylen)) { + ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER); + return 0; + } + ctx->keylen = keylen; } return 1; } @@ -298,8 +360,8 @@ int aes_get_params(OSSL_PARAM params[], int md, unsigned long flags, static OSSL_OP_cipher_get_params_fn aes_##kbits##_##lcmode##_get_params; \ static int aes_##kbits##_##lcmode##_get_params(OSSL_PARAM params[]) \ { \ - return aes_get_params(params, EVP_CIPH_##UCMODE##_MODE, flags, kbits, \ - blkbits, ivbits); \ + return cipher_default_get_params(params, EVP_CIPH_##UCMODE##_MODE, \ + flags, kbits, blkbits, ivbits); \ } \ static OSSL_OP_cipher_newctx_fn aes_##kbits##_##lcmode##_newctx; \ static void *aes_##kbits##_##lcmode##_newctx(void *provctx) \ @@ -339,166 +401,59 @@ IMPLEMENT_cipher(ctr, CTR, 0, 256, 8, 128) IMPLEMENT_cipher(ctr, CTR, 0, 192, 8, 128) IMPLEMENT_cipher(ctr, CTR, 0, 128, 8, 128) -static void aes_freectx(void *vctx) -{ - PROV_AES_KEY *ctx = (PROV_AES_KEY *)vctx; - OPENSSL_clear_free(ctx, sizeof(*ctx)); -} - -static void *aes_dupctx(void *ctx) -{ - PROV_AES_KEY *in = (PROV_AES_KEY *)ctx; - PROV_AES_KEY *ret = OPENSSL_malloc(sizeof(*ret)); - - if (ret == NULL) { - PROVerr(PROV_F_AES_DUPCTX, ERR_R_MALLOC_FAILURE); - return NULL; - } - *ret = *in; - - return ret; -} - -static int aes_get_ctx_params(void *vctx, OSSL_PARAM params[]) -{ - PROV_AES_KEY *ctx = (PROV_AES_KEY *)vctx; - OSSL_PARAM *p; - - p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_IVLEN); - if (p != NULL) { - if (!OSSL_PARAM_set_int(p, AES_BLOCK_SIZE)) - return 0; - } - p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_PADDING); - if (p != NULL && !OSSL_PARAM_set_int(p, ctx->pad)) { - PROVerr(PROV_F_AES_GET_CTX_PARAMS, PROV_R_FAILED_TO_SET_PARAMETER); - return 0; - } - p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_IV); - if (p != NULL - && !OSSL_PARAM_set_octet_ptr(p, &ctx->iv, AES_BLOCK_SIZE) - && !OSSL_PARAM_set_octet_string(p, &ctx->iv, AES_BLOCK_SIZE)) { - PROVerr(PROV_F_AES_GET_CTX_PARAMS, - PROV_R_FAILED_TO_SET_PARAMETER); - return 0; - } - p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_NUM); - if (p != NULL && !OSSL_PARAM_set_size_t(p, ctx->num)) { - PROVerr(PROV_F_AES_GET_CTX_PARAMS, - PROV_R_FAILED_TO_SET_PARAMETER); - return 0; - } - p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_KEYLEN); - if (p != NULL && !OSSL_PARAM_set_int(p, ctx->keylen)) { - PROVerr(PROV_F_AES_GET_CTX_PARAMS, - PROV_R_FAILED_TO_SET_PARAMETER); - return 0; - } - - return 1; -} - -static int aes_set_ctx_params(void *vctx, const OSSL_PARAM params[]) -{ - PROV_AES_KEY *ctx = (PROV_AES_KEY *)vctx; - const OSSL_PARAM *p; - - p = OSSL_PARAM_locate_const(params, OSSL_CIPHER_PARAM_PADDING); - if (p != NULL) { - int pad; - - if (!OSSL_PARAM_get_int(p, &pad)) { - PROVerr(PROV_F_AES_SET_CTX_PARAMS, - PROV_R_FAILED_TO_GET_PARAMETER); - return 0; - } - ctx->pad = pad ? 1 : 0; - } - p = OSSL_PARAM_locate_const(params, OSSL_CIPHER_PARAM_NUM); - if (p != NULL) { - int num; - - if (!OSSL_PARAM_get_int(p, &num)) { - PROVerr(PROV_F_AES_SET_CTX_PARAMS, - PROV_R_FAILED_TO_GET_PARAMETER); - return 0; - } - ctx->num = num; - } - p = OSSL_PARAM_locate_const(params, OSSL_CIPHER_PARAM_KEYLEN); - if (p != NULL) { - int keylen; - - if (!OSSL_PARAM_get_int(p, &keylen)) { - PROVerr(PROV_F_AES_SET_CTX_PARAMS, - PROV_R_FAILED_TO_GET_PARAMETER); - return 0; - } - ctx->keylen = keylen; - } - return 1; -} - -#define IMPLEMENT_block_funcs(mode, kbits) \ - const OSSL_DISPATCH aes##kbits##mode##_functions[] = { \ - { OSSL_FUNC_CIPHER_NEWCTX, (void (*)(void))aes_##kbits##_##mode##_newctx }, \ - { OSSL_FUNC_CIPHER_ENCRYPT_INIT, (void (*)(void))aes_einit }, \ - { OSSL_FUNC_CIPHER_DECRYPT_INIT, (void (*)(void))aes_dinit }, \ - { OSSL_FUNC_CIPHER_UPDATE, (void (*)(void))aes_block_update }, \ - { OSSL_FUNC_CIPHER_FINAL, (void (*)(void))aes_block_final }, \ - { OSSL_FUNC_CIPHER_CIPHER, (void (*)(void))aes_cipher }, \ - { OSSL_FUNC_CIPHER_FREECTX, (void (*)(void))aes_freectx }, \ - { OSSL_FUNC_CIPHER_DUPCTX, (void (*)(void))aes_dupctx }, \ - { OSSL_FUNC_CIPHER_GET_PARAMS, (void (*)(void))aes_##kbits##_##mode##_get_params }, \ - { OSSL_FUNC_CIPHER_GET_CTX_PARAMS, (void (*)(void))aes_get_ctx_params }, \ - { OSSL_FUNC_CIPHER_SET_CTX_PARAMS, (void (*)(void))aes_set_ctx_params }, \ - { 0, NULL } \ - }; - -#define IMPLEMENT_stream_funcs(mode, kbits) \ - const OSSL_DISPATCH aes##kbits##mode##_functions[] = { \ - { OSSL_FUNC_CIPHER_NEWCTX, (void (*)(void))aes_##kbits##_##mode##_newctx }, \ - { OSSL_FUNC_CIPHER_ENCRYPT_INIT, (void (*)(void))aes_einit }, \ - { OSSL_FUNC_CIPHER_DECRYPT_INIT, (void (*)(void))aes_dinit }, \ - { OSSL_FUNC_CIPHER_UPDATE, (void (*)(void))aes_stream_update }, \ - { OSSL_FUNC_CIPHER_FINAL, (void (*)(void))aes_stream_final }, \ - { OSSL_FUNC_CIPHER_CIPHER, (void (*)(void))aes_cipher }, \ - { OSSL_FUNC_CIPHER_FREECTX, (void (*)(void))aes_freectx }, \ - { OSSL_FUNC_CIPHER_DUPCTX, (void (*)(void))aes_dupctx }, \ - { OSSL_FUNC_CIPHER_GET_PARAMS, (void (*)(void))aes_##kbits##_##mode##_get_params }, \ - { OSSL_FUNC_CIPHER_GET_CTX_PARAMS, (void (*)(void))aes_get_ctx_params }, \ - { OSSL_FUNC_CIPHER_SET_CTX_PARAMS, (void (*)(void))aes_set_ctx_params }, \ - { 0, NULL } \ - }; +#define IMPLEMENT_funcs(mode, kbits, type) \ +const OSSL_DISPATCH aes##kbits##mode##_functions[] = { \ + { OSSL_FUNC_CIPHER_NEWCTX, (void (*)(void))aes_##kbits##_##mode##_newctx },\ + { OSSL_FUNC_CIPHER_ENCRYPT_INIT, (void (*)(void))aes_einit }, \ + { OSSL_FUNC_CIPHER_DECRYPT_INIT, (void (*)(void))aes_dinit }, \ + { OSSL_FUNC_CIPHER_UPDATE, (void (*)(void))aes_##type##_update }, \ + { OSSL_FUNC_CIPHER_FINAL, (void (*)(void))aes_##type##_final }, \ + { OSSL_FUNC_CIPHER_CIPHER, (void (*)(void))aes_cipher }, \ + { OSSL_FUNC_CIPHER_FREECTX, (void (*)(void))aes_freectx }, \ + { OSSL_FUNC_CIPHER_DUPCTX, (void (*)(void))aes_dupctx }, \ + { OSSL_FUNC_CIPHER_GET_PARAMS, \ + (void (*)(void))aes_##kbits##_##mode##_get_params }, \ + { OSSL_FUNC_CIPHER_GET_CTX_PARAMS, \ + (void (*)(void))aes_get_ctx_params }, \ + { OSSL_FUNC_CIPHER_SET_CTX_PARAMS, \ + (void (*)(void))aes_set_ctx_params }, \ + { OSSL_FUNC_CIPHER_GETTABLE_PARAMS, \ + (void (*)(void))cipher_default_gettable_params }, \ + { OSSL_FUNC_CIPHER_GETTABLE_CTX_PARAMS, \ + (void (*)(void))cipher_default_gettable_ctx_params }, \ + { OSSL_FUNC_CIPHER_SETTABLE_CTX_PARAMS, \ + (void (*)(void))cipher_default_settable_ctx_params }, \ + { 0, NULL } \ +}; /* ECB */ -IMPLEMENT_block_funcs(ecb, 256) -IMPLEMENT_block_funcs(ecb, 192) -IMPLEMENT_block_funcs(ecb, 128) +IMPLEMENT_funcs(ecb, 256, block) +IMPLEMENT_funcs(ecb, 192, block) +IMPLEMENT_funcs(ecb, 128, block) /* CBC */ -IMPLEMENT_block_funcs(cbc, 256) -IMPLEMENT_block_funcs(cbc, 192) -IMPLEMENT_block_funcs(cbc, 128) +IMPLEMENT_funcs(cbc, 256, block) +IMPLEMENT_funcs(cbc, 192, block) +IMPLEMENT_funcs(cbc, 128, block) /* OFB */ -IMPLEMENT_stream_funcs(ofb, 256) -IMPLEMENT_stream_funcs(ofb, 192) -IMPLEMENT_stream_funcs(ofb, 128) +IMPLEMENT_funcs(ofb, 256, stream) +IMPLEMENT_funcs(ofb, 192, stream) +IMPLEMENT_funcs(ofb, 128, stream) /* CFB */ -IMPLEMENT_stream_funcs(cfb, 256) -IMPLEMENT_stream_funcs(cfb, 192) -IMPLEMENT_stream_funcs(cfb, 128) -IMPLEMENT_stream_funcs(cfb1, 256) -IMPLEMENT_stream_funcs(cfb1, 192) -IMPLEMENT_stream_funcs(cfb1, 128) -IMPLEMENT_stream_funcs(cfb8, 256) -IMPLEMENT_stream_funcs(cfb8, 192) -IMPLEMENT_stream_funcs(cfb8, 128) +IMPLEMENT_funcs(cfb, 256, stream) +IMPLEMENT_funcs(cfb, 192, stream) +IMPLEMENT_funcs(cfb, 128, stream) +IMPLEMENT_funcs(cfb1, 256, stream) +IMPLEMENT_funcs(cfb1, 192, stream) +IMPLEMENT_funcs(cfb1, 128, stream) +IMPLEMENT_funcs(cfb8, 256, stream) +IMPLEMENT_funcs(cfb8, 192, stream) +IMPLEMENT_funcs(cfb8, 128, stream) /* CTR */ -IMPLEMENT_stream_funcs(ctr, 256) -IMPLEMENT_stream_funcs(ctr, 192) -IMPLEMENT_stream_funcs(ctr, 128) +IMPLEMENT_funcs(ctr, 256, stream) +IMPLEMENT_funcs(ctr, 192, stream) +IMPLEMENT_funcs(ctr, 128, stream) diff --git a/providers/common/ciphers/aes_basic.c b/providers/common/ciphers/aes_basic.c index f2ba2f3c24..f43b8fc605 100644 --- a/providers/common/ciphers/aes_basic.c +++ b/providers/common/ciphers/aes_basic.c @@ -48,7 +48,7 @@ static int aesni_init_key(PROV_AES_KEY *dat, const unsigned char *key, } if (ret < 0) { - PROVerr(PROV_F_AESNI_INIT_KEY, PROV_R_AES_KEY_SETUP_FAILED); + ERR_raise(ERR_LIB_PROV, PROV_R_AES_KEY_SETUP_FAILED); return 0; } @@ -169,7 +169,7 @@ static int aes_t4_init_key(PROV_AES_KEY *dat, const unsigned char *key, } if (ret < 0) { - PROVerr(PROV_F_AES_T4_INIT_KEY, PROV_R_AES_KEY_SETUP_FAILED); + ERR_raise(ERR_LIB_PROV, PROV_R_AES_KEY_SETUP_FAILED); return 0; } @@ -509,7 +509,7 @@ static int aes_init_key(PROV_AES_KEY *dat, const unsigned char *key, } if (ret < 0) { - PROVerr(PROV_F_AES_INIT_KEY, PROV_R_AES_KEY_SETUP_FAILED); + ERR_raise(ERR_LIB_PROV, PROV_R_AES_KEY_SETUP_FAILED); return 0; } diff --git a/providers/common/ciphers/block.c b/providers/common/ciphers/block.c index 03aa429b30..7014b9d997 100644 --- a/providers/common/ciphers/block.c +++ b/providers/common/ciphers/block.c @@ -67,7 +67,7 @@ int trailingdata(unsigned char *buf, size_t *buflen, size_t blocksize, return 1; if (*buflen + *inlen > blocksize) { - PROVerr(PROV_F_TRAILINGDATA, ERR_R_INTERNAL_ERROR); + ERR_raise(ERR_LIB_PROV, ERR_R_INTERNAL_ERROR); return 0; } @@ -94,7 +94,7 @@ int unpadblock(unsigned char *buf, size_t *buflen, size_t blocksize) size_t len = *buflen; if(len != blocksize) { - PROVerr(PROV_F_UNPADBLOCK, ERR_R_INTERNAL_ERROR); + ERR_raise(ERR_LIB_PROV, ERR_R_INTERNAL_ERROR); return 0; } @@ -104,12 +104,12 @@ int unpadblock(unsigned char *buf, size_t *buflen, size_t blocksize) */ pad = buf[blocksize - 1]; if (pad == 0 || pad > blocksize) { - PROVerr(PROV_F_UNPADBLOCK, PROV_R_BAD_DECRYPT); + ERR_raise(ERR_LIB_PROV, PROV_R_BAD_DECRYPT); return 0; } for (i = 0; i < pad; i++) { if (buf[--len] != pad) { - PROVerr(PROV_F_UNPADBLOCK, PROV_R_BAD_DECRYPT); + ERR_raise(ERR_LIB_PROV, PROV_R_BAD_DECRYPT); return 0; } } diff --git a/providers/common/ciphers/build.info b/providers/common/ciphers/build.info index 8916a22469..45f493de7e 100644 --- a/providers/common/ciphers/build.info +++ b/providers/common/ciphers/build.info @@ -1,5 +1,5 @@ LIBS=../../../libcrypto -$COMMON=block.c aes.c aes_basic.c gcm.c gcm_hw.c +$COMMON=block.c aes.c aes_basic.c gcm.c gcm_hw.c ciphers_common.c SOURCE[../../../libcrypto]=$COMMON INCLUDE[../../../libcrypto]=. ../../../crypto diff --git a/providers/common/ciphers/ciphers_common.c b/providers/common/ciphers/ciphers_common.c new file mode 100644 index 0000000000..1423092c87 --- /dev/null +++ b/providers/common/ciphers/ciphers_common.c @@ -0,0 +1,115 @@ +/* + * Copyright 2019 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include +#include +#include "ciphers_locl.h" +#include "internal/provider_algs.h" +#include "internal/providercommonerr.h" + +/*- + * Default cipher functions for OSSL_PARAM gettables and settables + */ +static const OSSL_PARAM cipher_known_gettable_params[] = { + OSSL_PARAM_int(OSSL_CIPHER_PARAM_MODE, NULL), + OSSL_PARAM_int(OSSL_CIPHER_PARAM_KEYLEN, NULL), + OSSL_PARAM_int(OSSL_CIPHER_PARAM_IVLEN, NULL), + OSSL_PARAM_int(OSSL_CIPHER_PARAM_BLOCK_SIZE, NULL), + OSSL_PARAM_END +}; +const OSSL_PARAM *cipher_default_gettable_params(void) +{ + return cipher_known_gettable_params; +} + +int cipher_default_get_params(OSSL_PARAM params[], int md, unsigned long flags, + int kbits, int blkbits, int ivbits) +{ + OSSL_PARAM *p; + + p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_MODE); + if (p != NULL && !OSSL_PARAM_set_int(p, md)) { + ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER); + return 0; + } + p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_FLAGS); + if (p != NULL && !OSSL_PARAM_set_ulong(p, flags)) { + ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER); + return 0; + } + p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_KEYLEN); + if (p != NULL && !OSSL_PARAM_set_int(p, kbits / 8)) { + ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER); + return 0; + } + p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_BLOCK_SIZE); + if (p != NULL && !OSSL_PARAM_set_int(p, blkbits / 8)) { + ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER); + return 0; + } + p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_IVLEN); + if (p != NULL && !OSSL_PARAM_set_int(p, ivbits / 8)) { + ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER); + return 0; + } + return 1; +} + +static const OSSL_PARAM cipher_known_gettable_ctx_params[] = { + OSSL_PARAM_int(OSSL_CIPHER_PARAM_KEYLEN, NULL), + OSSL_PARAM_int(OSSL_CIPHER_PARAM_IVLEN, NULL), + OSSL_PARAM_int(OSSL_CIPHER_PARAM_PADDING, NULL), + OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_NUM, NULL), + OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_IV, NULL, 0), + OSSL_PARAM_END +}; +const OSSL_PARAM *cipher_default_gettable_ctx_params(void) +{ + return cipher_known_gettable_ctx_params; +} + +static const OSSL_PARAM cipher_known_settable_ctx_params[] = { + OSSL_PARAM_int(OSSL_CIPHER_PARAM_KEYLEN, NULL), + OSSL_PARAM_int(OSSL_CIPHER_PARAM_PADDING, NULL), + OSSL_PARAM_int(OSSL_CIPHER_PARAM_NUM, NULL), + OSSL_PARAM_END +}; +const OSSL_PARAM *cipher_default_settable_ctx_params(void) +{ + return cipher_known_settable_ctx_params; +} + +/*- + * AEAD cipher functions for OSSL_PARAM gettables and settables + */ +static const OSSL_PARAM cipher_aead_known_gettable_ctx_params[] = { + OSSL_PARAM_int(OSSL_CIPHER_PARAM_KEYLEN, NULL), + OSSL_PARAM_int(OSSL_CIPHER_PARAM_IVLEN, NULL), + OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_IV, NULL, 0), + OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_AEAD_TAG, NULL, 0), + OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_AEAD_TLS1_AAD_PAD, NULL), + OSSL_PARAM_END +}; +const OSSL_PARAM *cipher_aead_gettable_ctx_params(void) +{ + return cipher_aead_known_gettable_ctx_params; +} + +static const OSSL_PARAM cipher_aead_known_settable_ctx_params[] = { + OSSL_PARAM_int(OSSL_CIPHER_PARAM_KEYLEN, NULL), + OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_AEAD_IVLEN, NULL), + OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_AEAD_TAG, NULL, 0), + OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_AEAD_TLS1_AAD, NULL, 0), + OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_AEAD_TLS1_IV_FIXED, NULL, 0), + OSSL_PARAM_END +}; +const OSSL_PARAM *cipher_aead_settable_ctx_params(void) +{ + return cipher_aead_known_settable_ctx_params; +} diff --git a/providers/common/ciphers/ciphers_locl.h b/providers/common/ciphers/ciphers_locl.h index 91033eb262..9930c3288d 100644 --- a/providers/common/ciphers/ciphers_locl.h +++ b/providers/common/ciphers/ciphers_locl.h @@ -10,6 +10,7 @@ #include #include #include +#include #include "internal/cryptlib.h" #include "internal/modes_int.h" @@ -144,5 +145,13 @@ int trailingdata(unsigned char *buf, size_t *buflen, size_t blocksize, const unsigned char **in, size_t *inlen); void padblock(unsigned char *buf, size_t *buflen, size_t blocksize); int unpadblock(unsigned char *buf, size_t *buflen, size_t blocksize); -int aes_get_params(OSSL_PARAM params[], int md, unsigned long flags, - int kbits, int blkbits, int ivbits); + +OSSL_OP_cipher_gettable_params_fn cipher_default_gettable_params; +OSSL_OP_cipher_gettable_ctx_params_fn cipher_default_gettable_ctx_params; +OSSL_OP_cipher_settable_ctx_params_fn cipher_default_settable_ctx_params; +OSSL_OP_cipher_gettable_ctx_params_fn cipher_aead_gettable_ctx_params; +OSSL_OP_cipher_settable_ctx_params_fn cipher_aead_settable_ctx_params; + +int cipher_default_get_params(OSSL_PARAM params[], int md, unsigned long flags, + int kbits, int blkbits, int ivbits); + diff --git a/providers/common/ciphers/gcm.c b/providers/common/ciphers/gcm.c index 74c2089fe7..7644f81f21 100644 --- a/providers/common/ciphers/gcm.c +++ b/providers/common/ciphers/gcm.c @@ -68,7 +68,7 @@ static int gcm_init(void *vctx, const unsigned char *key, size_t keylen, if (iv != NULL) { if (ivlen < ctx->ivlen_min || ivlen > sizeof(ctx->iv)) { - PROVerr(0, PROV_R_INVALID_IV_LENGTH); + ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_IV_LENGTH); return 0; } ctx->ivlen = ivlen; @@ -78,7 +78,7 @@ static int gcm_init(void *vctx, const unsigned char *key, size_t keylen, if (key != NULL) { if (keylen != ctx->keylen) { - PROVerr(0, PROV_R_INVALID_KEY_LENGTH); + ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_KEY_LENGTH); return 0; } return ctx->hw->setkey(ctx, key, ctx->keylen); @@ -111,7 +111,7 @@ static int gcm_get_ctx_params(void *vctx, OSSL_PARAM params[]) } p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_KEYLEN); if (p != NULL && !OSSL_PARAM_set_int(p, ctx->keylen)) { - PROVerr(0, PROV_R_FAILED_TO_SET_PARAMETER); + ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER); return 0; } @@ -120,29 +120,29 @@ static int gcm_get_ctx_params(void *vctx, OSSL_PARAM params[]) if (ctx->iv_gen != 1 && ctx->iv_gen_rand != 1) return 0; if (ctx->ivlen != (int)p->data_size) { - PROVerr(0, PROV_R_INVALID_IV_LENGTH); + ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_IV_LENGTH); return 0; } if (!OSSL_PARAM_set_octet_string(p, ctx->iv, ctx->ivlen)) { - PROVerr(0, PROV_R_FAILED_TO_SET_PARAMETER); + ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER); return 0; } } p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_AEAD_TLS1_AAD_PAD); if (p != NULL && !OSSL_PARAM_set_size_t(p, ctx->tls_aad_pad_sz)) { - PROVerr(0, PROV_R_FAILED_TO_SET_PARAMETER); + ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER); return 0; } p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_AEAD_TAG); if (p != NULL) { sz = p->data_size; if (sz == 0 || sz > EVP_GCM_TLS_TAG_LEN || !ctx->enc || ctx->taglen < 0) { - PROVerr(0, PROV_R_INVALID_TAG); + ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_TAG); return 0; } if (!OSSL_PARAM_set_octet_string(p, ctx->buf, sz)) { - PROVerr(0, PROV_R_FAILED_TO_SET_PARAMETER); + ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER); return 0; } } @@ -160,11 +160,11 @@ static int gcm_set_ctx_params(void *vctx, const OSSL_PARAM params[]) if (p != NULL) { vp = ctx->buf; if (!OSSL_PARAM_get_octet_string(p, &vp, EVP_GCM_TLS_TAG_LEN, &sz)) { - PROVerr(0, PROV_R_FAILED_TO_GET_PARAMETER); + ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER); return 0; } if (sz == 0 || ctx->enc) { - PROVerr(0, PROV_R_INVALID_TAG); + ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_TAG); return 0; } ctx->taglen = sz; @@ -173,11 +173,11 @@ static int gcm_set_ctx_params(void *vctx, const OSSL_PARAM params[]) p = OSSL_PARAM_locate_const(params, OSSL_CIPHER_PARAM_AEAD_IVLEN); if (p != NULL) { if (!OSSL_PARAM_get_size_t(p, &sz)) { - PROVerr(0, PROV_R_FAILED_TO_GET_PARAMETER); + ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER); return 0; } if (sz == 0 || sz > sizeof(ctx->iv)) { - PROVerr(0, PROV_R_INVALID_IV_LENGTH); + ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_IV_LENGTH); return 0; } ctx->ivlen = sz; @@ -186,12 +186,12 @@ static int gcm_set_ctx_params(void *vctx, const OSSL_PARAM params[]) p = OSSL_PARAM_locate_const(params, OSSL_CIPHER_PARAM_AEAD_TLS1_AAD); if (p != NULL) { if (p->data_type != OSSL_PARAM_OCTET_STRING) { - PROVerr(0, PROV_R_FAILED_TO_GET_PARAMETER); + ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER); return 0; } sz = gcm_tls_init(ctx, p->data, p->data_size); if (sz == 0) { - PROVerr(0, PROV_R_INVALID_AAD); + ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_AAD); return 0; } ctx->tls_aad_pad_sz = sz; @@ -200,11 +200,11 @@ static int gcm_set_ctx_params(void *vctx, const OSSL_PARAM params[]) p = OSSL_PARAM_locate_const(params, OSSL_CIPHER_PARAM_AEAD_TLS1_IV_FIXED); if (p != NULL) { if (p->data_type != OSSL_PARAM_OCTET_STRING) { - PROVerr(0, PROV_R_FAILED_TO_GET_PARAMETER); + ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER); return 0; } if (gcm_tls_iv_set_fixed(ctx, p->data, p->data_size) == 0) { - PROVerr(0, PROV_R_FAILED_TO_GET_PARAMETER); + ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER); return 0; } } @@ -220,7 +220,7 @@ static int gcm_set_ctx_params(void *vctx, const OSSL_PARAM params[]) int keylen; if (!OSSL_PARAM_get_int(p, &keylen)) { - PROVerr(0, PROV_R_FAILED_TO_GET_PARAMETER); + ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER); return 0; } /* The key length can not be modified for gcm mode */ @@ -238,12 +238,12 @@ static int gcm_stream_update(void *vctx, unsigned char *out, size_t *outl, PROV_GCM_CTX *ctx = (PROV_GCM_CTX *)vctx; if (outsize < inl) { - PROVerr(0, PROV_R_OUTPUT_BUFFER_TOO_SMALL); + ERR_raise(ERR_LIB_PROV, PROV_R_OUTPUT_BUFFER_TOO_SMALL); return -1; } if (gcm_cipher_internal(ctx, out, outl, in, inl) <= 0) { - PROVerr(0, PROV_R_CIPHER_OPERATION_FAILED); + ERR_raise(ERR_LIB_PROV, PROV_R_CIPHER_OPERATION_FAILED); return -1; } return 1; @@ -270,7 +270,7 @@ static int gcm_cipher(void *vctx, PROV_GCM_CTX *ctx = (PROV_GCM_CTX *)vctx; if (outsize < inl) { - PROVerr(0, PROV_R_OUTPUT_BUFFER_TOO_SMALL); + ERR_raise(ERR_LIB_PROV, PROV_R_OUTPUT_BUFFER_TOO_SMALL); return -1; } @@ -460,7 +460,7 @@ static int gcm_tls_cipher(PROV_GCM_CTX *ctx, unsigned char *out, size_t *padlen, * side only. */ if (ctx->enc && ++ctx->tls_enc_records == 0) { - PROVerr(0, EVP_R_TOO_MANY_RECORDS); + ERR_raise(ERR_LIB_PROV, EVP_R_TOO_MANY_RECORDS); goto err; } @@ -517,8 +517,8 @@ err: static OSSL_OP_cipher_get_params_fn alg##_##kbits##_##lcmode##_get_params; \ static int alg##_##kbits##_##lcmode##_get_params(OSSL_PARAM params[]) \ { \ - return aes_get_params(params, EVP_CIPH_##UCMODE##_MODE, flags, \ - kbits, blkbits, ivbits); \ + return cipher_default_get_params(params, EVP_CIPH_##UCMODE##_MODE, \ + flags, kbits, blkbits, ivbits); \ } \ static OSSL_OP_cipher_newctx_fn alg##kbits##gcm_newctx; \ static void *alg##kbits##gcm_newctx(void *provctx) \ @@ -539,6 +539,12 @@ err: (void (*)(void))gcm_get_ctx_params }, \ { OSSL_FUNC_CIPHER_SET_CTX_PARAMS, \ (void (*)(void))gcm_set_ctx_params }, \ + { OSSL_FUNC_CIPHER_GETTABLE_PARAMS, \ + (void (*)(void))cipher_default_gettable_params }, \ + { OSSL_FUNC_CIPHER_GETTABLE_CTX_PARAMS, \ + (void (*)(void))cipher_aead_gettable_ctx_params }, \ + { OSSL_FUNC_CIPHER_SETTABLE_CTX_PARAMS, \ + (void (*)(void))cipher_aead_settable_ctx_params }, \ { 0, NULL } \ } diff --git a/test/evp_extra_test.c b/test/evp_extra_test.c index fc3d6283ac..f187f73bf0 100644 --- a/test/evp_extra_test.c +++ b/test/evp_extra_test.c @@ -1229,6 +1229,170 @@ static int test_EVP_MD_fetch(int tst) return ret; } +static int encrypt_decrypt(const EVP_CIPHER *cipher, const unsigned char *msg, + size_t len) +{ + int ret = 0, ctlen, ptlen; + EVP_CIPHER_CTX *ctx = NULL; + unsigned char key[128 / 8]; + unsigned char ct[64], pt[64]; + + memset(key, 0, sizeof(key)); + if (!TEST_ptr(ctx = EVP_CIPHER_CTX_new()) + || !TEST_true(EVP_CipherInit_ex(ctx, cipher, NULL, key, NULL, 1)) + || !TEST_true(EVP_CipherUpdate(ctx, ct, &ctlen, msg, len)) + || !TEST_true(EVP_CipherFinal_ex(ctx, ct, &ctlen)) + || !TEST_true(EVP_CipherInit_ex(ctx, cipher, NULL, key, NULL, 0)) + || !TEST_true(EVP_CipherUpdate(ctx, pt, &ptlen, ct, ctlen)) + || !TEST_true(EVP_CipherFinal_ex(ctx, pt, &ptlen)) + || !TEST_mem_eq(pt, ptlen, msg, len)) + goto err; + + ret = 1; + err: + EVP_CIPHER_CTX_free(ctx); + return ret; +} + +static int get_num_params(const OSSL_PARAM *params) +{ + int i = 0; + + if (params != NULL) { + while (params[i].key != NULL) + ++i; + ++i; + } + return i; +} + +/* + * Test EVP_CIPHER_fetch() + * + * Test 0: Test with the default OPENSSL_CTX + * Test 1: Test with an explicit OPENSSL_CTX + * Test 2: Explicit OPENSSL_CTX with explicit load of default provider + * Test 3: Explicit OPENSSL_CTX with explicit load of default and fips provider + * Test 4: Explicit OPENSSL_CTX with explicit load of fips provider + */ +static int test_EVP_CIPHER_fetch(int tst) +{ + OPENSSL_CTX *ctx = NULL; + EVP_CIPHER *cipher = NULL; + OSSL_PROVIDER *defltprov = NULL, *fipsprov = NULL; + int ret = 0; + const unsigned char testmsg[] = "Hello world"; + const OSSL_PARAM *params; + + if (tst > 0) { + ctx = OPENSSL_CTX_new(); + if (!TEST_ptr(ctx)) + goto err; + + if (tst == 2 || tst == 3) { + defltprov = OSSL_PROVIDER_load(ctx, "default"); + if (!TEST_ptr(defltprov)) + goto err; + } + if (tst == 3 || tst == 4) { + fipsprov = OSSL_PROVIDER_load(ctx, "fips"); + if (!TEST_ptr(fipsprov)) + goto err; + } + } + + /* Implicit fetching of the cipher should produce the expected result */ + if (!TEST_true(encrypt_decrypt(EVP_aes_128_cbc(), testmsg, sizeof(testmsg)))) + goto err; + + /* + * Test that without specifying any properties we can get a cipher from a + * provider. + */ + if (!TEST_ptr(cipher = EVP_CIPHER_fetch(ctx, "AES-128-CBC", NULL)) + || !TEST_true(encrypt_decrypt(cipher, testmsg, sizeof(testmsg)))) + goto err; + + /* Also test EVP_CIPHER_up_ref() while we're doing this */ + if (!TEST_true(EVP_CIPHER_up_ref(cipher))) + goto err; + /* Ref count should now be 2. Release both */ + EVP_CIPHER_meth_free(cipher); + EVP_CIPHER_meth_free(cipher); + cipher = NULL; + + /* + * In tests 0 - 2 we've only loaded the default provider so explicitly + * asking for a non-default implementation should fail. In tests 3 and 4 we + * have the FIPS provider loaded so we should succeed in that case. + */ + cipher = EVP_CIPHER_fetch(ctx, "AES-128-CBC", "default=no"); + if (tst == 3 || tst == 4) { + if (!TEST_ptr(cipher) + || !TEST_true(encrypt_decrypt(cipher, testmsg, sizeof(testmsg)))) + goto err; + } else { + if (!TEST_ptr_null(cipher)) + goto err; + } + + EVP_CIPHER_meth_free(cipher); + cipher = NULL; + + /* + * Explicitly asking for the default implementation should succeed except + * in test 4 where the default provider is not loaded. + */ + cipher = EVP_CIPHER_fetch(ctx, "AES-128-CBC", "default=yes"); + if (tst != 4) { + if (!TEST_ptr(cipher) + || !TEST_int_eq(EVP_CIPHER_nid(cipher), NID_aes_128_cbc) + || !TEST_true(encrypt_decrypt(cipher, testmsg, sizeof(testmsg))) + || !TEST_int_eq(EVP_CIPHER_block_size(cipher), 128/8)) + goto err; + } else { + if (!TEST_ptr_null(cipher)) + goto err; + } + + EVP_CIPHER_meth_free(cipher); + cipher = NULL; + + /* + * Explicitly asking for a fips implementation should succeed if we have + * the FIPS provider loaded and fail otherwise + */ + cipher = EVP_CIPHER_fetch(ctx, "AES-128-CBC", "fips=yes"); + if (tst == 3 || tst == 4) { + if (!TEST_ptr(cipher) + || !TEST_true(encrypt_decrypt(cipher, testmsg, sizeof(testmsg))) + || !TEST_ptr(params = cipher->gettable_params()) + || !TEST_int_gt(get_num_params(params), 1) + || !TEST_ptr(params = cipher->gettable_ctx_params()) + || !TEST_int_gt(get_num_params(params), 1) + || !TEST_ptr(params = cipher->settable_ctx_params()) + || !TEST_int_gt(get_num_params(params), 1)) + goto err; + } else { + if (!TEST_ptr_null(cipher)) + goto err; + } + + ret = 1; + + err: + EVP_CIPHER_meth_free(cipher); + OSSL_PROVIDER_unload(defltprov); + OSSL_PROVIDER_unload(fipsprov); + /* Not normally needed, but we would like to test that + * OPENSSL_thread_stop_ex() behaves as expected. + */ + if (ctx != NULL) + OPENSSL_thread_stop_ex(ctx); + OPENSSL_CTX_free(ctx); + return ret; +} + int setup_tests(void) { ADD_TEST(test_EVP_DigestSignInit); @@ -1260,8 +1424,10 @@ int setup_tests(void) #endif #ifdef NO_FIPS_MODULE ADD_ALL_TESTS(test_EVP_MD_fetch, 3); + ADD_ALL_TESTS(test_EVP_CIPHER_fetch, 3); #else ADD_ALL_TESTS(test_EVP_MD_fetch, 5); + ADD_ALL_TESTS(test_EVP_CIPHER_fetch, 5); #endif return 1; }