Skip to content

Commit 66d01e3

Browse files
committed
ext/openssl: openssl_encrypt() zend mm heap overflow on AES-WRAP-PAD mode.
Fix #22186
1 parent 673cb6d commit 66d01e3

1 file changed

Lines changed: 15 additions & 2 deletions

File tree

ext/openssl/openssl.c

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7932,6 +7932,7 @@ static int php_openssl_cipher_update(const EVP_CIPHER *cipher_type,
79327932
const char *aad, size_t aad_len, int enc) /* {{{ */
79337933
{
79347934
int i = 0;
7935+
size_t outlen = data_len + EVP_CIPHER_block_size(cipher_type);
79357936

79367937
if (mode->is_single_run_aead && !EVP_CipherUpdate(cipher_ctx, NULL, &i, NULL, (int)data_len)) {
79377938
php_openssl_store_errors();
@@ -7945,7 +7946,19 @@ static int php_openssl_cipher_update(const EVP_CIPHER *cipher_type,
79457946
return FAILURE;
79467947
}
79477948

7948-
*poutbuf = zend_string_alloc((int)data_len + EVP_CIPHER_block_size(cipher_type), 0);
7949+
#ifdef EVP_CIPH_WRAP_MODE
7950+
if ((EVP_CIPHER_flags(cipher_type) & EVP_CIPH_MODE) == EVP_CIPH_WRAP_MODE) {
7951+
/*
7952+
* RFC 5649 wrap-with-padding rounds the input up to the block size
7953+
* and prepends an integrity block, we reserve one extra block.
7954+
* See EVP_EncryptUpdate(3): wrap mode may write up to
7955+
* inl + cipher_block_size bytes.
7956+
*/
7957+
outlen += EVP_CIPHER_block_size(cipher_type);
7958+
}
7959+
#endif
7960+
7961+
*poutbuf = zend_string_alloc(outlen, false);
79497962

79507963
if (!EVP_CipherUpdate(cipher_ctx, (unsigned char*)ZSTR_VAL(*poutbuf),
79517964
&i, (const unsigned char *)data, (int)data_len)) {
@@ -7957,7 +7970,7 @@ static int php_openssl_cipher_update(const EVP_CIPHER *cipher_type,
79577970
}
79587971
*/
79597972
php_openssl_store_errors();
7960-
zend_string_release_ex(*poutbuf, 0);
7973+
zend_string_release_ex(*poutbuf, false);
79617974
return FAILURE;
79627975
}
79637976

0 commit comments

Comments
 (0)