Skip to content

Commit 0749f20

Browse files
committed
Require exact tag length in EVP_DigestVerifyFinal HMAC path
ZD#21457 (31)
1 parent 0a00b47 commit 0749f20

3 files changed

Lines changed: 74 additions & 2 deletions

File tree

tests/api/test_evp_pkey.c

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -382,6 +382,76 @@ int test_wolfSSL_EVP_MD_hmac_signing(void)
382382
return EXPECT_RESULT();
383383
}
384384

385+
/* Verify that EVP_DigestVerifyFinal rejects zero-length HMAC tags. */
386+
int test_wolfSSL_EVP_DigestVerify_HMAC_zero_len_forgery(void)
387+
{
388+
EXPECT_DECLS;
389+
#if defined(OPENSSL_EXTRA) && !defined(NO_HMAC) && !defined(NO_SHA256)
390+
static const unsigned char key[] = {
391+
0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
392+
0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
393+
0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
394+
0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b
395+
};
396+
static const char message[] = "wolfSSL DigestVerifyFinal forgery probe";
397+
static const unsigned char zeros[WC_MAX_DIGEST_SIZE] = { 0 };
398+
399+
WOLFSSL_EVP_PKEY* pkey = NULL;
400+
WOLFSSL_EVP_MD_CTX mdCtx;
401+
unsigned char tag[WC_MAX_DIGEST_SIZE];
402+
size_t tagLen = sizeof(tag);
403+
404+
wolfSSL_EVP_MD_CTX_init(&mdCtx);
405+
406+
ExpectNotNull(pkey = wolfSSL_EVP_PKEY_new_mac_key(EVP_PKEY_HMAC, NULL,
407+
key, (int)sizeof(key)));
408+
409+
/* Compute the genuine HMAC-SHA256 tag for the message. */
410+
ExpectIntEQ(wolfSSL_EVP_DigestSignInit(&mdCtx, NULL, wolfSSL_EVP_sha256(),
411+
NULL, pkey), 1);
412+
ExpectIntEQ(wolfSSL_EVP_DigestSignUpdate(&mdCtx, message,
413+
(unsigned int)XSTRLEN(message)),
414+
1);
415+
ExpectIntEQ(wolfSSL_EVP_DigestSignFinal(&mdCtx, tag, &tagLen), 1);
416+
ExpectIntEQ((int)tagLen, WC_SHA256_DIGEST_SIZE);
417+
ExpectIntEQ(wolfSSL_EVP_MD_CTX_cleanup(&mdCtx), 1);
418+
419+
/* Full-length genuine tag verifies. */
420+
wolfSSL_EVP_MD_CTX_init(&mdCtx);
421+
ExpectIntEQ(wolfSSL_EVP_DigestVerifyInit(&mdCtx, NULL, wolfSSL_EVP_sha256(),
422+
NULL, pkey), 1);
423+
ExpectIntEQ(wolfSSL_EVP_DigestVerifyUpdate(&mdCtx, message,
424+
(unsigned int)XSTRLEN(message)),
425+
1);
426+
ExpectIntEQ(wolfSSL_EVP_DigestVerifyFinal(&mdCtx, tag, tagLen), 1);
427+
ExpectIntEQ(wolfSSL_EVP_MD_CTX_cleanup(&mdCtx), 1);
428+
429+
/* Wrong full-length tag is rejected. */
430+
wolfSSL_EVP_MD_CTX_init(&mdCtx);
431+
ExpectIntEQ(wolfSSL_EVP_DigestVerifyInit(&mdCtx, NULL, wolfSSL_EVP_sha256(),
432+
NULL, pkey), 1);
433+
ExpectIntEQ(wolfSSL_EVP_DigestVerifyUpdate(&mdCtx, message,
434+
(unsigned int)XSTRLEN(message)),
435+
1);
436+
ExpectIntNE(wolfSSL_EVP_DigestVerifyFinal(&mdCtx, zeros,
437+
WC_SHA256_DIGEST_SIZE), 1);
438+
ExpectIntEQ(wolfSSL_EVP_MD_CTX_cleanup(&mdCtx), 1);
439+
440+
/* Zero-length tag must be rejected. */
441+
wolfSSL_EVP_MD_CTX_init(&mdCtx);
442+
ExpectIntEQ(wolfSSL_EVP_DigestVerifyInit(&mdCtx, NULL, wolfSSL_EVP_sha256(),
443+
NULL, pkey), 1);
444+
ExpectIntEQ(wolfSSL_EVP_DigestVerifyUpdate(&mdCtx, message,
445+
(unsigned int)XSTRLEN(message)),
446+
1);
447+
ExpectIntNE(wolfSSL_EVP_DigestVerifyFinal(&mdCtx, zeros, 0), 1);
448+
ExpectIntEQ(wolfSSL_EVP_MD_CTX_cleanup(&mdCtx), 1);
449+
450+
wolfSSL_EVP_PKEY_free(pkey);
451+
#endif
452+
return EXPECT_RESULT();
453+
}
454+
385455
int test_wolfSSL_EVP_PKEY_new_mac_key(void)
386456
{
387457
EXPECT_DECLS;

tests/api/test_evp_pkey.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ int test_wolfSSL_EVP_PKEY_base_id(void);
3232
int test_wolfSSL_EVP_PKEY_id(void);
3333
int test_wolfSSL_EVP_MD_pkey_type(void);
3434
int test_wolfSSL_EVP_MD_hmac_signing(void);
35+
int test_wolfSSL_EVP_DigestVerify_HMAC_zero_len_forgery(void);
3536
int test_wolfSSL_EVP_PKEY_new_mac_key(void);
3637
int test_wolfSSL_EVP_PKEY_hkdf(void);
3738
int test_wolfSSL_EVP_PBE_scrypt(void);
@@ -70,6 +71,8 @@ int test_wolfSSL_EVP_PKEY_print_public(void);
7071
TEST_DECL_GROUP("evp_pkey", test_wolfSSL_EVP_PKEY_id), \
7172
TEST_DECL_GROUP("evp_pkey", test_wolfSSL_EVP_MD_pkey_type), \
7273
TEST_DECL_GROUP("evp_pkey", test_wolfSSL_EVP_MD_hmac_signing), \
74+
TEST_DECL_GROUP("evp_pkey", \
75+
test_wolfSSL_EVP_DigestVerify_HMAC_zero_len_forgery), \
7376
TEST_DECL_GROUP("evp_pkey", test_wolfSSL_EVP_PKEY_new_mac_key), \
7477
TEST_DECL_GROUP("evp_pkey", test_wolfSSL_EVP_PKEY_hkdf), \
7578
TEST_DECL_GROUP("evp_pkey", test_wolfSSL_EVP_PBE_scrypt), \

wolfcrypt/src/evp.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4992,9 +4992,8 @@ int wolfSSL_EVP_DigestVerifyFinal(WOLFSSL_EVP_MD_CTX *ctx,
49924992

49934993
hashLen = wolfssl_mac_len(ctx->hash.hmac.macType);
49944994

4995-
if (siglen > hashLen || siglen > INT_MAX)
4995+
if (hashLen == 0 || siglen != hashLen)
49964996
return WOLFSSL_FAILURE;
4997-
/* May be a truncated signature. */
49984997
}
49994998

50004999
if (wolfssl_evp_digest_pk_final(ctx, digest, &hashLen) <= 0)

0 commit comments

Comments
 (0)