Skip to content

force local wc_nnn hash struct variables to zeros#6068

Closed
gojimmypi wants to merge 4 commits intowolfSSL:masterfrom
gojimmypi:hash_force_zero
Closed

force local wc_nnn hash struct variables to zeros#6068
gojimmypi wants to merge 4 commits intowolfSSL:masterfrom
gojimmypi:hash_force_zero

Conversation

@gojimmypi
Copy link
Contributor

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 ctx and otherwise have potentially bad data if not properly initialized or worse: copied from another SHA ctx that 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

  • added tests
  • updated/added doxygen
  • updated appropriate READMEs
  • Updated manual and documentation

@gojimmypi gojimmypi self-assigned this Feb 8, 2023
@dgarske dgarske self-assigned this Feb 8, 2023
Copy link
Contributor

@dgarske dgarske left a comment

Choose a reason for hiding this comment

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

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.

/* 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));
Copy link
Contributor

Choose a reason for hiding this comment

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

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).

Copy link
Contributor

Choose a reason for hiding this comment

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

This will have performance implications. My preference is to fix it in wc_InitMd5.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I've reverted the changes to hash.c and moved the memory zeroize, now with XMEMSET instead of ForceZero into the respective inits.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

duplicates work already done in some of the init functions

@dgarske regarding this topic,: Although the ESP32 SHA tests pass, the RSA fails when the apparently duplicate XMEMSET here which should be ok to omit, as it is also here in the call to InitSha256. Clearly there's more research to be done.

/* 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));
Copy link
Contributor

Choose a reason for hiding this comment

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

Same

Copy link
Contributor Author

Choose a reason for hiding this comment

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

moved to md5.c

/* 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));
Copy link
Contributor

Choose a reason for hiding this comment

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

Same

Copy link
Contributor Author

Choose a reason for hiding this comment

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

moved to sha256.c

/* 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));
Copy link
Contributor

Choose a reason for hiding this comment

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

Same

Copy link
Contributor Author

Choose a reason for hiding this comment

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

moved to sha256.c

/* 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));
Copy link
Contributor

Choose a reason for hiding this comment

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

Same

Copy link
Contributor Author

Choose a reason for hiding this comment

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

moved to sha512.c

/* 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));
Copy link
Contributor

Choose a reason for hiding this comment

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

Same

Copy link
Contributor Author

Choose a reason for hiding this comment

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

moved to sha3c

/* 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));
Copy link
Contributor

Choose a reason for hiding this comment

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

Same

Copy link
Contributor Author

Choose a reason for hiding this comment

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

moved to sha3c

/* 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));
Copy link
Contributor

Choose a reason for hiding this comment

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

Same

Copy link
Contributor Author

Choose a reason for hiding this comment

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

moved to sha3c

/* 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));
Copy link
Contributor

Choose a reason for hiding this comment

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

Same

Copy link
Contributor Author

Choose a reason for hiding this comment

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

moved to sha3c

/* 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));
Copy link
Contributor

Choose a reason for hiding this comment

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

Same

Copy link
Contributor Author

Choose a reason for hiding this comment

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

moved to sha3c

@dgarske dgarske removed their assignment Feb 8, 2023
@gojimmypi gojimmypi marked this pull request as draft February 8, 2023 22:59
@gojimmypi
Copy link
Contributor Author

Reverted hash.c and moved XMEMSET into various files for initializtions. I'll squash merge after review if desired.

Rechecked with wolftest:

make[2]: Leaving directory '/mnt/c/temp/wolfssl_PR6068_test'
make[1]: Leaving directory '/mnt/c/temp/wolfssl_PR6068_test'
------------------------------------------------------------------------------
 wolfSSL version 5.5.4
------------------------------------------------------------------------------
error    test passed!
MEMORY   test passed!
base64   test passed!
asn      test passed!
RANDOM   test passed!
MD5      test passed!
SHA      test passed!
SHA-224  test passed!
SHA-256  test passed!
SHA-384  test passed!
SHA-512  test passed!
SHA-3    test passed!
Hash     test passed!
HMAC-MD5 test passed!
HMAC-SHA test passed!
HMAC-SHA224 test passed!
HMAC-SHA256 test passed!
HMAC-SHA384 test passed!
HMAC-SHA512 test passed!
HMAC-SHA3   test passed!
HMAC-KDF    test passed!
TLSv1.3 KDF test passed!
GMAC     test passed!
Chacha   test passed!
POLY1305 test passed!
ChaCha20-Poly1305 AEAD test passed!
AES      test passed!
AES192   test passed!
AES256   test passed!
AES-GCM  test passed!
RSA      test passed!
DH       test passed!
PWDBASED test passed!
ECC      test passed!
logging  test passed!
time test passed!
mutex    test passed!
memcb    test passed!
Test complete
stack used = 2097152
total   Allocs   =      1079
total   Deallocs =      1079
total   Bytes    =   2948064
peak    Bytes    =     59930
current Bytes    =         0
Exiting main with return code: 0

@gojimmypi gojimmypi marked this pull request as ready for review February 9, 2023 03:47
@gojimmypi gojimmypi requested a review from dgarske February 9, 2023 03:47
@dgarske dgarske self-assigned this Feb 9, 2023
#if !defined(WOLFSSL_NOSHA512_224)
int wc_InitSha512_224(wc_Sha512* sha)
{
if (sha == NULL)
Copy link
Contributor

Choose a reason for hiding this comment

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

This is redundant. Already done in wc_InitSha512_224_ex -> InitSha512_Family.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

agreed. good catch. updated.

@dgarske dgarske removed their assignment Feb 9, 2023
@gojimmypi gojimmypi requested a review from dgarske February 9, 2023 17:11
Copy link
Contributor

@dgarske dgarske left a comment

Choose a reason for hiding this comment

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

Thanks Jim. FYI: I will squash this on merge.

@dgarske dgarske self-assigned this Feb 9, 2023
@wolfSSL-Bot
Copy link

Can one of the admins verify this patch?

@dgarske dgarske assigned SparkiDev and unassigned gojimmypi Feb 9, 2023
@dgarske dgarske mentioned this pull request Feb 9, 2023
4 tasks
return BAD_FUNC_ARG;
}

XMEMSET(sha224, 0, sizeof(wc_Sha224));
Copy link
Contributor

Choose a reason for hiding this comment

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

Missed wc_InitSha256_ex()

Copy link
Contributor Author

@gojimmypi gojimmypi Feb 11, 2023

Choose a reason for hiding this comment

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

@SparkiDev thanks for your review! Would you recommend that I do a XMEMSET in each of these?

image

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:

image

Copy link
Contributor

Choose a reason for hiding this comment

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

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));
Copy link
Contributor

Choose a reason for hiding this comment

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

Missed wc_InitSha383_ex().

@dgarske dgarske assigned gojimmypi and unassigned dgarske and SparkiDev Feb 9, 2023
@gojimmypi gojimmypi marked this pull request as draft February 10, 2023 23:38
@gojimmypi
Copy link
Contributor Author

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.

@gojimmypi gojimmypi closed this Feb 13, 2023
@gojimmypi
Copy link
Contributor Author

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 ctx copies during active SHA HW process.

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants