-
Notifications
You must be signed in to change notification settings - Fork 865
[sw/crypto] Clear HMAC ctx struct #26990
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
358feb1
to
bc1ea57
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, thanks Hakim!
BTW, would you mind updating your mail in the git commit to your work mail?
sw/device/lib/crypto/drivers/hmac.c
Outdated
*/ | ||
static void wipe_buffer(uint32_t *buf, uint32_t buf_len) { | ||
for (int i = 0; i < buf_len; ++i) { | ||
buf[i] = ibex_rnd_uint32(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What happens if the random data inside Ibex never gets ready, e.g., when the EDN is turned off? I guess then we would loop forever in the ibex_rnd_uint32()
function?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Might be a good idea to use cryptolib's entropy_complex_check()
to ensure the EDN is on and in cryptolib's expected configuration 🙂 cryptolib is supposed to be stateless, so it shouldn't need an initialization step, but it does expect ROM_EXT to leave the entropy complex in a certain state for it and operations should generally always run the check function before using the entropy complex.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, I'll add the check in my next amendment.
sw/device/lib/crypto/impl/hash.c
Outdated
return OTCRYPTO_BAD_ARGS; | ||
} | ||
|
||
for (int i = 0; i < kOtcryptoHashCtxStructWords; ++i) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would use size_t
whenever possible in for loops.
sw/device/lib/crypto/drivers/hmac.c
Outdated
*/ | ||
static void wipe_buffer(uint32_t *buf, uint32_t buf_len) { | ||
for (int i = 0; i < buf_len; ++i) { | ||
buf[i] = ibex_rnd_uint32(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Might be a good idea to use cryptolib's entropy_complex_check()
to ensure the EDN is on and in cryptolib's expected configuration 🙂 cryptolib is supposed to be stateless, so it shouldn't need an initialization step, but it does expect ROM_EXT to leave the entropy complex in a certain state for it and operations should generally always run the check function before using the entropy complex.
sw/device/lib/crypto/drivers/hmac.c
Outdated
* @param buf The incoming buffer to be wiped with random data. | ||
* @param buf_len The length of `buf` in words. | ||
*/ | ||
static void wipe_buffer(uint32_t *buf, uint32_t buf_len) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we should probably use hardened_memshred
here, that's basically what it's meant for and it has some heavier-weight anti-FI/SCA mechanisms:
void hardened_memshred(uint32_t *dest, size_t word_len); |
However, it currently uses a hardcoded constant value to clear, which should probably be replaced with ibex RND reads now that the Ibex driver exists:
// The source of randomness for shred, which may be replaced at link-time. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure I can use the hardened_memshred function. However, the entropy complex check can't be done in there since it doesn't have a return value. I suggest we forget the check in this PR and I do a follow up PR where I change ibex_rnd_uint to return the cycle count whenever the entropy complex is not set up properly. What do you think?
sw/device/lib/crypto/drivers/hmac.c
Outdated
@@ -531,6 +581,5 @@ status_t hmac(const hmac_mode_t hmac_mode, const uint32_t *key, | |||
// Clean up HMAC HWIP so it can be reused by other driver calls. | |||
hmac_hwip_clear(); | |||
|
|||
// TODO(#23191): Destroy sensitive values in the ctx object. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks like this was deleted but hmac_context_wipe
wasn't called?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is no ctx
obj here. I could wipe the key and the message though. So either we leave the wiping of the input key and data to the caller or wipe them in this function.
sw/device/lib/crypto/impl/hash.c
Outdated
* | ||
* @param[out] ctx Initialized context object. | ||
*/ | ||
static otcrypto_status_t hash_context_wipe(otcrypto_hash_context_t *const ctx) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd suggest hardened_memshred
here too.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry, this comment wasn't clear -- I mean I think the function should be replaced with hardened_memshred
. The null check isn't needed, since it's an internal function and I expect the cryptolib will always have checked if that pointer is null before getting to the point of wiping the context. So this function isn't necessary; you can just call hardened_memshred
inline. This is actually an important distinction for code size; the HARDENED_TRY
macro introduces several instructions and kind of blocks the compiler from just inlining the function call.
8eb6a55
to
7961de7
Compare
8597600
to
f381b57
Compare
ff5ea08
to
0fd10b3
Compare
dd247ef
to
76977ff
Compare
@nasahlpa @jadephilipoom I rebased to #27145 and removed the overlapping parts. I addressed all the requested changes. Do you think we can merge this whenever #27145 is merged? |
cfce754
to
0b41fef
Compare
0df0040
to
c1a9857
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM with one question.
sw/device/lib/crypto/drivers/hmac.c
Outdated
// TODO(#23191): Use a random value from EDN to wipe. | ||
abs_mmio_write32(kHmacBaseAddr + HMAC_WIPE_SECRET_REG_OFFSET, UINT32_MAX); | ||
// Use a random value from EDN to wipe HMAC. | ||
HARDENED_TRY(entropy_complex_check()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It seems that, for some functions, we check multiple times whether the entropy complex is enabled or not.
Would it make sense to move these checks at the beginning of the functions, e.g., in hmac_final()
and remove it in clear()
and hmac_context_wipe()?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks Pascal, that's a good point. I'll move the check out of clear()
and hmac_context_wipe()
. Especially since they are static functions and we have a good overview from where the functions are called.
3ab44f4
to
9c45dce
Compare
54e9a4b
to
b358f8d
Compare
At certain points the HMAC ctx struct has to be wiped to avoid leaking secrets. The sensitive fields need to be overwritten by randomness and the non-sensitive fields are just zeroized. Signed-off-by: Hakim Filali <[email protected]>
b358f8d
to
2e087e8
Compare
All the comments on this PR should be addressed and if there are no further suggestions this is ready to be merged. |
This PR depends on #26961.
This PR adds functionality for wiping the HMAC ctx struct using randomness for the sensitive struct members.
Part of #26941.