summaryrefslogtreecommitdiffstats
path: root/php-bug79601.patch
blob: b377887afff31c3f8a1a1e85969e92c815bd89ca (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
From 3528f51fe33944ba7bab263a47c49dd1d7dd12e3 Mon Sep 17 00:00:00 2001
From: Stanislav Malyshev <stas@php.net>
Date: Sat, 26 Sep 2020 22:08:52 -0700
Subject: [PATCH] Fix bug #79601 (Wrong ciphertext/tag in AES-CCM encryption
 for a 12 bytes IV)

(cherry picked from commit 0216630ea2815a5789a24279a1211ac398d4de79)
---
 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 39b6a20473..21c5367f72 100644
--- a/ext/openssl/openssl.c
+++ b/ext/openssl/openssl.c
@@ -6216,11 +6216,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");
@@ -6229,6 +6224,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 b1e46b411e..779bfa8515 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 87b6d4b264..479114719a 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 c8610bc96b..64a3b758e2 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
@@ -29,7 +31,13 @@ var_dump(openssl_encrypt('data', $method, 'password', 0, str_repeat('x', 10), $t
 var_dump(strlen($tag));
 ?>
 --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)
 
From 74495ac743e1896c3b33c954fcef54b412f87ac9 Mon Sep 17 00:00:00 2001
From: Jakub Zelenka <bukka@php.net>
Date: Sun, 2 Jun 2019 19:10:56 +0100
Subject: [PATCH] Fix bug #78079 (openssl_encrypt_ccm.phpt fails with OpenSSL
 1.1.1c)

It also fixes invalid setting of tag length

(cherry picked from commit 2e025794745e09f7d0c72822ad0238bf6d67b2e8)
---
 ext/openssl/openssl.c                      |  5 ++++-
 ext/openssl/tests/openssl_encrypt_ccm.phpt | 12 +++++++++---
 2 files changed, 13 insertions(+), 4 deletions(-)

diff --git a/ext/openssl/openssl.c b/ext/openssl/openssl.c
index 21c5367f72..72db9941d4 100644
--- a/ext/openssl/openssl.c
+++ b/ext/openssl/openssl.c
@@ -6289,7 +6289,10 @@ static int php_openssl_cipher_init(const EVP_CIPHER *cipher_type,
 		return FAILURE;
 	}
 	if (mode->is_single_run_aead && enc) {
-		EVP_CIPHER_CTX_ctrl(cipher_ctx, mode->aead_set_tag_flag, tag_len, NULL);
+		if (!EVP_CIPHER_CTX_ctrl(cipher_ctx, mode->aead_set_tag_flag, tag_len, NULL)) {
+			php_error_docref(NULL, E_WARNING, "Setting tag length for AEAD cipher failed");
+			return FAILURE;
+		}
 	} else if (!enc && tag && tag_len > 0) {
 		if (!mode->is_aead) {
 			php_error_docref(NULL, E_WARNING, "The tag cannot be used because the cipher method does not support AEAD");
diff --git a/ext/openssl/tests/openssl_encrypt_ccm.phpt b/ext/openssl/tests/openssl_encrypt_ccm.phpt
index 64a3b758e2..8c4c41f818 100644
--- a/ext/openssl/tests/openssl_encrypt_ccm.phpt
+++ b/ext/openssl/tests/openssl_encrypt_ccm.phpt
@@ -26,9 +26,12 @@ foreach ($methods as $method) {
 // Empty IV error
 var_dump(openssl_encrypt('data', $method, 'password', 0, NULL, $tag, ''));
 
-// Test setting different IV length and unlimeted tag
-var_dump(openssl_encrypt('data', $method, 'password', 0, str_repeat('x', 10), $tag, '', 1024));
+// Test setting different IV length and tag length
+var_dump(openssl_encrypt('data', $method, 'password', 0, str_repeat('x', 10), $tag, '', 14));
 var_dump(strlen($tag));
+
+// Test setting invalid tag length
+var_dump(openssl_encrypt('data', $method, 'password', 0, str_repeat('x', 16), $tag, '', 1024));
 ?>
 --EXPECTF--
 aes-128-ccm - TEST 0
@@ -44,4 +47,7 @@ bool(true)
 Warning: openssl_encrypt(): Setting of IV length for AEAD mode failed in %s on line %d
 bool(false)
 string(8) "p/lvgA=="
-int(1024)
+int(14)
+
+Warning: openssl_encrypt(): Setting of IV length for AEAD mode failed in %s on line %d
+bool(false)