Skip to content

Fix: WolfCrypt Fenrir - 12 fixes#10786

Open
aidankeefe2022 wants to merge 1 commit into
wolfSSL:masterfrom
aidankeefe2022:fenrir-fixes-jun24/26-ak
Open

Fix: WolfCrypt Fenrir - 12 fixes#10786
aidankeefe2022 wants to merge 1 commit into
wolfSSL:masterfrom
aidankeefe2022:fenrir-fixes-jun24/26-ak

Conversation

@aidankeefe2022

@aidankeefe2022 aidankeefe2022 commented Jun 25, 2026

Copy link
Copy Markdown
Member

Description

https://fenrir.wolfssl.com/finding/6145

wc_DsaVerify/wc_DsaVerify_ex leave *answer uninitialized on all error paths, unlike sibling ECC/ECCSI verify APIs that default to "not verified".

  • Initialized the answer parameter 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.

  • Changed the ecc_key fields to CAAM_ADDRESS when 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_MutexInit unsafe lazy mutex initialization without WOLFSSL_MUTEX_INITIALIZER.

  • Instead of checking a plain 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.

  • Instead of an if statement, we use a mask to set bits in ks.

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.

  • Confirmed and removed the double free in esp_crt_bundle.c.

https://fenrir.wolfssl.com/finding/4445

devcrypto wc_Sha256Copy produces a non-functional hash copy when WOLFSSL_DEVCRYPTO_HASH_KEEP is disabled.

  • Made the function match the rest of the file and return an error when a copy is not available. Also freed the destination before the copy to fix a memory leak.

https://fenrir.wolfssl.com/finding/4446

devcrypto wc_Sha256Final leaks the kernel hash session when GetDigest fails.

  • Added a free on error, which uncovered and fixed memory leaks caught by tests when devcrypto is enabled.

https://fenrir.wolfssl.com/finding/5418

FSPSM AES-GCM TLS key allocation failures return without unlocking hardware.

  • Added a mutex unlock on memory allocation failure.

https://fenrir.wolfssl.com/finding/5420

FSPSM hash Final/GetHash silently succeeds when hardware hash initialization fails.

  • Set ret to 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 word64 pointer casts.

  • Swapped multiple byte* to word64* casts to use the GET_U64() helper macro to protect against alignment issues.

https://fenrir.wolfssl.com/finding/5412

Intel RDSEED/RDRAND generators write arbitrary output buffers as word64.

  • Added a temporary word64 value, then used writeUnalignedWord64 to 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 word64 pointers.

  • Used the alignment-protected helper function writeUnalignedWord64 instead of a byte* -> word64* cast.

@aidankeefe2022 aidankeefe2022 self-assigned this Jun 25, 2026
@aidankeefe2022 aidankeefe2022 changed the title https://fenrir.wolfssl.com/finding/6145 Fix: WolfCrypt Fenrir - 6145, 5384, 4432, 5392 Jun 25, 2026
@aidankeefe2022 aidankeefe2022 force-pushed the fenrir-fixes-jun24/26-ak branch from 9046e08 to 8968849 Compare June 26, 2026 18:34
@aidankeefe2022 aidankeefe2022 marked this pull request as ready for review June 26, 2026 18:47
@github-actions

Copy link
Copy Markdown

retest this please

@aidankeefe2022

Copy link
Copy Markdown
Member Author

Jenkins retest this please

@aidankeefe2022 aidankeefe2022 changed the title Fix: WolfCrypt Fenrir - 6145, 5384, 4432, 5392 Fix: WolfCrypt Fenrir - 6145, 5384, 4432, 5392, 5994, 4445, 4446, 5418, 5420, 5411, 5412, 5413 Jun 26, 2026
@aidankeefe2022 aidankeefe2022 force-pushed the fenrir-fixes-jun24/26-ak branch 3 times, most recently from f0db333 to 60b22a5 Compare June 26, 2026 21:10
@aidankeefe2022

Copy link
Copy Markdown
Member Author

Jenkins retest this please

@aidankeefe2022 aidankeefe2022 changed the title Fix: WolfCrypt Fenrir - 6145, 5384, 4432, 5392, 5994, 4445, 4446, 5418, 5420, 5411, 5412, 5413 Fix: WolfCrypt Fenrir - 12 fixes Jun 26, 2026
@aidankeefe2022

Copy link
Copy Markdown
Member Author

Jenkins retest this please

1 similar comment
@aidankeefe2022

Copy link
Copy Markdown
Member Author

Jenkins retest this please

@aidankeefe2022

Copy link
Copy Markdown
Member Author

rebased branch on to master

Comment thread wolfcrypt/src/port/devcrypto/devcrypto_hash.c Outdated
@aidankeefe2022 aidankeefe2022 force-pushed the fenrir-fixes-jun24/26-ak branch from 7a668b2 to f475fe0 Compare July 1, 2026 21:42
@Frauschi

Frauschi commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

Jenkins retest this please.

@Frauschi Frauschi left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🐺 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 failurewolfcrypt/src/port/devcrypto/devcrypto_hash.c:238-241

Review generated by Skoll via Claude/Codex

Comment thread wolfcrypt/src/port/devcrypto/devcrypto_hash.c Outdated
Comment thread wolfcrypt/src/port/devcrypto/devcrypto_hash.c
@aidankeefe2022 aidankeefe2022 force-pushed the fenrir-fixes-jun24/26-ak branch from f475fe0 to 5fea5ea Compare July 2, 2026 16:50

@Frauschi Frauschi left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 to wc_fspsm_AesGcmEncrypt; the identical return MEMORY_E with the lock held still exists in the wc_fspsm_AesGcmDecrypt sibling.
  • [Med] The alloc-failure block frees the plain/cipher/aTag buffers but not the session-key buffers on a partial allocation.
  • [Low] wc_Sha256Final still has one error path that leaks the session/msg buffer.
  • [Nit] cfd > 0 vs the documented -1 sentinel.

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();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 [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);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 [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);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟢 [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) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚪ [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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants