Fix: WolfCrypt Fenrir - 12 fixes#10786
Conversation
9046e08 to
8968849
Compare
|
retest this please |
|
Jenkins retest this please |
f0db333 to
60b22a5
Compare
|
Jenkins retest this please |
|
Jenkins retest this please |
1 similar comment
|
Jenkins retest this please |
60b22a5 to
06d9993
Compare
|
rebased branch on to master |
7a668b2 to
f475fe0
Compare
|
Jenkins retest this please. |
Frauschi
left a comment
There was a problem hiding this comment.
🐺 Skoll Code Review
Overall recommendation: REQUEST_CHANGES
Findings: 2 total — 2 posted, 0 skipped
Posted findings
- [High] wc_Sha256Copy frees a zero-initialized dst and closes fd 0 (devcrypto) —
wolfcrypt/src/port/devcrypto/devcrypto_hash.c:231 - [Medium] wc_Sha256Copy leaks the just-opened session on XMALLOC failure —
wolfcrypt/src/port/devcrypto/devcrypto_hash.c:238-241
Review generated by Skoll via Claude/Codex
f475fe0 to
5fea5ea
Compare
https://fenrir.wolfssl.com/finding/5384 https://fenrir.wolfssl.com/finding/4432 https://fenrir.wolfssl.com/finding/5392 https://fenrir.wolfssl.com/finding/5392 skoll fixes Changed type for keys for CAAM in ecc so it matches assignment with out cast to never truncate Added check to see if CAAM_ADDRESS is defined before using in ecc.h https://fenrir.wolfssl.com/finding/5994 https://fenrir.wolfssl.com/finding/4445 Fixed memory leaks for dev crypto and fixed https://fenrir.wolfssl.com/finding/4446 https://fenrir.wolfssl.com/finding/5418 https://fenrir.wolfssl.com/finding/5420 https://fenrir.wolfssl.com/finding/5411 https://fenrir.wolfssl.com/finding/5412 https://fenrir.wolfssl.com/finding/5413 Skoll Fixes github comment fix github review fixes skoll fixes
5fea5ea to
7947f01
Compare
Frauschi
left a comment
There was a problem hiding this comment.
Follow-up review — my three earlier wc_Sha256Copy findings are all fixed, thanks. A few adjacent items surfaced while re-checking the touched code:
- [Med] The
wc_fspsm_hw_unlock()fix for finding 5418 was only applied towc_fspsm_AesGcmEncrypt; the identicalreturn MEMORY_Ewith the lock held still exists in thewc_fspsm_AesGcmDecryptsibling. - [Med] The alloc-failure block frees the plain/cipher/aTag buffers but not the session-key buffers on a partial allocation.
- [Low]
wc_Sha256Finalstill has one error path that leaks the session/msg buffer. - [Nit]
cfd > 0vs the documented-1sentinel.
Details inline. #1 (the missing Decrypt unlock) is the one worth fixing before merge — it re-introduces the exact lock leak this PR set out to fix.
| XFREE(plainBuf, aes->heap, DYNAMIC_TYPE_AES); | ||
| XFREE(cipherBuf, aes->heap, DYNAMIC_TYPE_AES); | ||
| XFREE(aTagBuf, aes->heap, DYNAMIC_TYPE_AES); | ||
| wc_fspsm_hw_unlock(); |
There was a problem hiding this comment.
🟡 [Med] Incomplete fix — the sibling wc_fspsm_AesGcmDecrypt still leaks the HW lock
This added wc_fspsm_hw_unlock() correctly closes finding 5418 here in wc_fspsm_AesGcmEncrypt, but the structurally identical alloc-failure branch in wc_fspsm_AesGcmDecrypt (line ~645) still does a bare return MEMORY_E; after wc_fspsm_hw_lock() succeeded — so it returns with the hardware lock held, which is the same leak/deadlock this PR is meant to eliminate.
Please apply the same wc_fspsm_hw_unlock() before the return MEMORY_E; in the Decrypt path.
| @@ -414,6 +414,7 @@ int wc_fspsm_AesGcmEncrypt(struct Aes* aes, byte* out, | |||
| XFREE(plainBuf, aes->heap, DYNAMIC_TYPE_AES); | |||
| XFREE(cipherBuf, aes->heap, DYNAMIC_TYPE_AES); | |||
| XFREE(aTagBuf, aes->heap, DYNAMIC_TYPE_AES); | |||
There was a problem hiding this comment.
🟡 [Med] Session-key buffers leaked on partial allocation
This branch frees plainBuf/cipherBuf/aTagBuf, but if only one of key_client_aes / key_server_aes failed to allocate, the other (successfully allocated) buffer is never freed before return MEMORY_E. Since the PR is specifically fixing resource-leak-on-error in this exact block, the key buffers should be released too (same applies to the Decrypt sibling).
| ret = GetDigest(sha, CRYPTO_SHA2_256, hash); | ||
| if (ret != 0) { | ||
| return ret; | ||
| wc_Sha256Free(sha); |
There was a problem hiding this comment.
🟢 [Low] Adjacent error path in wc_Sha256Final still leaks the session
This wc_Sha256Free(sha) correctly closes the GetDigest error path (finding 4446), but the earlier HashUpdate error path a few lines up:
if ((ret = HashUpdate(sha, CRYPTO_SHA2_256, sha->msg, sha->used)) < 0) {
return ret; /* session + sha->msg still leaked */
}returns without freeing the kernel session or sha->msg. Same leak class the PR targets — worth freeing there too.
|
|
||
| wc_InitSha256_ex(dst, src->heap, 0); | ||
| #ifdef WOLFSSL_DEVCRYPTO_HASH_KEEP | ||
| if (dst->ctx.cfd > 0) { |
There was a problem hiding this comment.
⚪ [Nit] cfd > 0 is inconsistent with the -1 "no session" sentinel
The comment in wc_Sha256GetHash establishes cfd == -1 as the "no session" sentinel, but this guard treats cfd == 0 as "no session". Functionally > 0 is what protects fd 0, so this is fine as-is — but >= 0 (or != -1) would match the documented sentinel and would also free a session that legitimately landed on fd 0. Purely a consistency nit.
Description
https://fenrir.wolfssl.com/finding/6145
wc_DsaVerify/wc_DsaVerify_exleave*answeruninitialized on all error paths, unlike sibling ECC/ECCSI verify APIs that default to "not verified".answerparameter to zero so that on early exit the output parameter is defined as false.https://fenrir.wolfssl.com/finding/5384
CAAM secure-memory addresses are truncated to 32 bits in ECC keys.
ecc_keyfields toCAAM_ADDRESSwhen it is defined. This allows the address width to expand with the platform so addresses are not truncated.https://fenrir.wolfssl.com/finding/4432
wc_DrbgState_MutexInitunsafe lazy mutex initialization withoutWOLFSSL_MUTEX_INITIALIZER.int, we use atomic operations when they are present to initialize the mutex. This ensures that no two threads can initialize the same mutex.https://fenrir.wolfssl.com/finding/5392
DES key schedule branches on secret key bits.
ifstatement, we use a mask to set bits inks.https://fenrir.wolfssl.com/finding/5994
Invalid free / use-after-free of embedded X509 NAME in the ESP32 cert-bundle verify callback on a lookup miss.
esp_crt_bundle.c.https://fenrir.wolfssl.com/finding/4445
devcrypto
wc_Sha256Copyproduces a non-functional hash copy whenWOLFSSL_DEVCRYPTO_HASH_KEEPis disabled.https://fenrir.wolfssl.com/finding/4446
devcrypto
wc_Sha256Finalleaks the kernel hash session whenGetDigestfails.https://fenrir.wolfssl.com/finding/5418
FSPSM AES-GCM TLS key allocation failures return without unlocking hardware.
https://fenrir.wolfssl.com/finding/5420
FSPSM hash
Final/GetHashsilently succeeds when hardware hash initialization fails.retto an error value so that on return the error is no longer silent.https://fenrir.wolfssl.com/finding/5411
SipHash assembly paths load the caller key through
word64pointer casts.byte*toword64*casts to use theGET_U64()helper macro to protect against alignment issues.https://fenrir.wolfssl.com/finding/5412
Intel RDSEED/RDRAND generators write arbitrary output buffers as
word64.word64value, then usedwriteUnalignedWord64to transfer it into the output without alignment issues.https://fenrir.wolfssl.com/finding/5413
ML-KEM AArch64 noise helpers cast byte buffers and seeds to
word64pointers.writeUnalignedWord64instead of abyte*->word64*cast.