| Subject: Fix bug #79601 (Wrong ciphertext/tag in AES-CCM encryption |
| for a 12 bytes IV) |
| |
| --- |
| ext/openssl/openssl.c | 10 ++++----- |
| ext/openssl/tests/cipher_tests.inc | 21 +++++++++++++++++ |
| ext/openssl/tests/openssl_decrypt_ccm.phpt | 22 +++++++++++------- |
| ext/openssl/tests/openssl_encrypt_ccm.phpt | 26 ++++++++++++++-------- |
| 4 files changed, 57 insertions(+), 22 deletions(-) |
| |
| diff --git a/ext/openssl/openssl.c b/ext/openssl/openssl.c |
| index 04cb9b0f..fdad2c3b 100644 |
| --- a/ext/openssl/openssl.c |
| +++ b/ext/openssl/openssl.c |
| @@ -6521,11 +6521,6 @@ static int php_openssl_validate_iv(char **piv, size_t *piv_len, size_t iv_requir |
| { |
| char *iv_new; |
| |
| - /* Best case scenario, user behaved */ |
| - if (*piv_len == iv_required_len) { |
| - return SUCCESS; |
| - } |
| - |
| if (mode->is_aead) { |
| if (EVP_CIPHER_CTX_ctrl(cipher_ctx, mode->aead_ivlen_flag, *piv_len, NULL) != 1) { |
| php_error_docref(NULL, E_WARNING, "Setting of IV length for AEAD mode failed"); |
| @@ -6534,6 +6529,11 @@ static int php_openssl_validate_iv(char **piv, size_t *piv_len, size_t iv_requir |
| return SUCCESS; |
| } |
| |
| + /* Best case scenario, user behaved */ |
| + if (*piv_len == iv_required_len) { |
| + return SUCCESS; |
| + } |
| + |
| iv_new = ecalloc(1, iv_required_len + 1); |
| |
| if (*piv_len == 0) { |
| diff --git a/ext/openssl/tests/cipher_tests.inc b/ext/openssl/tests/cipher_tests.inc |
| index b1e46b41..779bfa85 100644 |
| --- a/ext/openssl/tests/cipher_tests.inc |
| +++ b/ext/openssl/tests/cipher_tests.inc |
| @@ -1,5 +1,26 @@ |
| <?php |
| $php_openssl_cipher_tests = array( |
| + 'aes-128-ccm' => array( |
| + array( |
| + 'key' => '404142434445464748494a4b4c4d4e4f', |
| + 'iv' => '1011121314151617', |
| + 'aad' => '000102030405060708090a0b0c0d0e0f', |
| + 'tag' => '1fc64fbfaccd', |
| + 'pt' => '202122232425262728292a2b2c2d2e2f', |
| + 'ct' => 'd2a1f0e051ea5f62081a7792073d593d', |
| + ), |
| + array( |
| + 'key' => '404142434445464748494a4b4c4d4e4f', |
| + 'iv' => '101112131415161718191a1b', |
| + 'aad' => '000102030405060708090a0b0c0d0e0f' . |
| + '10111213', |
| + 'tag' => '484392fbc1b09951', |
| + 'pt' => '202122232425262728292a2b2c2d2e2f' . |
| + '3031323334353637', |
| + 'ct' => 'e3b201a9f5b71a7a9b1ceaeccd97e70b' . |
| + '6176aad9a4428aa5', |
| + ), |
| + ), |
| 'aes-256-ccm' => array( |
| array( |
| 'key' => '1bde3251d41a8b5ea013c195ae128b21' . |
| diff --git a/ext/openssl/tests/openssl_decrypt_ccm.phpt b/ext/openssl/tests/openssl_decrypt_ccm.phpt |
| index a5f01b87..08ef5bb7 100644 |
| --- a/ext/openssl/tests/openssl_decrypt_ccm.phpt |
| +++ b/ext/openssl/tests/openssl_decrypt_ccm.phpt |
| @@ -10,14 +10,16 @@ if (!in_array('aes-256-ccm', openssl_get_cipher_methods())) |
| --FILE-- |
| <?php |
| require_once __DIR__ . "/cipher_tests.inc"; |
| -$method = 'aes-256-ccm'; |
| -$tests = openssl_get_cipher_tests($method); |
| +$methods = ['aes-128-ccm', 'aes-256-ccm']; |
| |
| -foreach ($tests as $idx => $test) { |
| - echo "TEST $idx\n"; |
| - $pt = openssl_decrypt($test['ct'], $method, $test['key'], OPENSSL_RAW_DATA, |
| - $test['iv'], $test['tag'], $test['aad']); |
| - var_dump($test['pt'] === $pt); |
| +foreach ($methods as $method) { |
| + $tests = openssl_get_cipher_tests($method); |
| + foreach ($tests as $idx => $test) { |
| + echo "$method - TEST $idx\n"; |
| + $pt = openssl_decrypt($test['ct'], $method, $test['key'], OPENSSL_RAW_DATA, |
| + $test['iv'], $test['tag'], $test['aad']); |
| + var_dump($test['pt'] === $pt); |
| + } |
| } |
| |
| // no IV |
| @@ -32,7 +34,11 @@ var_dump(openssl_decrypt($test['ct'], $method, $test['key'], OPENSSL_RAW_DATA, |
| |
| ?> |
| --EXPECTF-- |
| -TEST 0 |
| +aes-128-ccm - TEST 0 |
| +bool(true) |
| +aes-128-ccm - TEST 1 |
| +bool(true) |
| +aes-256-ccm - TEST 0 |
| bool(true) |
| |
| Warning: openssl_decrypt(): Setting of IV length for AEAD mode failed in %s on line %d |
| diff --git a/ext/openssl/tests/openssl_encrypt_ccm.phpt b/ext/openssl/tests/openssl_encrypt_ccm.phpt |
| index fb5dbbc8..8c4c41f8 100644 |
| --- a/ext/openssl/tests/openssl_encrypt_ccm.phpt |
| +++ b/ext/openssl/tests/openssl_encrypt_ccm.phpt |
| @@ -10,15 +10,17 @@ if (!in_array('aes-256-ccm', openssl_get_cipher_methods())) |
| --FILE-- |
| <?php |
| require_once __DIR__ . "/cipher_tests.inc"; |
| -$method = 'aes-256-ccm'; |
| -$tests = openssl_get_cipher_tests($method); |
| +$methods = ['aes-128-ccm', 'aes-256-ccm']; |
| |
| -foreach ($tests as $idx => $test) { |
| - echo "TEST $idx\n"; |
| - $ct = openssl_encrypt($test['pt'], $method, $test['key'], OPENSSL_RAW_DATA, |
| - $test['iv'], $tag, $test['aad'], strlen($test['tag'])); |
| - var_dump($test['ct'] === $ct); |
| - var_dump($test['tag'] === $tag); |
| +foreach ($methods as $method) { |
| + $tests = openssl_get_cipher_tests($method); |
| + foreach ($tests as $idx => $test) { |
| + echo "$method - TEST $idx\n"; |
| + $ct = openssl_encrypt($test['pt'], $method, $test['key'], OPENSSL_RAW_DATA, |
| + $test['iv'], $tag, $test['aad'], strlen($test['tag'])); |
| + var_dump($test['ct'] === $ct); |
| + var_dump($test['tag'] === $tag); |
| + } |
| } |
| |
| // Empty IV error |
| @@ -32,7 +34,13 @@ var_dump(strlen($tag)); |
| var_dump(openssl_encrypt('data', $method, 'password', 0, str_repeat('x', 16), $tag, '', 1024)); |
| ?> |
| --EXPECTF-- |
| -TEST 0 |
| +aes-128-ccm - TEST 0 |
| +bool(true) |
| +bool(true) |
| +aes-128-ccm - TEST 1 |
| +bool(true) |
| +bool(true) |
| +aes-256-ccm - TEST 0 |
| bool(true) |
| bool(true) |
| |
| -- |
| 2.25.1 |
| |