diff --git a/wolfcrypt/src/aes.c b/wolfcrypt/src/aes.c index b7d43c33d13..02a6e1d4240 100644 --- a/wolfcrypt/src/aes.c +++ b/wolfcrypt/src/aes.c @@ -13661,10 +13661,12 @@ Aes* wc_AesNew_Label(const char* label, void* heap, int devId, int wc_AesDelete(Aes *aes, Aes** aes_p) { + void* heap; if (aes == NULL) return BAD_FUNC_ARG; + heap = aes->heap; wc_AesFree(aes); - XFREE(aes, aes->heap, DYNAMIC_TYPE_AES); + XFREE(aes, heap, DYNAMIC_TYPE_AES); if (aes_p != NULL) *aes_p = NULL; return 0; diff --git a/wolfcrypt/src/ext_lms.c b/wolfcrypt/src/ext_lms.c index cd354232034..c953abcfb38 100644 --- a/wolfcrypt/src/ext_lms.c +++ b/wolfcrypt/src/ext_lms.c @@ -861,6 +861,10 @@ int wc_LmsKey_Sign(LmsKey* key, byte * sig, word32 * sigSz, const byte * msg, sig, len, &key->info); if (!result) { + /* Erase any partial signature to prevent OTS key reuse if state + * is rolled back. */ + ForceZero(sig, len); + if (wc_LmsKey_SigsLeft(key) == 0) { WOLFSSL_MSG("error: LMS signatures exhausted"); key->state = WC_LMS_STATE_NOSIGS; diff --git a/wolfcrypt/src/hash.c b/wolfcrypt/src/hash.c index b500d2145ef..86a01999a1b 100644 --- a/wolfcrypt/src/hash.c +++ b/wolfcrypt/src/hash.c @@ -866,12 +866,14 @@ wc_HashAlg* wc_HashNew(enum wc_HashType type, void* heap, int devId, int wc_HashDelete(wc_HashAlg *hash, wc_HashAlg **hash_p) { int ret; + void* heap; if (hash == NULL) return BAD_FUNC_ARG; + heap = hash->heap; ret = wc_HashFree(hash, hash->type); if (ret < 0) return ret; - XFREE(hash, hash->heap, DYNAMIC_TYPE_HASHES); + XFREE(hash, heap, DYNAMIC_TYPE_HASHES); if (hash_p != NULL) *hash_p = NULL; return 0; diff --git a/wolfcrypt/src/hmac.c b/wolfcrypt/src/hmac.c index edc16f1a5fb..8e8ad3ff3e2 100644 --- a/wolfcrypt/src/hmac.c +++ b/wolfcrypt/src/hmac.c @@ -1590,6 +1590,10 @@ int wolfSSL_GetHmacMaxSize(void) const byte* localSalt; /* either points to user input or tmp */ word32 hashSz; + if (out == NULL || (inKey == NULL && inKeySz > 0)) { + return BAD_FUNC_ARG; + } + ret = wc_HmacSizeByType(type); if (ret < 0) { return ret; diff --git a/wolfcrypt/src/kdf.c b/wolfcrypt/src/kdf.c index c6be3afc992..849b6dfa52f 100644 --- a/wolfcrypt/src/kdf.c +++ b/wolfcrypt/src/kdf.c @@ -1009,7 +1009,8 @@ int wc_SRTP_KDF(const byte* key, word32 keySz, const byte* salt, word32 saltSz, /* Validate parameters. */ if ((key == NULL) || (keySz > AES_256_KEY_SIZE) || (salt == NULL) || - (saltSz > WC_SRTP_MAX_SALT) || (kdrIdx < -1) || (kdrIdx > 24)) { + (saltSz > WC_SRTP_MAX_SALT) || (kdrIdx < -1) || (kdrIdx > 24) || + ((kdrIdx >= 0) && (idx == NULL))) { ret = BAD_FUNC_ARG; } @@ -1103,7 +1104,8 @@ int wc_SRTCP_KDF_ex(const byte* key, word32 keySz, const byte* salt, word32 salt /* Validate parameters. */ if ((key == NULL) || (keySz > AES_256_KEY_SIZE) || (salt == NULL) || - (saltSz > WC_SRTP_MAX_SALT) || (kdrIdx < -1) || (kdrIdx > 24)) { + (saltSz > WC_SRTP_MAX_SALT) || (kdrIdx < -1) || (kdrIdx > 24) || + ((kdrIdx >= 0) && (idx == NULL))) { ret = BAD_FUNC_ARG; } @@ -1194,7 +1196,7 @@ int wc_SRTP_KDF_label(const byte* key, word32 keySz, const byte* salt, /* Validate parameters. */ if ((key == NULL) || (keySz > AES_256_KEY_SIZE) || (salt == NULL) || (saltSz > WC_SRTP_MAX_SALT) || (kdrIdx < -1) || (kdrIdx > 24) || - (outKey == NULL)) { + (outKey == NULL) || ((kdrIdx >= 0) && (idx == NULL))) { ret = BAD_FUNC_ARG; } @@ -1267,7 +1269,7 @@ int wc_SRTCP_KDF_label(const byte* key, word32 keySz, const byte* salt, /* Validate parameters. */ if ((key == NULL) || (keySz > AES_256_KEY_SIZE) || (salt == NULL) || (saltSz > WC_SRTP_MAX_SALT) || (kdrIdx < -1) || (kdrIdx > 24) || - (outKey == NULL)) { + (outKey == NULL) || ((kdrIdx >= 0) && (idx == NULL))) { ret = BAD_FUNC_ARG; } diff --git a/wolfcrypt/src/wc_lms.c b/wolfcrypt/src/wc_lms.c index f6aa7098c0c..402b2f3c5a4 100644 --- a/wolfcrypt/src/wc_lms.c +++ b/wolfcrypt/src/wc_lms.c @@ -1052,6 +1052,9 @@ int wc_LmsKey_Sign(LmsKey* key, byte* sig, word32* sigSz, const byte* msg, HSS_PRIVATE_KEY_LEN(key->params->hash_len), key->context); #endif if (rv != WC_LMS_RC_SAVED_TO_NV_MEMORY) { + /* Write to NV storage failed. Erase the signature from + * memory to prevent OTS key reuse if state is rolled back. */ + ForceZero(sig, key->params->sig_len); ret = IO_FAILED_E; } } diff --git a/wolfcrypt/src/wc_mlkem.c b/wolfcrypt/src/wc_mlkem.c index 95fa76e0f8f..74c4260a1cb 100644 --- a/wolfcrypt/src/wc_mlkem.c +++ b/wolfcrypt/src/wc_mlkem.c @@ -337,10 +337,12 @@ MlKemKey* wc_MlKemKey_New(int type, void* heap, int devId) int wc_MlKemKey_Delete(MlKemKey* key, MlKemKey** key_p) { + void* heap; if (key == NULL) return BAD_FUNC_ARG; + heap = key->heap; wc_MlKemKey_Free(key); - XFREE(key, key->heap, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(key, heap, DYNAMIC_TYPE_TMP_BUFFER); if (key_p != NULL) *key_p = NULL; diff --git a/wolfcrypt/test/test.c b/wolfcrypt/test/test.c index d639f523a44..b869dc19609 100644 --- a/wolfcrypt/test/test.c +++ b/wolfcrypt/test/test.c @@ -31466,7 +31466,18 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t hkdf_test(void) #endif /* !NO_SHA256 */ #endif /* !NO_SHA || !NO_SHA256 */ - return ret; +#ifndef NO_SHA256 + /* wc_HKDF_Extract bad arg: NULL out */ + ret = wc_HKDF_Extract(WC_SHA256, NULL, 0, ikm1, (word32)sizeof(ikm1), NULL); + if (ret != WC_NO_ERR_TRACE(BAD_FUNC_ARG)) + return WC_TEST_RET_ENC_EC(ret); + /* wc_HKDF_Extract bad arg: NULL inKey with non-zero inKeySz */ + ret = wc_HKDF_Extract(WC_SHA256, NULL, 0, NULL, 5, okm1); + if (ret != WC_NO_ERR_TRACE(BAD_FUNC_ARG)) + return WC_TEST_RET_ENC_EC(ret); +#endif /* !NO_SHA256 */ + + return 0; } #endif /* HAVE_HKDF */ @@ -33402,6 +33413,24 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t srtpkdf_test(void) if (ret != WC_NO_ERR_TRACE(BAD_FUNC_ARG)) ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); + /* kdrIdx >= 0 requires non-NULL idx. */ + ret = wc_SRTP_KDF(tv[i].key, tv[i].keySz, tv[i].salt, tv[i].saltSz, + 0, NULL, keyE, tv[i].keSz, keyA, tv[i].kaSz, keyS, tv[i].ksSz); + if (ret != WC_NO_ERR_TRACE(BAD_FUNC_ARG)) + ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); + ret = wc_SRTCP_KDF(tv[i].key, tv[i].keySz, tv[i].salt, tv[i].saltSz, + 0, NULL, keyE, tv[i].keSz, keyA, tv[i].kaSz, keyS, tv[i].ksSz); + if (ret != WC_NO_ERR_TRACE(BAD_FUNC_ARG)) + ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); + ret = wc_SRTP_KDF_label(tv[i].key, tv[i].keySz, tv[i].salt, tv[i].saltSz, + 0, NULL, WC_SRTP_LABEL_ENCRYPTION, keyE, tv[i].keSz); + if (ret != WC_NO_ERR_TRACE(BAD_FUNC_ARG)) + ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); + ret = wc_SRTCP_KDF_label(tv[i].key, tv[i].keySz, tv[i].salt, tv[i].saltSz, + 0, NULL, WC_SRTCP_LABEL_ENCRYPTION, keyE, tv[i].keSz); + if (ret != WC_NO_ERR_TRACE(BAD_FUNC_ARG)) + ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); + ret = wc_SRTP_KDF(tv[i].key, tv[i].keySz, tv[i].salt, tv[i].saltSz, tv[i].kdfIdx, tv[i].index, NULL, tv[i].keSz, keyA, tv[i].kaSz, keyS, tv[i].ksSz);