From 7195678d27c5cc7f51c3946b528207870a5bd5fa Mon Sep 17 00:00:00 2001 From: Jeremiah Mackey Date: Tue, 5 May 2026 22:12:51 +0000 Subject: [PATCH 1/5] add AEAD bad tag tests --- tests/api/test_aes.c | 64 ++++++++++++++++++++++++++++++ tests/api/test_aes.h | 2 + tests/api/test_chacha20_poly1305.c | 60 ++++++++++++++++++++++++++++ tests/api/test_chacha20_poly1305.h | 2 + 4 files changed, 128 insertions(+) diff --git a/tests/api/test_aes.c b/tests/api/test_aes.c index 3d4eda1eec7..9740f351616 100644 --- a/tests/api/test_aes.c +++ b/tests/api/test_aes.c @@ -4392,6 +4392,70 @@ int test_wc_AesGcmStream_ReinitAfterFinal(void) return EXPECT_RESULT(); } /* END test_wc_AesGcmStream_ReinitAfterFinal */ +int test_wc_AesGcmStream_BadAuthTag(void) +{ + EXPECT_DECLS; +#if !defined(NO_AES) && defined(HAVE_AESGCM) && defined(HAVE_AES_DECRYPT) && \ + defined(WOLFSSL_AES_128) && defined(WOLFSSL_AESGCM_STREAM) + static const byte key[AES_128_KEY_SIZE] = { + 0xfe,0xff,0xe9,0x92, 0x86,0x65,0x73,0x1c, + 0x6d,0x6a,0x8f,0x94, 0x67,0x30,0x83,0x08 + }; + static const byte iv[GCM_NONCE_MID_SZ] = { + 0xca,0xfe,0xba,0xbe, 0xfa,0xce,0xdb,0xad, + 0xde,0xca,0xf8,0x88 + }; + static const byte aad[20] = { + 0xfe,0xed,0xfa,0xce, 0xde,0xad,0xbe,0xef, + 0xfe,0xed,0xfa,0xce, 0xde,0xad,0xbe,0xef, + 0xab,0xad,0xda,0xd2 + }; + static const byte plain[16] = { + 0xd9,0x31,0x32,0x25, 0xf8,0x84,0x06,0xe5, + 0xa5,0x59,0x09,0xc5, 0xaf,0xf5,0x26,0x9a + }; + Aes enc[1]; + Aes dec[1]; + byte ct[sizeof(plain)]; + byte pt[sizeof(plain)]; + byte tag[WC_AES_BLOCK_SIZE]; + byte bad_aad[sizeof(aad)]; + + XMEMSET(enc, 0, sizeof(Aes)); + XMEMSET(dec, 0, sizeof(Aes)); + XMEMSET(tag, 0, sizeof(tag)); + + ExpectIntEQ(wc_AesInit(enc, NULL, INVALID_DEVID), 0); + ExpectIntEQ(wc_AesGcmInit(enc, key, sizeof(key), iv, sizeof(iv)), 0); + ExpectIntEQ(wc_AesGcmEncryptUpdate(enc, ct, plain, sizeof(plain), + aad, sizeof(aad)), 0); + ExpectIntEQ(wc_AesGcmEncryptFinal(enc, tag, sizeof(tag)), 0); + wc_AesFree(enc); + + tag[0] ^= 0x01; + + ExpectIntEQ(wc_AesInit(dec, NULL, INVALID_DEVID), 0); + ExpectIntEQ(wc_AesGcmDecryptInit(dec, key, sizeof(key), iv, sizeof(iv)), 0); + ExpectIntEQ(wc_AesGcmDecryptUpdate(dec, pt, ct, sizeof(ct), + aad, sizeof(aad)), 0); + ExpectIntEQ(wc_AesGcmDecryptFinal(dec, tag, sizeof(tag)), + WC_NO_ERR_TRACE(AES_GCM_AUTH_E)); + wc_AesFree(dec); + + tag[0] ^= 0x01; + XMEMCPY(bad_aad, aad, sizeof(aad)); + bad_aad[0] ^= 0x01; + ExpectIntEQ(wc_AesInit(dec, NULL, INVALID_DEVID), 0); + ExpectIntEQ(wc_AesGcmDecryptInit(dec, key, sizeof(key), iv, sizeof(iv)), 0); + ExpectIntEQ(wc_AesGcmDecryptUpdate(dec, pt, ct, sizeof(ct), + bad_aad, sizeof(bad_aad)), 0); + ExpectIntEQ(wc_AesGcmDecryptFinal(dec, tag, sizeof(tag)), + WC_NO_ERR_TRACE(AES_GCM_AUTH_E)); + wc_AesFree(dec); +#endif + return EXPECT_RESULT(); +} + /******************************************************************************* * GMAC ******************************************************************************/ diff --git a/tests/api/test_aes.h b/tests/api/test_aes.h index 51f0ba3efcd..e4b6c84339e 100644 --- a/tests/api/test_aes.h +++ b/tests/api/test_aes.h @@ -54,6 +54,7 @@ int test_wc_AesGcmNonStdNonce(void); int test_wc_AesGcmStream(void); int test_wc_AesGcmStream_MidStreamState(void); int test_wc_AesGcmStream_ReinitAfterFinal(void); +int test_wc_AesGcmStream_BadAuthTag(void); int test_wc_AesCcmSetKey(void); int test_wc_AesCcmEncryptDecrypt(void); int test_wc_AesCcmEncryptDecrypt_InPlace(void); @@ -133,6 +134,7 @@ int test_wc_CryptoCb_AesGcm_EncryptDecrypt(void); TEST_DECL_GROUP("aes", test_wc_AesGcmStream), \ TEST_DECL_GROUP("aes", test_wc_AesGcmStream_MidStreamState), \ TEST_DECL_GROUP("aes", test_wc_AesGcmStream_ReinitAfterFinal), \ + TEST_DECL_GROUP("aes", test_wc_AesGcmStream_BadAuthTag), \ TEST_DECL_GROUP("aes", test_wc_AesCcmSetKey), \ TEST_DECL_GROUP("aes", test_wc_AesCcmEncryptDecrypt), \ TEST_DECL_GROUP("aes", test_wc_AesCcmEncryptDecrypt_InPlace), \ diff --git a/tests/api/test_chacha20_poly1305.c b/tests/api/test_chacha20_poly1305.c index 9a8ad4032b0..6f90c71712c 100644 --- a/tests/api/test_chacha20_poly1305.c +++ b/tests/api/test_chacha20_poly1305.c @@ -284,6 +284,66 @@ int test_wc_XChaCha20Poly1305_aead(void) return EXPECT_RESULT(); } /* END test_wc_XChaCha20Poly1305_aead */ +int test_wc_XChaCha20Poly1305_BadAuthTag(void) +{ + EXPECT_DECLS; +#if defined(HAVE_POLY1305) && defined(HAVE_XCHACHA) + const byte key[32] = { + 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, + 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, + 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, + 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f + }; + const byte nonce[24] = { + 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, + 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, + 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57 + }; + const byte plaintext[] = { + 0x4c, 0x61, 0x64, 0x69, 0x65, 0x73, 0x20, 0x61, + 0x6e, 0x64, 0x20, 0x47, 0x65, 0x6e, 0x74, 0x73 + }; + const byte aad[] = { + 0x50, 0x51, 0x52, 0x53, 0xc0, 0xc1, 0xc2, 0xc3 + }; + byte ct[sizeof(plaintext) + 16]; + byte pt[sizeof(plaintext)]; + byte ct_bad[sizeof(ct)]; + byte aad_bad[sizeof(aad)]; + + XMEMSET(ct, 0, sizeof(ct)); + + ExpectIntEQ(wc_XChaCha20Poly1305_Encrypt(ct, sizeof(ct), + plaintext, sizeof(plaintext), aad, sizeof(aad), + nonce, sizeof(nonce), key, sizeof(key)), 0); + + ExpectIntEQ(wc_XChaCha20Poly1305_Decrypt(pt, sizeof(pt), ct, sizeof(ct), + aad, sizeof(aad), nonce, sizeof(nonce), key, sizeof(key)), 0); + + XMEMCPY(ct_bad, ct, sizeof(ct)); + ct_bad[sizeof(ct) - 1] ^= 0x01; + ExpectIntEQ(wc_XChaCha20Poly1305_Decrypt(pt, sizeof(pt), ct_bad, + sizeof(ct_bad), aad, sizeof(aad), nonce, sizeof(nonce), + key, sizeof(key)), + WC_NO_ERR_TRACE(MAC_CMP_FAILED_E)); + + XMEMCPY(ct_bad, ct, sizeof(ct)); + ct_bad[0] ^= 0x01; + ExpectIntEQ(wc_XChaCha20Poly1305_Decrypt(pt, sizeof(pt), ct_bad, + sizeof(ct_bad), aad, sizeof(aad), nonce, sizeof(nonce), + key, sizeof(key)), + WC_NO_ERR_TRACE(MAC_CMP_FAILED_E)); + + XMEMCPY(aad_bad, aad, sizeof(aad)); + aad_bad[0] ^= 0x01; + ExpectIntEQ(wc_XChaCha20Poly1305_Decrypt(pt, sizeof(pt), ct, sizeof(ct), + aad_bad, sizeof(aad_bad), nonce, sizeof(nonce), + key, sizeof(key)), + WC_NO_ERR_TRACE(MAC_CMP_FAILED_E)); +#endif + return EXPECT_RESULT(); +} + #include #define MC_CIPHER_TEST_COUNT 100 diff --git a/tests/api/test_chacha20_poly1305.h b/tests/api/test_chacha20_poly1305.h index 398d1d939c0..22d3cc6af33 100644 --- a/tests/api/test_chacha20_poly1305.h +++ b/tests/api/test_chacha20_poly1305.h @@ -26,6 +26,7 @@ int test_wc_ChaCha20Poly1305_aead(void); int test_wc_XChaCha20Poly1305_aead(void); +int test_wc_XChaCha20Poly1305_BadAuthTag(void); int test_wc_ChaCha20Poly1305_MonteCarlo(void); int test_wc_ChaCha20Poly1305_Stream(void); int test_wc_ChaCha20Poly1305_AeadEdgeCases(void); @@ -38,6 +39,7 @@ int test_wc_ChaCha20Poly1305_CrossCipher(void); #define TEST_CHACHA20_POLY1305_DECLS \ TEST_DECL_GROUP("chacha20-poly1305", test_wc_ChaCha20Poly1305_aead), \ TEST_DECL_GROUP("xchacha20-poly1305", test_wc_XChaCha20Poly1305_aead), \ + TEST_DECL_GROUP("xchacha20-poly1305", test_wc_XChaCha20Poly1305_BadAuthTag), \ TEST_DECL_GROUP("chacha20-poly1305", test_wc_ChaCha20Poly1305_MonteCarlo), \ TEST_DECL_GROUP("chacha20-poly1305", test_wc_ChaCha20Poly1305_Stream), \ TEST_DECL_GROUP("chacha20-poly1305", test_wc_ChaCha20Poly1305_AeadEdgeCases), \ From f53f57097c5b7e332cde055e451cc61c3824e439 Mon Sep 17 00:00:00 2001 From: Jeremiah Mackey Date: Thu, 23 Apr 2026 16:18:33 +0000 Subject: [PATCH 2/5] add PKCS7 tampered attribs tests --- tests/api/test_pkcs7.c | 96 ++++++++++++++++++++++++++++++++++++++++++ tests/api/test_pkcs7.h | 4 ++ 2 files changed, 100 insertions(+) diff --git a/tests/api/test_pkcs7.c b/tests/api/test_pkcs7.c index 3c8b59fb8e4..ed84665921e 100644 --- a/tests/api/test_pkcs7.c +++ b/tests/api/test_pkcs7.c @@ -2103,6 +2103,54 @@ int test_wc_PKCS7_VerifySignedData_RSA(void) return EXPECT_RESULT(); } /* END test_wc_PKCS7_VerifySignedData()_RSA */ +int test_wc_PKCS7_VerifySignedData_TamperedAttribs(void) +{ + EXPECT_DECLS; +#if defined(HAVE_PKCS7) && !defined(NO_FILESYSTEM) && !defined(NO_RSA) + PKCS7* pkcs7 = NULL; + byte output[6000]; + word32 outputSz = sizeof(output); + byte data[] = "Test data to encode."; + /* SCEP messageType OID + SET { PrintableString "19" } */ + const byte pattern[] = { + 0x06, 0x0a, 0x60, 0x86, 0x48, 0x01, 0x86, 0xF8, + 0x45, 0x01, 0x09, 0x02, + 0x31, 0x04, 0x13, 0x02, 0x31, 0x39 + }; + word32 i; + int found = -1; + int matches = 0; + + XMEMSET(output, 0, outputSz); + ExpectIntGT((outputSz = (word32)CreatePKCS7SignedData(output, (int)outputSz, + data, (word32)sizeof(data), + 1 /* withAttribs */, 0 /* detached */, 0, RSA_TYPE)), 0); + + if (outputSz > 0 && outputSz <= sizeof(output)) { + for (i = 0; i + sizeof(pattern) <= outputSz; i++) { + if (XMEMCMP(output + i, pattern, sizeof(pattern)) == 0) { + if (matches == 0) + found = (int)i; + matches++; + } + } + ExpectIntEQ(matches, 1); + } + + if (matches == 1 && found >= 0) { + output[found + (int)sizeof(pattern) - 1] ^= 0x01; + + ExpectNotNull(pkcs7 = wc_PKCS7_New(HEAP_HINT, testDevId)); + ExpectIntEQ(wc_PKCS7_InitWithCert(pkcs7, NULL, 0), 0); + ExpectIntEQ(wc_PKCS7_VerifySignedData(pkcs7, output, outputSz), + WC_NO_ERR_TRACE(SIG_VERIFY_E)); + wc_PKCS7_Free(pkcs7); + pkcs7 = NULL; + } +#endif + return EXPECT_RESULT(); +} + /* * Testing wc_PKCS_VerifySignedData() */ @@ -2292,6 +2340,54 @@ int test_wc_PKCS7_VerifySignedData_ECC(void) return EXPECT_RESULT(); } /* END test_wc_PKCS7_VerifySignedData_ECC() */ +int test_wc_PKCS7_VerifySignedData_ECC_TamperedAttribs(void) +{ + EXPECT_DECLS; +#if defined(HAVE_PKCS7) && !defined(NO_FILESYSTEM) && defined(HAVE_ECC) + PKCS7* pkcs7 = NULL; + byte output[6000]; + word32 outputSz = sizeof(output); + byte data[] = "Test data to encode."; + /* SCEP messageType OID + SET { PrintableString "19" } */ + const byte pattern[] = { + 0x06, 0x0a, 0x60, 0x86, 0x48, 0x01, 0x86, 0xF8, + 0x45, 0x01, 0x09, 0x02, + 0x31, 0x04, 0x13, 0x02, 0x31, 0x39 + }; + word32 i; + int found = -1; + int matches = 0; + + XMEMSET(output, 0, outputSz); + ExpectIntGT((outputSz = (word32)CreatePKCS7SignedData(output, (int)outputSz, + data, (word32)sizeof(data), + 1 /* withAttribs */, 0 /* detached */, 0, ECC_TYPE)), 0); + + if (outputSz > 0 && outputSz <= sizeof(output)) { + for (i = 0; i + sizeof(pattern) <= outputSz; i++) { + if (XMEMCMP(output + i, pattern, sizeof(pattern)) == 0) { + if (matches == 0) + found = (int)i; + matches++; + } + } + ExpectIntEQ(matches, 1); + } + + if (matches == 1 && found >= 0) { + output[found + (int)sizeof(pattern) - 1] ^= 0x01; + + ExpectNotNull(pkcs7 = wc_PKCS7_New(HEAP_HINT, testDevId)); + ExpectIntEQ(wc_PKCS7_InitWithCert(pkcs7, NULL, 0), 0); + ExpectIntEQ(wc_PKCS7_VerifySignedData(pkcs7, output, outputSz), + WC_NO_ERR_TRACE(SIG_VERIFY_E)); + wc_PKCS7_Free(pkcs7); + pkcs7 = NULL; + } +#endif + return EXPECT_RESULT(); +} + #if defined(HAVE_PKCS7) && !defined(NO_AES) && defined(HAVE_AES_CBC) && \ defined(WOLFSSL_AES_256) && defined(HAVE_AES_KEYWRAP) diff --git a/tests/api/test_pkcs7.h b/tests/api/test_pkcs7.h index 084744d43c6..2eb6e0e8e01 100644 --- a/tests/api/test_pkcs7.h +++ b/tests/api/test_pkcs7.h @@ -40,7 +40,9 @@ int test_wc_PKCS7_EnvelopedData_KTRI_RSA_PSS(void); #endif int test_wc_PKCS7_EncodeSignedData_ex(void); int test_wc_PKCS7_VerifySignedData_RSA(void); +int test_wc_PKCS7_VerifySignedData_TamperedAttribs(void); int test_wc_PKCS7_VerifySignedData_ECC(void); +int test_wc_PKCS7_VerifySignedData_ECC_TamperedAttribs(void); int test_wc_PKCS7_DecodeEnvelopedData_stream(void); int test_wc_PKCS7_EncodeDecodeEnvelopedData(void); int test_wc_PKCS7_SetAESKeyWrapUnwrapCb(void); @@ -89,7 +91,9 @@ int test_wc_PKCS7_VerifySignedData_IndefLenOOB(void); TEST_PKCS7_RSA_PSS_SD_DECL \ TEST_DECL_GROUP("pkcs7_sd", test_wc_PKCS7_EncodeSignedData_ex), \ TEST_DECL_GROUP("pkcs7_sd", test_wc_PKCS7_VerifySignedData_RSA), \ + TEST_DECL_GROUP("pkcs7_sd", test_wc_PKCS7_VerifySignedData_TamperedAttribs), \ TEST_DECL_GROUP("pkcs7_sd", test_wc_PKCS7_VerifySignedData_ECC), \ + TEST_DECL_GROUP("pkcs7_sd", test_wc_PKCS7_VerifySignedData_ECC_TamperedAttribs), \ TEST_DECL_GROUP("pkcs7_sd", test_wc_PKCS7_Degenerate), \ TEST_DECL_GROUP("pkcs7_sd", test_wc_PKCS7_BER), \ TEST_DECL_GROUP("pkcs7_sd", test_wc_PKCS7_NoDefaultSignedAttribs), \ From 93addb731149284bcfda7c92da1a795d4d2b92fa Mon Sep 17 00:00:00 2001 From: Jeremiah Mackey Date: Thu, 23 Apr 2026 16:18:33 +0000 Subject: [PATCH 3/5] add PQ key integrity tests --- tests/api/test_mlkem.c | 51 +++++++++++++++++++++++++++++++++++++++++ tests/api/test_mlkem.h | 4 +++- tests/api/test_slhdsa.c | 4 ++++ 3 files changed, 58 insertions(+), 1 deletion(-) diff --git a/tests/api/test_mlkem.c b/tests/api/test_mlkem.c index 4ff76604387..966e0278d2b 100644 --- a/tests/api/test_mlkem.c +++ b/tests/api/test_mlkem.c @@ -4018,3 +4018,54 @@ int test_wc_mlkem_decap_fo_reject(void) return EXPECT_RESULT(); } /* END test_wc_mlkem_decap_fo_reject */ +int test_wc_mlkem_decode_privkey_bad_pubhash(void) +{ + EXPECT_DECLS; +#if defined(WOLFSSL_HAVE_MLKEM) && defined(WOLFSSL_WC_MLKEM) && \ + !defined(WOLFSSL_NO_ML_KEM) && !defined(WOLFSSL_MLKEM_NO_MAKE_KEY) + MlKemKey* key = NULL; + WC_RNG rng; + byte priv[WC_ML_KEM_MAX_PRIVATE_KEY_SIZE]; + word32 privLen = 0; +#ifndef WOLFSSL_NO_ML_KEM_768 + const int mlkemType = WC_ML_KEM_768; +#elif !defined(WOLFSSL_NO_ML_KEM_512) + const int mlkemType = WC_ML_KEM_512; +#else + const int mlkemType = WC_ML_KEM_1024; +#endif + + XMEMSET(&rng, 0, sizeof(rng)); + XMEMSET(priv, 0, sizeof(priv)); + + key = (MlKemKey*)XMALLOC(sizeof(*key), NULL, DYNAMIC_TYPE_TMP_BUFFER); + ExpectNotNull(key); + ExpectIntEQ(wc_InitRng(&rng), 0); + + ExpectIntEQ(wc_MlKemKey_Init(key, mlkemType, NULL, INVALID_DEVID), 0); + ExpectIntEQ(wc_MlKemKey_MakeKey(key, &rng), 0); + ExpectIntEQ(wc_MlKemKey_PrivateKeySize(key, &privLen), 0); + ExpectTrue(privLen > (word32)(2 * WC_ML_KEM_SYM_SZ)); + ExpectIntEQ(wc_MlKemKey_EncodePrivateKey(key, priv, privLen), 0); + + wc_MlKemKey_Free(key); + ExpectIntEQ(wc_MlKemKey_Init(key, mlkemType, NULL, INVALID_DEVID), 0); + ExpectIntEQ(wc_MlKemKey_DecodePrivateKey(key, priv, privLen), 0); + wc_MlKemKey_Free(key); + + /* Tamper H(ek) (32 bytes before z). */ + if (privLen > (word32)(2 * WC_ML_KEM_SYM_SZ)) { + priv[privLen - 2 * WC_ML_KEM_SYM_SZ] ^= 0x01; + } + + ExpectIntEQ(wc_MlKemKey_Init(key, mlkemType, NULL, INVALID_DEVID), 0); + ExpectIntEQ(wc_MlKemKey_DecodePrivateKey(key, priv, privLen), + WC_NO_ERR_TRACE(MLKEM_PUB_HASH_E)); + wc_MlKemKey_Free(key); + + DoExpectIntEQ(wc_FreeRng(&rng), 0); + XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER); +#endif + return EXPECT_RESULT(); +} /* END test_wc_mlkem_decode_privkey_bad_pubhash */ + diff --git a/tests/api/test_mlkem.h b/tests/api/test_mlkem.h index 2c166409b66..d8dc2e51073 100644 --- a/tests/api/test_mlkem.h +++ b/tests/api/test_mlkem.h @@ -29,12 +29,14 @@ int test_wc_mlkem_encapsulate_kats(void); int test_wc_mlkem_decapsulate_kats(void); int test_wc_mlkem_decapsulate_pubonly_fails(void); int test_wc_mlkem_decap_fo_reject(void); +int test_wc_mlkem_decode_privkey_bad_pubhash(void); #define TEST_MLKEM_DECLS \ TEST_DECL_GROUP("mlkem", test_wc_mlkem_make_key_kats), \ TEST_DECL_GROUP("mlkem", test_wc_mlkem_encapsulate_kats), \ TEST_DECL_GROUP("mlkem", test_wc_mlkem_decapsulate_kats), \ TEST_DECL_GROUP("mlkem", test_wc_mlkem_decapsulate_pubonly_fails), \ - TEST_DECL_GROUP("mlkem", test_wc_mlkem_decap_fo_reject) + TEST_DECL_GROUP("mlkem", test_wc_mlkem_decap_fo_reject), \ + TEST_DECL_GROUP("mlkem", test_wc_mlkem_decode_privkey_bad_pubhash) #endif /* WOLFCRYPT_TEST_MLKEM_H */ diff --git a/tests/api/test_slhdsa.c b/tests/api/test_slhdsa.c index fc40bed9c7a..9bc89b34959 100644 --- a/tests/api/test_slhdsa.c +++ b/tests/api/test_slhdsa.c @@ -1164,6 +1164,10 @@ int test_wc_slhdsa_check_key(void) ExpectIntEQ(wc_SlhDsaKey_ImportPublic(&key, pubKey, pubKeyLen), 0); ExpectIntEQ(wc_SlhDsaKey_ImportPrivate(&key, privKey, privKeyLen), 0); ExpectIntEQ(wc_SlhDsaKey_CheckKey(&key), 0); + + key.sk[0] ^= 0x01; + ExpectIntEQ(wc_SlhDsaKey_CheckKey(&key), + WC_NO_ERR_TRACE(WC_KEY_MISMATCH_E)); wc_SlhDsaKey_Free(&key); wc_FreeRng(&rng); From e1010765c38ff0e28f21e1c6b4e7ab2cc19b1036 Mon Sep 17 00:00:00 2001 From: Jeremiah Mackey Date: Thu, 23 Apr 2026 16:18:33 +0000 Subject: [PATCH 4/5] add signature negative verify tests --- tests/api/test_dsa.c | 10 ++++++++ tests/api/test_rsa.c | 59 ++++++++++++++++++++++++++++++++++++++++++++ tests/api/test_rsa.h | 2 ++ 3 files changed, 71 insertions(+) diff --git a/tests/api/test_dsa.c b/tests/api/test_dsa.c index 4605d48abbf..0813f727a12 100644 --- a/tests/api/test_dsa.c +++ b/tests/api/test_dsa.c @@ -117,6 +117,16 @@ int test_wc_DsaSignVerify(void) ExpectIntEQ(wc_DsaVerify(hash, signature, NULL, &answer), WC_NO_ERR_TRACE(BAD_FUNC_ARG)); ExpectIntEQ(wc_DsaVerify(hash, signature, &key, NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG)); + { + byte badHash[WC_SHA_DIGEST_SIZE]; + + XMEMCPY(badHash, hash, sizeof(badHash)); + badHash[0] ^= 0x01; + answer = 1; + ExpectIntEQ(wc_DsaVerify(badHash, signature, &key, &answer), 0); + ExpectIntEQ(answer, 0); + } + #if !defined(HAVE_SELFTEST) && !defined(HAVE_FIPS) && defined(WOLFSSL_PUBLIC_MP) /* hard set q to 0 and test fail case */ mp_free(&key.q); diff --git a/tests/api/test_rsa.c b/tests/api/test_rsa.c index 862af44d1ce..ddf2c6917b6 100644 --- a/tests/api/test_rsa.c +++ b/tests/api/test_rsa.c @@ -491,6 +491,65 @@ int test_wc_RsaPSS_Verify(void) return EXPECT_RESULT(); } /* END test_wc_RsaPSS_Verify */ +int test_wc_RsaPSS_BadTerminator(void) +{ + EXPECT_DECLS; +#if !defined(NO_RSA) && defined(WOLFSSL_KEY_GEN) && !defined(HAVE_SELFTEST) && \ + !defined(HAVE_FIPS) && defined(WC_RSA_BLINDING) && defined(WC_RSA_PSS) && \ + (defined(WC_RSA_DIRECT) || defined(WC_RSA_NO_PADDING) || \ + defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)) + RsaKey key; + WC_RNG rng; + const char* msg = "This is the string to be signed"; + unsigned char sig[2048/8]; + unsigned char em[2048/8]; + unsigned char badSig[2048/8]; + unsigned char verifyOut[2048/8]; + int sigLen = 0; + word32 emSz = sizeof(em); + word32 badSigSz = sizeof(badSig); + + XMEMSET(&key, 0, sizeof(RsaKey)); + XMEMSET(&rng, 0, sizeof(WC_RNG)); + XMEMSET(em, 0, sizeof(em)); + XMEMSET(sig, 0, sizeof(sig)); + XMEMSET(badSig, 0, sizeof(badSig)); + + ExpectIntEQ(wc_InitRsaKey(&key, HEAP_HINT), 0); + ExpectIntEQ(wc_InitRng(&rng), 0); + ExpectIntEQ(wc_RsaSetRNG(&key, &rng), 0); + ExpectIntEQ(wc_MakeRsaKey(&key, 2048, WC_RSA_EXPONENT, &rng), 0); + + ExpectIntGT(sigLen = wc_RsaPSS_Sign((const byte*)msg, + (word32)XSTRLEN(msg) + 1, sig, sizeof(sig), + WC_HASH_TYPE_SHA256, WC_MGF1SHA256, &key, &rng), 0); + + ExpectIntGT(wc_RsaDirect(sig, (word32)sigLen, em, &emSz, &key, + RSA_PUBLIC_DECRYPT, NULL), 0); + + ExpectTrue(emSz > 0); + if (emSz > 0) { + ExpectIntEQ((int)em[emSz - 1], 0xbc); + } + + if (emSz > 0 && em[emSz - 1] == 0xbc) { + em[emSz - 1] = 0xbd; + + ExpectIntGT(wc_RsaDirect(em, emSz, badSig, &badSigSz, &key, + RSA_PRIVATE_ENCRYPT, &rng), 0); + + ExpectIntEQ(wc_RsaPSS_Verify(badSig, badSigSz, verifyOut, + sizeof(verifyOut), + WC_HASH_TYPE_SHA256, WC_MGF1SHA256, &key), + WC_NO_ERR_TRACE(BAD_PADDING_E)); + } + + DoExpectIntEQ(wc_FreeRsaKey(&key), 0); + DoExpectIntEQ(wc_FreeRng(&rng), 0); +#endif + return EXPECT_RESULT(); +} /* END test_wc_RsaPSS_BadTerminator */ + /* * Testing wc_RsaPSS_VerifyCheck() */ diff --git a/tests/api/test_rsa.h b/tests/api/test_rsa.h index ff1af18e812..3ba60132259 100644 --- a/tests/api/test_rsa.h +++ b/tests/api/test_rsa.h @@ -32,6 +32,7 @@ int test_wc_RsaPrivateKeyDecodeRaw(void); int test_wc_MakeRsaKey(void); int test_wc_CheckProbablePrime(void); int test_wc_RsaPSS_Verify(void); +int test_wc_RsaPSS_BadTerminator(void); int test_wc_RsaPSS_VerifyCheck(void); int test_wc_RsaPSS_VerifyCheckInline(void); int test_wc_RsaKeyToDer(void); @@ -52,6 +53,7 @@ int test_wc_RsaDecrypt_BoundsCheck(void); TEST_DECL_GROUP("rsa", test_wc_MakeRsaKey), \ TEST_DECL_GROUP("rsa", test_wc_CheckProbablePrime), \ TEST_DECL_GROUP("rsa", test_wc_RsaPSS_Verify), \ + TEST_DECL_GROUP("rsa", test_wc_RsaPSS_BadTerminator), \ TEST_DECL_GROUP("rsa", test_wc_RsaPSS_VerifyCheck), \ TEST_DECL_GROUP("rsa", test_wc_RsaPSS_VerifyCheckInline), \ TEST_DECL_GROUP("rsa", test_wc_RsaKeyToDer), \ From 4034b53e5201ef02f565f4db34dab42e7ccdd39f Mon Sep 17 00:00:00 2001 From: Jeremiah Mackey Date: Thu, 23 Apr 2026 16:18:33 +0000 Subject: [PATCH 5/5] add DRBG reseed boundary test --- tests/api/test_random.c | 35 +++++++++++++++++++++++++++++++++++ tests/api/test_random.h | 2 ++ 2 files changed, 37 insertions(+) diff --git a/tests/api/test_random.c b/tests/api/test_random.c index fe8aaf0ee15..f6930789ce9 100644 --- a/tests/api/test_random.c +++ b/tests/api/test_random.c @@ -94,6 +94,41 @@ int test_wc_RNG_GenerateBlock_Reseed(void) return EXPECT_RESULT(); } +int test_wc_RNG_ReseedBoundary(void) +{ + EXPECT_DECLS; +#if defined(HAVE_HASHDRBG) && !defined(CUSTOM_RAND_GENERATE_BLOCK) && \ + !defined(HAVE_FIPS) && !defined(HAVE_SELFTEST) + WC_RNG rng; + struct DRBG_internal* drbg; + byte out[32]; +#ifdef WORD64_AVAILABLE + word64 startCtr; +#else + word32 startCtr; +#endif + + XMEMSET(&rng, 0, sizeof(WC_RNG)); + ExpectIntEQ(wc_InitRng(&rng), 0); + + drbg = (struct DRBG_internal*)rng.drbg; + if (drbg != NULL && rng.status == WC_DRBG_OK) { + startCtr = drbg->reseedCtr; + ExpectIntEQ(wc_RNG_GenerateBlock(&rng, out, sizeof(out)), 0); + if (drbg->reseedCtr == startCtr + 1) { + drbg->reseedCtr = WC_RESEED_INTERVAL - 1; + ExpectIntEQ(wc_RNG_GenerateBlock(&rng, out, sizeof(out)), 0); + ExpectTrue(drbg->reseedCtr == WC_RESEED_INTERVAL); + ExpectIntEQ(wc_RNG_GenerateBlock(&rng, out, sizeof(out)), 0); + ExpectTrue(drbg->reseedCtr == 2); + } + } + + DoExpectIntEQ(wc_FreeRng(&rng), 0); +#endif + return EXPECT_RESULT(); +} + int test_wc_RNG_GenerateBlock(void) { EXPECT_DECLS; diff --git a/tests/api/test_random.h b/tests/api/test_random.h index a6478b38df9..3db015dc83f 100644 --- a/tests/api/test_random.h +++ b/tests/api/test_random.h @@ -26,6 +26,7 @@ int test_wc_InitRng(void); int test_wc_RNG_GenerateBlock_Reseed(void); +int test_wc_RNG_ReseedBoundary(void); int test_wc_RNG_GenerateBlock(void); int test_wc_RNG_GenerateByte(void); int test_wc_InitRngNonce(void); @@ -39,6 +40,7 @@ int test_wc_RNG_HealthTest(void); #define TEST_RANDOM_DECLS \ TEST_DECL_GROUP("random", test_wc_InitRng), \ TEST_DECL_GROUP("random", test_wc_RNG_GenerateBlock_Reseed), \ + TEST_DECL_GROUP("random", test_wc_RNG_ReseedBoundary), \ TEST_DECL_GROUP("random", test_wc_RNG_GenerateBlock), \ TEST_DECL_GROUP("random", test_wc_RNG_GenerateByte), \ TEST_DECL_GROUP("random", test_wc_InitRngNonce), \