force local wc_nnn hash struct variables to zeros#6068
force local wc_nnn hash struct variables to zeros#6068gojimmypi wants to merge 4 commits intowolfSSL:masterfrom
Conversation
dgarske
left a comment
There was a problem hiding this comment.
Jim please consider properly fixing the initialization it in each of the hash init routines. Some of these already do a memset and this is now duplicated. Also the ForceZero should be memset.
wolfcrypt/src/hash.c
Outdated
| /* Typically only important to hardware acceleration, but a good | ||
| ** practice: we'll make sure the md5 we start with does not have | ||
| ** any unexpected values in any of the properties. */ | ||
| ForceZero(md5, sizeof(wc_Md5)); |
There was a problem hiding this comment.
Just use XMEMSET here please. The ForceZero is possible not as fast and is only required in places where there might be secrets that need cleared after use. This is just ensuring the data is zero'd, there shouldn't be any secrets left behind. Also this now duplicates work already done in some of the init functions. If using memset the compiler could optimize away the duplicate (not if ForceZero is used).
There was a problem hiding this comment.
This will have performance implications. My preference is to fix it in wc_InitMd5.
There was a problem hiding this comment.
I've reverted the changes to hash.c and moved the memory zeroize, now with XMEMSET instead of ForceZero into the respective inits.
There was a problem hiding this comment.
wolfcrypt/src/hash.c
Outdated
| /* Typically only important to hardware acceleration, but a good | ||
| ** practice: we'll make sure the sha we start with does not have | ||
| ** any unexpected values in any of the properties */ | ||
| ForceZero(sha, sizeof(wc_Sha)); |
wolfcrypt/src/hash.c
Outdated
| /* Typically only important to hardware acceleration, but a good | ||
| ** practice: we'll make sure the sha224 we start with does not have | ||
| ** any unexpected values in any of the properties */ | ||
| ForceZero(sha224, sizeof(wc_Sha224)); |
wolfcrypt/src/hash.c
Outdated
| /* Typically only important to hardware acceleration, but a good | ||
| ** practice: we'll make sure the sha256 we start with does not have | ||
| ** any unexpected values in any of the properties */ | ||
| ForceZero(sha256, sizeof(wc_Sha256)); |
wolfcrypt/src/hash.c
Outdated
| /* Typically only important to hardware acceleration, but a good | ||
| ** practice: we'll make sure the sha512 we start with does not have | ||
| ** any unexpected values in any of the properties. */ | ||
| ForceZero(sha512, sizeof(wc_Sha512)); |
wolfcrypt/src/hash.c
Outdated
| /* Typically only important to hardware acceleration, but a good | ||
| ** practice: we'll make sure the sha3 we start with does not have | ||
| ** any unexpected values in any of the properties. */ | ||
| ForceZero(sha3, sizeof(wc_Sha3)); |
wolfcrypt/src/hash.c
Outdated
| /* Typically only important to hardware acceleration, but a good | ||
| ** practice: we'll make sure the sha3 we start with does not have | ||
| ** any unexpected values in any of the properties. */ | ||
| ForceZero(sha3, sizeof(wc_Sha3)); |
wolfcrypt/src/hash.c
Outdated
| /* Typically only important to hardware acceleration, but a good | ||
| ** practice: we'll make sure the sha3 we start with does not have | ||
| ** any unexpected values in any of the properties. */ | ||
| ForceZero(sha3, sizeof(wc_Sha3)); |
wolfcrypt/src/hash.c
Outdated
| /* Typically only important to hardware acceleration, but a good | ||
| ** practice: we'll make sure the shake we start with does not have | ||
| ** any unexpected values in any of the properties. */ | ||
| ForceZero(shake, sizeof(wc_Shake)); |
wolfcrypt/src/hash.c
Outdated
| /* Typically only important to hardware acceleration, but a good | ||
| ** practice: we'll make sure the shake we start with does not have | ||
| ** any unexpected values in any of the properties. */ | ||
| ForceZero(shake, sizeof(wc_Shake)); |
|
Reverted Rechecked with wolftest: |
wolfcrypt/src/sha512.c
Outdated
| #if !defined(WOLFSSL_NOSHA512_224) | ||
| int wc_InitSha512_224(wc_Sha512* sha) | ||
| { | ||
| if (sha == NULL) |
There was a problem hiding this comment.
This is redundant. Already done in wc_InitSha512_224_ex -> InitSha512_Family.
There was a problem hiding this comment.
agreed. good catch. updated.
dgarske
left a comment
There was a problem hiding this comment.
Thanks Jim. FYI: I will squash this on merge.
|
Can one of the admins verify this patch? |
| return BAD_FUNC_ARG; | ||
| } | ||
|
|
||
| XMEMSET(sha224, 0, sizeof(wc_Sha224)); |
There was a problem hiding this comment.
Missed wc_InitSha256_ex()
There was a problem hiding this comment.
@SparkiDev thanks for your review! Would you recommend that I do a XMEMSET in each of these?
I'm not entirely convinced it is a good idea for software-only hashes. The only reason I found this and started to do the initializations was due to undesired hardware encryption state data being copied into a new sha ctx instance.
Please advise. Thank you.
- Edit: Here's a code explorer view for conversation sake:
There was a problem hiding this comment.
If the PR is to memset the data structure when using hardware and they are the implementations for hardware, then yes.
If you can't find a common for each function, then it needs to be done in each.
| return BAD_FUNC_ARG; | ||
| } | ||
|
|
||
| XMEMSET(sha512, 0, sizeof(wc_Sha512)); |
There was a problem hiding this comment.
Missed wc_InitSha383_ex().
|
I have a higher performance, less brute-force method of initialization in the works. Closing this PR; New PR will be created from my WIP ED25519_SHA2_fix Branch. |
|
For reference, the root cause of the ED25519 failures are noted in #5948 (comment) and fixed in #6287. The root cause was the use of in-progress |


Description
Related to the #5948 ED25519 failure, this update forces the local SHA struct values to all zeros before using them. This is typically only important to hash hardware acceleration where existing HW state may be stored in the
ctxand otherwise have potentially bad data if not properly initialized or worse: copied from another SHActxthat may have active hardware acceleration computation state values.Recall only one given HW acceleration computation can be in process at a given time on the ESP32. Although the ESP32-C3 does seem to have the ability for concurrent HW encryption, that's beyond the scope of this PR and in any case we'd still need a properly initialized variable anyhow.
Note this PR is not a substitute for proper SHA ctx self validation to check for creation from a copy as noted in #5948 (comment), and is not meant to be a final fix to #5948 . A separate PR will be created soon.
There's a small performance hit when assigning zeros at every use. I'm open to suggestions if this should only be applied for relevant platforms, such as the Espressif ESP32 with Hardware Acceleration. I chose to do it all the time as a Best Practice to have variables always safely initialized.
Fixes zd# n/a
Testing
How did you test? Ran the wolfcrypt test for both embedded ESP32 and Linux.
Checklist