Require exact tag length in EVP_DigestVerifyFinal HMAC path

ZD#21457 (31)
This commit is contained in:
Mattia Moffa
2026-04-10 22:15:37 +02:00
parent 0a00b47c75
commit 0749f20c33
3 changed files with 74 additions and 2 deletions
+70
View File
@@ -382,6 +382,76 @@ int test_wolfSSL_EVP_MD_hmac_signing(void)
return EXPECT_RESULT();
}
/* Verify that EVP_DigestVerifyFinal rejects zero-length HMAC tags. */
int test_wolfSSL_EVP_DigestVerify_HMAC_zero_len_forgery(void)
{
EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && !defined(NO_HMAC) && !defined(NO_SHA256)
static const unsigned char key[] = {
0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b
};
static const char message[] = "wolfSSL DigestVerifyFinal forgery probe";
static const unsigned char zeros[WC_MAX_DIGEST_SIZE] = { 0 };
WOLFSSL_EVP_PKEY* pkey = NULL;
WOLFSSL_EVP_MD_CTX mdCtx;
unsigned char tag[WC_MAX_DIGEST_SIZE];
size_t tagLen = sizeof(tag);
wolfSSL_EVP_MD_CTX_init(&mdCtx);
ExpectNotNull(pkey = wolfSSL_EVP_PKEY_new_mac_key(EVP_PKEY_HMAC, NULL,
key, (int)sizeof(key)));
/* Compute the genuine HMAC-SHA256 tag for the message. */
ExpectIntEQ(wolfSSL_EVP_DigestSignInit(&mdCtx, NULL, wolfSSL_EVP_sha256(),
NULL, pkey), 1);
ExpectIntEQ(wolfSSL_EVP_DigestSignUpdate(&mdCtx, message,
(unsigned int)XSTRLEN(message)),
1);
ExpectIntEQ(wolfSSL_EVP_DigestSignFinal(&mdCtx, tag, &tagLen), 1);
ExpectIntEQ((int)tagLen, WC_SHA256_DIGEST_SIZE);
ExpectIntEQ(wolfSSL_EVP_MD_CTX_cleanup(&mdCtx), 1);
/* Full-length genuine tag verifies. */
wolfSSL_EVP_MD_CTX_init(&mdCtx);
ExpectIntEQ(wolfSSL_EVP_DigestVerifyInit(&mdCtx, NULL, wolfSSL_EVP_sha256(),
NULL, pkey), 1);
ExpectIntEQ(wolfSSL_EVP_DigestVerifyUpdate(&mdCtx, message,
(unsigned int)XSTRLEN(message)),
1);
ExpectIntEQ(wolfSSL_EVP_DigestVerifyFinal(&mdCtx, tag, tagLen), 1);
ExpectIntEQ(wolfSSL_EVP_MD_CTX_cleanup(&mdCtx), 1);
/* Wrong full-length tag is rejected. */
wolfSSL_EVP_MD_CTX_init(&mdCtx);
ExpectIntEQ(wolfSSL_EVP_DigestVerifyInit(&mdCtx, NULL, wolfSSL_EVP_sha256(),
NULL, pkey), 1);
ExpectIntEQ(wolfSSL_EVP_DigestVerifyUpdate(&mdCtx, message,
(unsigned int)XSTRLEN(message)),
1);
ExpectIntNE(wolfSSL_EVP_DigestVerifyFinal(&mdCtx, zeros,
WC_SHA256_DIGEST_SIZE), 1);
ExpectIntEQ(wolfSSL_EVP_MD_CTX_cleanup(&mdCtx), 1);
/* Zero-length tag must be rejected. */
wolfSSL_EVP_MD_CTX_init(&mdCtx);
ExpectIntEQ(wolfSSL_EVP_DigestVerifyInit(&mdCtx, NULL, wolfSSL_EVP_sha256(),
NULL, pkey), 1);
ExpectIntEQ(wolfSSL_EVP_DigestVerifyUpdate(&mdCtx, message,
(unsigned int)XSTRLEN(message)),
1);
ExpectIntNE(wolfSSL_EVP_DigestVerifyFinal(&mdCtx, zeros, 0), 1);
ExpectIntEQ(wolfSSL_EVP_MD_CTX_cleanup(&mdCtx), 1);
wolfSSL_EVP_PKEY_free(pkey);
#endif
return EXPECT_RESULT();
}
int test_wolfSSL_EVP_PKEY_new_mac_key(void)
{
EXPECT_DECLS;
+3
View File
@@ -32,6 +32,7 @@ int test_wolfSSL_EVP_PKEY_base_id(void);
int test_wolfSSL_EVP_PKEY_id(void);
int test_wolfSSL_EVP_MD_pkey_type(void);
int test_wolfSSL_EVP_MD_hmac_signing(void);
int test_wolfSSL_EVP_DigestVerify_HMAC_zero_len_forgery(void);
int test_wolfSSL_EVP_PKEY_new_mac_key(void);
int test_wolfSSL_EVP_PKEY_hkdf(void);
int test_wolfSSL_EVP_PBE_scrypt(void);
@@ -70,6 +71,8 @@ int test_wolfSSL_EVP_PKEY_print_public(void);
TEST_DECL_GROUP("evp_pkey", test_wolfSSL_EVP_PKEY_id), \
TEST_DECL_GROUP("evp_pkey", test_wolfSSL_EVP_MD_pkey_type), \
TEST_DECL_GROUP("evp_pkey", test_wolfSSL_EVP_MD_hmac_signing), \
TEST_DECL_GROUP("evp_pkey", \
test_wolfSSL_EVP_DigestVerify_HMAC_zero_len_forgery), \
TEST_DECL_GROUP("evp_pkey", test_wolfSSL_EVP_PKEY_new_mac_key), \
TEST_DECL_GROUP("evp_pkey", test_wolfSSL_EVP_PKEY_hkdf), \
TEST_DECL_GROUP("evp_pkey", test_wolfSSL_EVP_PBE_scrypt), \
+1 -2
View File
@@ -4992,9 +4992,8 @@ int wolfSSL_EVP_DigestVerifyFinal(WOLFSSL_EVP_MD_CTX *ctx,
hashLen = wolfssl_mac_len(ctx->hash.hmac.macType);
if (siglen > hashLen || siglen > INT_MAX)
if (hashLen == 0 || siglen != hashLen)
return WOLFSSL_FAILURE;
/* May be a truncated signature. */
}
if (wolfssl_evp_digest_pk_final(ctx, digest, &hashLen) <= 0)