summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ext/openssl/openssl.c5
-rw-r--r--ext/openssl/tests/openssl_decrypt_ccm.phpt38
2 files changed, 41 insertions, 2 deletions
diff --git a/ext/openssl/openssl.c b/ext/openssl/openssl.c
index d87d9b931f..a02b8adeab 100644
--- a/ext/openssl/openssl.c
+++ b/ext/openssl/openssl.c
@@ -5483,7 +5483,7 @@ PHP_FUNCTION(openssl_decrypt)
const EVP_CIPHER *cipher_type;
EVP_CIPHER_CTX *cipher_ctx;
struct php_openssl_cipher_mode mode;
- int i, outlen;
+ int outlen, i = 0;
zend_string *outbuf;
zend_string *base64_str = NULL;
zend_bool free_iv = 0, free_password = 0;
@@ -5534,7 +5534,8 @@ PHP_FUNCTION(openssl_decrypt)
php_openssl_cipher_update(cipher_type, cipher_ctx, &mode, &outbuf, &outlen,
data, data_len, aad, aad_len, 0) == FAILURE) {
RETVAL_FALSE;
- } else if (EVP_DecryptFinal(cipher_ctx, (unsigned char *)ZSTR_VAL(outbuf) + outlen, &i)) {
+ } else if (mode.is_single_run_aead ||
+ EVP_DecryptFinal(cipher_ctx, (unsigned char *)ZSTR_VAL(outbuf) + outlen, &i)) {
outlen += i;
ZSTR_VAL(outbuf)[outlen] = '\0';
ZSTR_LEN(outbuf) = outlen;
diff --git a/ext/openssl/tests/openssl_decrypt_ccm.phpt b/ext/openssl/tests/openssl_decrypt_ccm.phpt
new file mode 100644
index 0000000000..359ce42ed9
--- /dev/null
+++ b/ext/openssl/tests/openssl_decrypt_ccm.phpt
@@ -0,0 +1,38 @@
+--TEST--
+openssl_decrypt() with CCM cipher algorithm tests
+--SKIPIF--
+<?php
+if (!extension_loaded("openssl"))
+ die("skip");
+if (!in_array('aes-256-ccm', openssl_get_cipher_methods()))
+ die("skip: aes-256-ccm not available");
+?>
+--FILE--
+<?php
+require_once __DIR__ . "/cipher_tests.inc";
+$method = 'aes-256-ccm';
+$tests = openssl_get_cipher_tests($method);
+
+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);
+}
+
+// no IV
+var_dump(openssl_decrypt($test['ct'], $method, $test['key'], 0, NULL, $test['tag'], $test['aad']));
+// failed because no AAD
+var_dump(openssl_decrypt($test['ct'], $method, $test['key'], 0, $test['iv'], $test['tag']));
+// failed because wrong tag
+var_dump(openssl_decrypt($test['ct'], $method, $test['key'], 0, $test['iv'], str_repeat('x', 10), $test['aad']));
+
+?>
+--EXPECTF--
+TEST 0
+bool(true)
+
+Warning: openssl_decrypt(): Setting of IV length for AEAD mode failed, the expected length is 12 bytes in %s on line %d
+bool(false)
+bool(false)
+bool(false)