Skip to content

Commit 87d2bb7

Browse files
committed
Merge branch 'PHP-7.4' into PHP-8.0
* PHP-7.4: Fix CCM tag length setting for old OpenSSL versions
2 parents 2c82873 + 1359f79 commit 87d2bb7

File tree

1 file changed

+9
-11
lines changed

1 file changed

+9
-11
lines changed

ext/openssl/openssl.c

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -6888,8 +6888,9 @@ PHP_FUNCTION(openssl_digest)
68886888
/* Cipher mode info */
68896889
struct php_openssl_cipher_mode {
68906890
zend_bool is_aead;
6891-
zend_bool should_set_tag_length;
68926891
zend_bool is_single_run_aead;
6892+
zend_bool set_tag_length_always;
6893+
zend_bool set_tag_length_when_encrypting;
68936894
int aead_get_tag_flag;
68946895
int aead_set_tag_flag;
68956896
int aead_ivlen_flag;
@@ -6898,14 +6899,17 @@ struct php_openssl_cipher_mode {
68986899
static void php_openssl_load_cipher_mode(struct php_openssl_cipher_mode *mode, const EVP_CIPHER *cipher_type) /* {{{ */
68996900
{
69006901
int cipher_mode = EVP_CIPHER_mode(cipher_type);
6902+
memset(mode, 0, sizeof(struct php_openssl_cipher_mode));
69016903
switch (cipher_mode) {
69026904
#if PHP_OPENSSL_API_VERSION >= 0x10100
69036905
case EVP_CIPH_GCM_MODE:
69046906
case EVP_CIPH_OCB_MODE:
69056907
case EVP_CIPH_CCM_MODE:
69066908
mode->is_aead = 1;
6907-
mode->should_set_tag_length =
6908-
cipher_mode == EVP_CIPH_CCM_MODE || cipher_mode == EVP_CIPH_OCB_MODE;
6909+
/* For OCB mode, explicitly set the tag length even when decrypting,
6910+
* see https://github.com/openssl/openssl/issues/8331. */
6911+
mode->set_tag_length_always = cipher_mode == EVP_CIPH_OCB_MODE;
6912+
mode->set_tag_length_when_encrypting = cipher_mode == EVP_CIPH_CCM_MODE;
69096913
mode->is_single_run_aead = cipher_mode == EVP_CIPH_CCM_MODE;
69106914
mode->aead_get_tag_flag = EVP_CTRL_AEAD_GET_TAG;
69116915
mode->aead_set_tag_flag = EVP_CTRL_AEAD_SET_TAG;
@@ -6915,8 +6919,6 @@ static void php_openssl_load_cipher_mode(struct php_openssl_cipher_mode *mode, c
69156919
# ifdef EVP_CIPH_GCM_MODE
69166920
case EVP_CIPH_GCM_MODE:
69176921
mode->is_aead = 1;
6918-
mode->should_set_tag_length = 0;
6919-
mode->is_single_run_aead = 0;
69206922
mode->aead_get_tag_flag = EVP_CTRL_GCM_GET_TAG;
69216923
mode->aead_set_tag_flag = EVP_CTRL_GCM_SET_TAG;
69226924
mode->aead_ivlen_flag = EVP_CTRL_GCM_SET_IVLEN;
@@ -6925,16 +6927,14 @@ static void php_openssl_load_cipher_mode(struct php_openssl_cipher_mode *mode, c
69256927
# ifdef EVP_CIPH_CCM_MODE
69266928
case EVP_CIPH_CCM_MODE:
69276929
mode->is_aead = 1;
6928-
mode->should_set_tag_length = 1;
69296930
mode->is_single_run_aead = 1;
6931+
mode->set_tag_length_when_encrypting = 1;
69306932
mode->aead_get_tag_flag = EVP_CTRL_CCM_GET_TAG;
69316933
mode->aead_set_tag_flag = EVP_CTRL_CCM_SET_TAG;
69326934
mode->aead_ivlen_flag = EVP_CTRL_CCM_SET_IVLEN;
69336935
break;
69346936
# endif
69356937
#endif
6936-
default:
6937-
memset(mode, 0, sizeof(struct php_openssl_cipher_mode));
69386938
}
69396939
}
69406940
/* }}} */
@@ -7016,9 +7016,7 @@ static int php_openssl_cipher_init(const EVP_CIPHER *cipher_type,
70167016
if (php_openssl_validate_iv(piv, piv_len, max_iv_len, free_iv, cipher_ctx, mode) == FAILURE) {
70177017
return FAILURE;
70187018
}
7019-
if (mode->should_set_tag_length) {
7020-
/* Explicitly set the tag length even when decrypting,
7021-
* see https://github.com/openssl/openssl/issues/8331. */
7019+
if (mode->set_tag_length_always || (enc && mode->set_tag_length_when_encrypting)) {
70227020
if (!EVP_CIPHER_CTX_ctrl(cipher_ctx, mode->aead_set_tag_flag, tag_len, NULL)) {
70237021
php_error_docref(NULL, E_WARNING, "Setting tag length for AEAD cipher failed");
70247022
return FAILURE;

0 commit comments

Comments
 (0)