Skip to content

Commit 65fa70f

Browse files
authored
Merge pull request #365 from padelsbach/wp-finding-255
Fix deep copy in wp_gmac_dup
2 parents 05d06d5 + 4d56ab8 commit 65fa70f

4 files changed

Lines changed: 131 additions & 2 deletions

File tree

src/wp_gmac.c

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,7 @@ static void wp_gmac_free(wp_GmacCtx* macCtx)
9494
{
9595
if (macCtx != NULL) {
9696
OPENSSL_cleanse(macCtx->key, macCtx->keyLen);
97+
OPENSSL_cleanse(macCtx->iv, macCtx->ivLen);
9798
OPENSSL_clear_free(macCtx->data, macCtx->dataLen);
9899
OPENSSL_free(macCtx);
99100
}
@@ -161,9 +162,24 @@ static wp_GmacCtx* wp_gmac_dup(wp_GmacCtx* src)
161162
}
162163
if (dst != NULL) {
163164
*dst = *src;
165+
dst->data = NULL;
166+
dst->dataLen = 0;
164167
dst->keyLen = 0;
165168
dst->ivLen = 0;
166169

170+
if (src->dataLen != 0) {
171+
dst->data = OPENSSL_memdup(src->data, src->dataLen);
172+
if (dst->data) {
173+
dst->dataLen = src->dataLen;
174+
}
175+
else {
176+
wp_gmac_free(dst);
177+
dst = NULL;
178+
}
179+
}
180+
}
181+
182+
if (dst != NULL) {
167183
if (src->ivLen != 0) {
168184
XMEMCPY(dst->iv, src->iv, src->ivLen);
169185
dst->ivLen = src->ivLen;

test/test_gmac.c

Lines changed: 113 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,118 @@ int test_gmac_create(void *data)
160160
return ret;
161161
}
162162

163-
#endif /* WP_HAVE_GMAC */
163+
int test_gmac_dup(void *data)
164+
{
165+
int ret = 0;
166+
EVP_MAC* emac = NULL;
167+
EVP_MAC_CTX* src = NULL;
168+
EVP_MAC_CTX* dup = NULL;
169+
OSSL_PARAM params[4];
170+
char cipher[] = "AES-256-GCM";
171+
unsigned char key[] = {
172+
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
173+
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
174+
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
175+
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07
176+
};
177+
unsigned char iv[] = {
178+
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
179+
0x00, 0x01, 0x02, 0x03
180+
};
181+
unsigned char prefix[] = "dup-prefix";
182+
unsigned char tailA[] = "-tail-a";
183+
unsigned char tailB[] = "-tail-b";
184+
unsigned char msgA[sizeof(prefix) + sizeof(tailA)];
185+
unsigned char msgB[sizeof(prefix) + sizeof(tailB)];
186+
unsigned char macA[16];
187+
unsigned char macB[16];
188+
unsigned char expA[16];
189+
unsigned char expB[16];
190+
size_t macASz = sizeof(macA);
191+
size_t macBSz = sizeof(macB);
192+
int expASz = sizeof(expA);
193+
int expBSz = sizeof(expB);
194+
195+
(void)data;
196+
197+
/* Build full messages used for one-shot expected MAC calculations. */
198+
XMEMCPY(msgA, prefix, sizeof(prefix));
199+
XMEMCPY(msgA + sizeof(prefix), tailA, sizeof(tailA));
200+
XMEMCPY(msgB, prefix, sizeof(prefix));
201+
XMEMCPY(msgB + sizeof(prefix), tailB, sizeof(tailB));
202+
203+
/* Compute expected MACs for each post-duplication branch. */
204+
ret = test_gmac_gen_mac(wpLibCtx, cipher, iv, (int)sizeof(iv), key,
205+
(int)sizeof(key), msgA, (int)sizeof(msgA), expA, &expASz);
206+
if (ret != 0) {
207+
PRINT_MSG("Generate expected MAC A failed");
208+
}
209+
if (ret == 0) {
210+
ret = test_gmac_gen_mac(wpLibCtx, cipher, iv, (int)sizeof(iv),
211+
key, (int)sizeof(key), msgB, (int)sizeof(msgB), expB, &expBSz);
212+
if (ret != 0) {
213+
PRINT_MSG("Generate expected MAC B failed");
214+
}
215+
}
216+
217+
params[0] = OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_CIPHER,
218+
cipher, 0);
219+
params[1] = OSSL_PARAM_construct_octet_string(OSSL_MAC_PARAM_KEY,
220+
(void*)key, sizeof(key));
221+
params[2] = OSSL_PARAM_construct_octet_string(OSSL_MAC_PARAM_IV,
222+
(void*)iv, sizeof(iv));
223+
params[3] = OSSL_PARAM_construct_end();
224+
225+
if (ret == 0) {
226+
ret = (emac = EVP_MAC_fetch(wpLibCtx, "GMAC", NULL)) == NULL;
227+
}
228+
if (ret == 0) {
229+
ret = (src = EVP_MAC_CTX_new(emac)) == NULL;
230+
}
231+
if (ret == 0) {
232+
ret = EVP_MAC_CTX_set_params(src, params) != 1;
233+
}
234+
if (ret == 0) {
235+
ret = EVP_MAC_init(src, NULL, 0, NULL) != 1;
236+
}
237+
if (ret == 0) {
238+
ret = EVP_MAC_update(src, prefix, sizeof(prefix)) != 1;
239+
}
240+
/* Duplicate after partial update so both contexts start from same state. */
241+
if (ret == 0) {
242+
ret = (dup = EVP_MAC_CTX_dup(src)) == NULL;
243+
}
244+
if (ret == 0) {
245+
ret = EVP_MAC_update(src, tailA, sizeof(tailA)) != 1;
246+
}
247+
if (ret == 0) {
248+
ret = EVP_MAC_update(dup, tailB, sizeof(tailB)) != 1;
249+
}
250+
if (ret == 0) {
251+
ret = EVP_MAC_final(src, macA, &macASz, sizeof(macA)) != 1;
252+
}
253+
if (ret == 0) {
254+
ret = EVP_MAC_final(dup, macB, &macBSz, sizeof(macB)) != 1;
255+
}
256+
/* Verify each branch matches its independently generated expected MAC. */
257+
if (ret == 0) {
258+
if ((macASz != (size_t)expASz) || (memcmp(macA, expA, macASz) != 0)) {
259+
PRINT_MSG("Duplicated source context MAC mismatch");
260+
ret = -1;
261+
}
262+
}
263+
if (ret == 0) {
264+
if ((macBSz != (size_t)expBSz) || (memcmp(macB, expB, macBSz) != 0)) {
265+
PRINT_MSG("Duplicated destination context MAC mismatch");
266+
ret = -1;
267+
}
268+
}
164269

270+
EVP_MAC_CTX_free(dup);
271+
EVP_MAC_CTX_free(src);
272+
EVP_MAC_free(emac);
165273

274+
return ret;
275+
}
276+
277+
#endif /* WP_HAVE_GMAC */

test/unit.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,7 @@ TEST_CASE test_case[] = {
209209
#endif
210210
#ifdef WP_HAVE_GMAC
211211
TEST_DECL(test_gmac_create, &flags),
212+
TEST_DECL(test_gmac_dup, &flags),
212213
#endif
213214
#ifdef WP_HAVE_TLS1_PRF
214215
TEST_DECL(test_tls1_prf, NULL),
@@ -813,4 +814,3 @@ int main(int argc, char* argv[])
813814

814815
return err;
815816
}
816-

test/unit.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,7 @@ int test_cmac_create(void *data);
123123

124124
#ifdef WP_HAVE_GMAC
125125
int test_gmac_create(void *data);
126+
int test_gmac_dup(void *data);
126127
#endif /* WP_HAVE_GMAC */
127128

128129
#ifdef WP_HAVE_TLS1_PRF

0 commit comments

Comments
 (0)