mirror of
https://github.com/openssl/openssl.git
synced 2024-11-21 01:15:20 +08:00
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)
This commit is contained in:
parent
344cfa34e5
commit
3b94944cf2
@ -562,6 +562,7 @@ int EVP_EncryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl,
|
||||
{
|
||||
int ret;
|
||||
size_t soutl;
|
||||
int blocksize;
|
||||
|
||||
/* Prevent accidental use of decryption context when encrypting */
|
||||
if (!ctx->encrypt) {
|
||||
@ -572,11 +573,15 @@ int EVP_EncryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl,
|
||||
if (ctx->cipher == NULL || ctx->cipher->prov == NULL)
|
||||
goto legacy;
|
||||
|
||||
if (ctx->cipher->cupdate == NULL) {
|
||||
blocksize = EVP_CIPHER_CTX_block_size(ctx);
|
||||
|
||||
if (ctx->cipher->cupdate == NULL || blocksize < 1) {
|
||||
EVPerr(EVP_F_EVP_ENCRYPTUPDATE, EVP_R_UPDATE_ERROR);
|
||||
return 0;
|
||||
}
|
||||
ret = ctx->cipher->cupdate(ctx->provctx, out, &soutl, in, (size_t)inl);
|
||||
ret = ctx->cipher->cupdate(ctx->provctx, out, &soutl,
|
||||
inl + (blocksize == 1 ? 0 : blocksize), in,
|
||||
(size_t)inl);
|
||||
|
||||
if (soutl > INT_MAX) {
|
||||
EVPerr(EVP_F_EVP_ENCRYPTUPDATE, EVP_R_UPDATE_ERROR);
|
||||
@ -603,6 +608,7 @@ int EVP_EncryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl)
|
||||
int n, ret;
|
||||
unsigned int i, b, bl;
|
||||
size_t soutl;
|
||||
int blocksize;
|
||||
|
||||
/* Prevent accidental use of decryption context when encrypting */
|
||||
if (!ctx->encrypt) {
|
||||
@ -613,12 +619,15 @@ int EVP_EncryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl)
|
||||
if (ctx->cipher == NULL || ctx->cipher->prov == NULL)
|
||||
goto legacy;
|
||||
|
||||
if (ctx->cipher->cfinal == NULL) {
|
||||
blocksize = EVP_CIPHER_CTX_block_size(ctx);
|
||||
|
||||
if (blocksize < 1 || ctx->cipher->cfinal == NULL) {
|
||||
EVPerr(EVP_F_EVP_ENCRYPTFINAL_EX, EVP_R_FINAL_ERROR);
|
||||
return 0;
|
||||
}
|
||||
|
||||
ret = ctx->cipher->cfinal(ctx->provctx, out, &soutl);
|
||||
ret = ctx->cipher->cfinal(ctx->provctx, out, &soutl,
|
||||
blocksize == 1 ? 0 : blocksize);
|
||||
|
||||
if (soutl > INT_MAX) {
|
||||
EVPerr(EVP_F_EVP_ENCRYPTFINAL_EX, EVP_R_FINAL_ERROR);
|
||||
@ -674,6 +683,7 @@ int EVP_DecryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl,
|
||||
int fix_len, cmpl = inl, ret;
|
||||
unsigned int b;
|
||||
size_t soutl;
|
||||
int blocksize;
|
||||
|
||||
/* Prevent accidental use of encryption context when decrypting */
|
||||
if (ctx->encrypt) {
|
||||
@ -684,11 +694,15 @@ int EVP_DecryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl,
|
||||
if (ctx->cipher == NULL || ctx->cipher->prov == NULL)
|
||||
goto legacy;
|
||||
|
||||
if (ctx->cipher->cupdate == NULL) {
|
||||
blocksize = EVP_CIPHER_CTX_block_size(ctx);
|
||||
|
||||
if (ctx->cipher->cupdate == NULL || blocksize < 1) {
|
||||
EVPerr(EVP_F_EVP_DECRYPTUPDATE, EVP_R_UPDATE_ERROR);
|
||||
return 0;
|
||||
}
|
||||
ret = ctx->cipher->cupdate(ctx->provctx, out, &soutl, in, (size_t)inl);
|
||||
ret = ctx->cipher->cupdate(ctx->provctx, out, &soutl,
|
||||
inl + (blocksize == 1 ? 0 : blocksize), in,
|
||||
(size_t)inl);
|
||||
|
||||
if (ret) {
|
||||
if (soutl > INT_MAX) {
|
||||
@ -779,6 +793,7 @@ int EVP_DecryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl)
|
||||
unsigned int b;
|
||||
size_t soutl;
|
||||
int ret;
|
||||
int blocksize;
|
||||
|
||||
/* Prevent accidental use of encryption context when decrypting */
|
||||
if (ctx->encrypt) {
|
||||
@ -789,12 +804,15 @@ int EVP_DecryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl)
|
||||
if (ctx->cipher == NULL || ctx->cipher->prov == NULL)
|
||||
goto legacy;
|
||||
|
||||
if (ctx->cipher->cfinal == NULL) {
|
||||
blocksize = EVP_CIPHER_CTX_block_size(ctx);
|
||||
|
||||
if (blocksize < 1 || ctx->cipher->cfinal == NULL) {
|
||||
EVPerr(EVP_F_EVP_DECRYPTFINAL_EX, EVP_R_FINAL_ERROR);
|
||||
return 0;
|
||||
}
|
||||
|
||||
ret = ctx->cipher->cfinal(ctx->provctx, out, &soutl);
|
||||
ret = ctx->cipher->cfinal(ctx->provctx, out, &soutl,
|
||||
blocksize == 1 ? 0 : blocksize);
|
||||
|
||||
if (ret) {
|
||||
if (soutl > INT_MAX) {
|
||||
|
@ -135,10 +135,10 @@ OSSL_CORE_MAKE_FUNC(int, OP_cipher_decrypt_init, (void *vctx,
|
||||
const unsigned char *iv,
|
||||
size_t ivlen))
|
||||
OSSL_CORE_MAKE_FUNC(int, OP_cipher_update,
|
||||
(void *, unsigned char *out, size_t *outl,
|
||||
(void *, unsigned char *out, size_t *outl, size_t outsize,
|
||||
const unsigned char *in, size_t inl))
|
||||
OSSL_CORE_MAKE_FUNC(int, OP_cipher_final,
|
||||
(void *, unsigned char *out, size_t *outl))
|
||||
(void *, unsigned char *out, size_t *outl, size_t outsize))
|
||||
OSSL_CORE_MAKE_FUNC(int, OP_cipher_cipher,
|
||||
(void *, unsigned char *out, const unsigned char *in,
|
||||
size_t inl))
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user