X-Git-Url: https://git.openssl.org/gitweb/?p=openssl.git;a=blobdiff_plain;f=providers%2Fcommon%2Fciphers%2Faes.c;h=d98a5c520b46110ea552f796c5b047632b99d8aa;hp=a7af6a6773bb0939b23379835f064493d47768e6;hb=64adf9aac7;hpb=75dd6d64f1f3afd6fda024d8d91bc2a216bbfcf9 diff --git a/providers/common/ciphers/aes.c b/providers/common/ciphers/aes.c index a7af6a6773..d98a5c520b 100644 --- a/providers/common/ciphers/aes.c +++ b/providers/common/ciphers/aes.c @@ -17,41 +17,74 @@ #include "internal/provider_algs.h" #include "ciphers_locl.h" -static void PROV_AES_KEY_generic_init(PROV_AES_KEY *ctx, +static OSSL_OP_cipher_encrypt_init_fn aes_einit; +static OSSL_OP_cipher_decrypt_init_fn aes_dinit; +static OSSL_OP_cipher_update_fn aes_block_update; +static OSSL_OP_cipher_final_fn aes_block_final; +static OSSL_OP_cipher_update_fn aes_stream_update; +static OSSL_OP_cipher_final_fn aes_stream_final; +static OSSL_OP_cipher_cipher_fn aes_cipher; +static OSSL_OP_cipher_freectx_fn aes_freectx; +static OSSL_OP_cipher_dupctx_fn aes_dupctx; +static OSSL_OP_cipher_key_length_fn key_length_256; +static OSSL_OP_cipher_key_length_fn key_length_192; +static OSSL_OP_cipher_key_length_fn key_length_128; +static OSSL_OP_cipher_iv_length_fn iv_length_16; +static OSSL_OP_cipher_iv_length_fn iv_length_0; +static OSSL_OP_cipher_block_size_fn block_size_16; +static OSSL_OP_cipher_block_size_fn block_size_1; +static OSSL_OP_cipher_ctx_get_params_fn aes_ctx_get_params; +static OSSL_OP_cipher_ctx_set_params_fn aes_ctx_set_params; + +static int PROV_AES_KEY_generic_init(PROV_AES_KEY *ctx, const unsigned char *iv, + size_t ivlen, int enc) { - if (iv != NULL) + if (iv != NULL && ctx->mode != EVP_CIPH_ECB_MODE) { + if (ivlen != AES_BLOCK_SIZE) + return 0; memcpy(ctx->iv, iv, AES_BLOCK_SIZE); + } ctx->enc = enc; + + return 1; } -static int aes_einit(void *vctx, const unsigned char *key, - const unsigned char *iv) +static int aes_einit(void *vctx, const unsigned char *key, size_t keylen, + const unsigned char *iv, size_t ivlen) { PROV_AES_KEY *ctx = (PROV_AES_KEY *)vctx; - PROV_AES_KEY_generic_init(ctx, iv, 1); - if (key != NULL) + if (!PROV_AES_KEY_generic_init(ctx, iv, ivlen, 1)) + return 0; + if (key != NULL) { + if (keylen != ctx->keylen) + return 0; return ctx->ciph->init(ctx, key, ctx->keylen); + } return 1; } -static int aes_dinit(void *vctx, const unsigned char *key, - const unsigned char *iv) +static int aes_dinit(void *vctx, const unsigned char *key, size_t keylen, + const unsigned char *iv, size_t ivlen) { PROV_AES_KEY *ctx = (PROV_AES_KEY *)vctx; - PROV_AES_KEY_generic_init(ctx, iv, 0); - if (key != NULL) + if (!PROV_AES_KEY_generic_init(ctx, iv, ivlen, 0)) + return 0; + if (key != NULL) { + if (keylen != ctx->keylen) + return 0; return ctx->ciph->init(ctx, key, ctx->keylen); + } return 1; } static int aes_block_update(void *vctx, unsigned char *out, size_t *outl, - const unsigned char *in, size_t inl) + size_t outsize, const unsigned char *in, size_t inl) { PROV_AES_KEY *ctx = (PROV_AES_KEY *)vctx; size_t nextblocks = fillblock(ctx->buf, &ctx->bufsz, AES_BLOCK_SIZE, &in, @@ -65,6 +98,8 @@ 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) + return 0; if (!ctx->ciph->cipher(ctx, out, ctx->buf, AES_BLOCK_SIZE)) return 0; ctx->bufsz = 0; @@ -77,11 +112,13 @@ static int aes_block_update(void *vctx, unsigned char *out, size_t *outl, return 0; nextblocks -= AES_BLOCK_SIZE; } + outlint += nextblocks; + if (outsize < outlint) + return 0; if (!ctx->ciph->cipher(ctx, out, in, nextblocks)) return 0; in += nextblocks; inl -= nextblocks; - outlint += nextblocks; } if (!trailingdata(ctx->buf, &ctx->bufsz, AES_BLOCK_SIZE, &in, &inl)) return 0; @@ -90,7 +127,8 @@ static int aes_block_update(void *vctx, unsigned char *out, size_t *outl, return inl == 0; } -static int aes_block_final(void *vctx, unsigned char *out, size_t *outl) +static int aes_block_final(void *vctx, unsigned char *out, size_t *outl, + size_t outsize) { PROV_AES_KEY *ctx = (PROV_AES_KEY *)vctx; @@ -105,6 +143,8 @@ static int aes_block_final(void *vctx, unsigned char *out, size_t *outl) return 0; } + if (outsize < AES_BLOCK_SIZE) + return 0; if (!ctx->ciph->cipher(ctx, out, ctx->buf, AES_BLOCK_SIZE)) return 0; ctx->bufsz = 0; @@ -129,6 +169,8 @@ static int aes_block_final(void *vctx, unsigned char *out, size_t *outl) if (ctx->pad && !unpadblock(ctx->buf, &ctx->bufsz, AES_BLOCK_SIZE)) return 0; + if (outsize < ctx->bufsz) + return 0; memcpy(out, ctx->buf, ctx->bufsz); *outl = ctx->bufsz; ctx->bufsz = 0; @@ -136,17 +178,22 @@ static int aes_block_final(void *vctx, unsigned char *out, size_t *outl) } static int aes_stream_update(void *vctx, unsigned char *out, size_t *outl, - const unsigned char *in, size_t inl) + size_t outsize, const unsigned char *in, + size_t inl) { PROV_AES_KEY *ctx = (PROV_AES_KEY *)vctx; + if (outsize < inl) + return 0; + if (!ctx->ciph->cipher(ctx, out, in, inl)) return 0; *outl = inl; return 1; } -static int aes_stream_final(void *vctx, unsigned char *out, size_t *outl) +static int aes_stream_final(void *vctx, unsigned char *out, size_t *outl, + size_t outsize) { *outl = 0; return 1; @@ -164,6 +211,7 @@ static int aes_cipher(void *vctx, unsigned char *out, const unsigned char *in, } #define IMPLEMENT_new_params(lcmode, UCMODE) \ + static OSSL_OP_cipher_get_params_fn aes_##lcmode##_get_params; \ static int aes_##lcmode##_get_params(const OSSL_PARAM params[]) \ { \ const OSSL_PARAM *p; \ @@ -176,13 +224,14 @@ static int aes_cipher(void *vctx, unsigned char *out, const unsigned char *in, } #define IMPLEMENT_new_ctx(lcmode, UCMODE, len) \ + static OSSL_OP_cipher_newctx_fn aes_##len##_##lcmode##_newctx; \ static void *aes_##len##_##lcmode##_newctx(void) \ { \ PROV_AES_KEY *ctx = OPENSSL_zalloc(sizeof(*ctx)); \ \ ctx->pad = 1; \ ctx->keylen = (len / 8); \ - ctx->ciph = PROV_AES_CIPHER_##lcmode(); \ + ctx->ciph = PROV_AES_CIPHER_##lcmode(ctx->keylen); \ ctx->mode = EVP_CIPH_##UCMODE##_MODE; \ return ctx; \ } @@ -219,6 +268,12 @@ IMPLEMENT_new_ctx(cfb8, CFB, 256) IMPLEMENT_new_ctx(cfb8, CFB, 192) IMPLEMENT_new_ctx(cfb8, CFB, 128) +/* CTR */ +IMPLEMENT_new_params(ctr, CTR) +IMPLEMENT_new_ctx(ctr, CTR, 256) +IMPLEMENT_new_ctx(ctr, CTR, 192) +IMPLEMENT_new_ctx(ctr, CTR, 128) + static void aes_freectx(void *vctx) { PROV_AES_KEY *ctx = (PROV_AES_KEY *)vctx; @@ -362,3 +417,8 @@ IMPLEMENT_stream_funcs(cfb1, 128, 16) IMPLEMENT_stream_funcs(cfb8, 256, 16) IMPLEMENT_stream_funcs(cfb8, 192, 16) IMPLEMENT_stream_funcs(cfb8, 128, 16) + +/* CTR */ +IMPLEMENT_stream_funcs(ctr, 256, 16) +IMPLEMENT_stream_funcs(ctr, 192, 16) +IMPLEMENT_stream_funcs(ctr, 128, 16)