-
Notifications
You must be signed in to change notification settings - Fork 3k
Nuvoton: TRNG_Get support 32 bytes unalignment #5454
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
Nuvoton: TRNG_Get support 32 bytes unalignment #5454
Conversation
cc @hanno-arm @Patater - please can you review? (I cant asign you as reviewer here, not certain why it does not work for me now) |
if( length > *output_length ) { | ||
trng_get(tmpBuff); | ||
memcpy(output, &tmpBuff, (length - *output_length)); | ||
*output_length = length; |
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.
The two code-paths handling the case of remaining length < 32
can be unified here. Also, while it's a pre-existing defect, we should safely zeroize tmpBuff
before returning.
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.
@hanno-arm , thanks of your comment, added new commit for code unify & zeroize.
@0xc0170 Sure. Could you also add the Mbed TLS label for ease of reference? |
ARM Internal Ref: IOTSSL-1875 |
output += 32; | ||
} | ||
if( length > *output_length ) { | ||
trng_zeroize(tmpBuff, sizeof(tmpBuff)); |
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.
@cyliangtw Thanks for the quick reworking. The zeroization should be done after the bytes have been fetched from the TRNG.
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.
@hanno-arm , after fetch from TRNG and copy to output, tmpBuffer is no longer used in this function. Why still need pay CPU resource to do zeroization, do you concern to disclose partial of random number in stack memory ?
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.
@cyliangtw Yes, exactly. The zeroization at the end (which is the only one that's needed here) is to prevent leakage of the random data on the stack - imagine the OS handing the same stack memory to some other process later. That's why one generally wipes sensitive data from the stack before returning.
trng_get(tmpBuff); | ||
memcpy(output, &tmpBuff, length); | ||
memcpy(output, &tmpBuff, (length - *output_length)); |
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.
One cannot reason about the correctness of this because *output_length
might have changed since the check length > *output_length
-- it's not under our control (it is likely that the compiler will not read it twice as it's not declared volatile
, but it could). My suggestion would be to use an additional temporary to keep track of the number of bytes written so far, and to set *output_length
to that temporary in the end.
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.
@hanno-arm Agree with your opinion to avoid the risk of *output_length's
change.
Commit 2ee058b
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 for the quick reworkings, the PR looks good to me!
@cyliangtw Two minor nigglings that you can but need not obey:
- You inconsistently use
tmpBuff
vs.&tmpBuff
, which when converted tovoid*
doesn't make a difference, but still it would be nicer to have it uniform. I'd prefertmpBuff
everywhere. - The function is slightly easier to read if
length
gets decreased during the main loop, and that loop goes as long aslength >= 32
. This way, it's immediately clear that the last branch will at most write32
bytes and hence cannot overflow the temporary buffer. (Again, the present version is fine wrt. functionality and security from my point of view, so it's just a suggestion).
/morph build |
Build : SUCCESSBuild number : 490 Triggering tests/morph test |
@@ -82,21 +87,21 @@ void trng_free(trng_t *obj) | |||
int trng_get_bytes(trng_t *obj, uint8_t *output, size_t length, size_t *output_length) |
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.
trng_get_bytes
looks pretty similar between TARGET_NUC472
and TARGET_M480
. Would it be prudent to move it to a location shared by both TARGET_NUC472
and TARGET_M480
?
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.
@Patater We will consider to be shared as while one more platform utilize the same HW IP.
*output_length = 0; | ||
if (length < 32) { | ||
unsigned char tmpBuff[32]; | ||
unsigned char tmpBuff[32]; |
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.
Consider making a define for 32
to use for the size of tmpBuff
.
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.
unsigned char tmpBuff[32]; | ||
size_t cur_length = 0; | ||
|
||
for (unsigned i = 0; i < (length/32); 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.
Consider using sizeof(tmpBuff)
instead of 32
.
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.
Consider also using spaces around binary operators like /
, for consistency with the style of other code in this file.
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.
Test : SUCCESSBuild number : 309 |
Exporter Build : SUCCESSBuild number : 111 |
@Patater Were your questions resolved by the latest commit? |
@Patater The last commit could resolve your concerns except shared location. This PR is relative to mbed-cloud-client-example-restricted PR for Nuvoton platforms, is there any other concern in your review ? |
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
/morph build |
Build : SUCCESSBuild number : 560 Triggering tests/morph test |
Exporter Build : SUCCESSBuild number : 173 |
Test : SUCCESSBuild number : 372 |
This is now waiting for travis only, to be resolved |
@0xc0170 To close and reopen this PR to trigger build in Travis |
@cyliangtw It's working now 🍾 |
Build : SUCCESSBuild number : 572 Triggering tests/morph test |
Exporter Build : SUCCESSBuild number : 184 |
Test : SUCCESSBuild number : 389 |
Exporter Build : SUCCESSBuild number : 185 |
Description
This PR refines code with TRNG_Get, to let TRNG_Get() support 32 bytes unalignment on NUC472/M487 platforms.
Related PRs
#5434
#5449
Test
Passed Mbed Cloud-Client-restricted(R1.2.4-LA) OTA test.
@0xc0170
@Ronny-Liu
@ccli8
@samchuarm