diff options
author | Matt Caswell <matt@openssl.org> | 2019-04-10 13:43:45 +0100 |
---|---|---|
committer | Matt Caswell <matt@openssl.org> | 2019-04-19 09:31:54 +0100 |
commit | 3b94944cf2d6476d1b8ac7949bf8b28abb644426 (patch) | |
tree | 216c4c9bf2d78700dc205319dbc74a4e3ada385e /providers/common/ciphers/aes.c | |
parent | 344cfa34e5b07f8b8b7f1e70f47f5d265c9c1185 (diff) |
Add a maximum output length to update and final calls
Reviewed-by: Paul Dale <paul.dale@oracle.com>
(Merged from https://github.com/openssl/openssl/pull/8700)
Diffstat (limited to 'providers/common/ciphers/aes.c')
-rw-r--r-- | providers/common/ciphers/aes.c | 24 |
1 files changed, 19 insertions, 5 deletions
diff --git a/providers/common/ciphers/aes.c b/providers/common/ciphers/aes.c index 21ecc2b14a..a70facc148 100644 --- a/providers/common/ciphers/aes.c +++ b/providers/common/ciphers/aes.c @@ -65,7 +65,7 @@ static int aes_dinit(void *vctx, const unsigned char *key, size_t keylen, } 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, @@ -79,6 +79,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; @@ -91,11 +93,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; @@ -104,7 +108,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; @@ -119,6 +124,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; @@ -143,6 +150,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; @@ -150,17 +159,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; |