Skip to content

Improve HMAC and SHA-2 Zeroing#9785

Open
rizlik wants to merge 2 commits intowolfSSL:masterfrom
rizlik:sha2_fix_zeroing
Open

Improve HMAC and SHA-2 Zeroing#9785
rizlik wants to merge 2 commits intowolfSSL:masterfrom
rizlik:sha2_fix_zeroing

Conversation

@rizlik
Copy link
Contributor

@rizlik rizlik commented Feb 17, 2026

Description

In HMAC avoid zeroing the hash struct twice (once in ForceZero(Hmac) and one inside wc_ShaFree.
In HMAC forceZero only sensitive fields.
In Sha
Free forceZero only sensitive fields.
Refactor out Hash clean-up from HmacFree.

@rizlik rizlik marked this pull request as ready for review February 17, 2026 10:34
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Refines cleanup/zeroization behavior for HMAC and SHA-2 contexts to reduce redundant wiping and focus on sensitive fields.

Changes:

  • Adjust SHA-256/SHA-224 and SHA-512/SHA-384 free functions to zero only buffer and (conditionally) digest.
  • Refactor HMAC cleanup by extracting hash-state freeing into a helper and narrowing wc_HmacFree zeroization to specific fields.
  • Reduce full-struct ForceZero usage to avoid double-zeroing.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 5 comments.

File Description
wolfcrypt/src/sha512.c Changes wc_Sha512Free/wc_Sha384Free to selectively wipe buffer/digest instead of whole struct.
wolfcrypt/src/sha256.c Changes wc_Sha224Free/wc_Sha256Free to selectively wipe buffer/digest instead of whole struct.
wolfcrypt/src/hmac.c Refactors HMAC free path and narrows zeroization to ipad/opad/innerHash while delegating hash freeing.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +2350 to +2352
ForceZero(sha224->buffer, sizeof(sha224->buffer));
if (sha224->hiLen != 0 || sha224->loLen != 0)
ForceZero(sha224->digest, sizeof(sha224->digest));
Copy link

Copilot AI Feb 17, 2026

Choose a reason for hiding this comment

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

wc_Sha224 is typedef'd to struct wc_Sha256, but that struct does not always contain buffer, digest, hiLen, or loLen (e.g. STM32_HASH_SHA2, FREESCALE_LTC_SHA, WOLFSSL_IMXRT_DCP, PSOC6_HASH_SHA2, etc. in sha256.h). These unguarded member accesses will break builds for those configurations. Please conditionally compile this wiping logic only when the software digest/buffer fields are present, or provide an alternative wipe path for the other struct variants.

Copilot uses AI. Check for mistakes.
Comment on lines +2499 to +2501
ForceZero(sha256->buffer, sizeof(sha256->buffer));
if (sha256->hiLen != 0 || sha256->loLen != 0)
ForceZero(sha256->digest, sizeof(sha256->digest));
Copy link

Copilot AI Feb 17, 2026

Choose a reason for hiding this comment

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

struct wc_Sha256 does not always define buffer, digest, hiLen, or loLen (see the multiple hardware/PSA variants in sha256.h). These unguarded member accesses will fail to compile when any of those alternative layouts are enabled. Suggest wrapping this zeroing logic in preprocessor checks that match the struct definition, or falling back to wiping the whole struct when the software fields are not available.

Suggested change
ForceZero(sha256->buffer, sizeof(sha256->buffer));
if (sha256->hiLen != 0 || sha256->loLen != 0)
ForceZero(sha256->digest, sizeof(sha256->digest));
ForceZero(sha256, sizeof(*sha256));

Copilot uses AI. Check for mistakes.
Comment on lines +1403 to +1411
HmacFreeHash(hmac->macType, &hmac->hash);
#ifdef WOLFSSL_HMAC_COPY_HASH
HmacFreeHash(hmac->macType, &hmac->i_hash);
HmacFreeHash(hmac->macType, &hmac->o_hash);
#endif

ForceZero(hmac, sizeof(*hmac));
ForceZero(hmac->ipad, sizeof(hmac->ipad));
ForceZero(hmac->opad, sizeof(hmac->opad));
ForceZero(hmac->innerHash, sizeof(hmac->innerHash));
Copy link

Copilot AI Feb 17, 2026

Choose a reason for hiding this comment

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

wc_HmacFree no longer wipes the hmac->hash / i_hash / o_hash unions themselves. Several underlying hash *Free functions (e.g. wc_Md5Free, wc_ShaFree) do not zero their internal digest/buffer state, so keyed intermediate state from HMAC can be left in memory after wc_HmacFree. Please explicitly zero the hash unions after calling HmacFreeHash (or otherwise ensure each possible hash *Free reliably wipes sensitive state) to avoid a security regression.

Copilot uses AI. Check for mistakes.
Copy link
Contributor Author

Choose a reason for hiding this comment

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

MD5 and Sha zeroing should be handled in their respective freeing function imo, however I thought to do that in a following PR instead of this one.

Comment on lines +1691 to +1693
ForceZero(sha512->buffer, sizeof(sha512->buffer));
if (!(sha512->hiLen == 0 && sha512->loLen == 0))
ForceZero(sha512->digest, sizeof(sha512->digest));
Copy link

Copilot AI Feb 17, 2026

Choose a reason for hiding this comment

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

wc_Sha512 does not always have buffer, digest, hiLen, or loLen fields (e.g. when PSOC6_HASH_SHA2 is enabled in sha512.h). These direct member accesses will cause build failures for those configurations. Consider guarding these zeroing statements with the same preprocessor conditions as the struct layout (or falling back to ForceZero(sha512, sizeof(*sha512)) when the software fields are not present).

Copilot uses AI. Check for mistakes.
Comment on lines +2181 to +2183
ForceZero(sha384->buffer, sizeof(sha384->buffer));
if (!(sha384->hiLen == 0 && sha384->loLen == 0))
ForceZero(sha384->digest, sizeof(sha384->digest));
Copy link

Copilot AI Feb 17, 2026

Choose a reason for hiding this comment

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

wc_Sha384 is a typedef of wc_Sha512, and in some configurations (notably PSOC6_HASH_SHA2) the struct layout does not include buffer, digest, hiLen, or loLen. These member accesses will not compile in those builds. Please add appropriate #if/#else guards (or a safe fallback wipe) that matches the struct definition in sha512.h.

Copilot uses AI. Check for mistakes.
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.

2 participants