-
Notifications
You must be signed in to change notification settings - Fork 3k
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
NUCLEO_F439ZI/mbedtls: add SHA256 hw_acceleration #4159
Conversation
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.
reviewed and added comments
void mbedtls_sha256_update( mbedtls_sha256_context *ctx, const unsigned char *input, size_t ilen ) | ||
{ | ||
if (ctx->is224 == 0) | ||
HAL_HASHEx_SHA256_Accumulate(&ctx->hhash_sha256, (uint8_t *)input, ilen); |
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 if ilen < 64?
Do you need an accumulation buffer like in SHA1 use case?
|
||
#if defined (MBEDTLS_SHA256_ALT) | ||
#include "mbedtls/platform.h" | ||
#include "mbedtls/config.h" |
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.
is this include needed? Please check what header file includes can be moved to mbedtls_sha256_alt.c
* \param output SHA-224/256 checksum result | ||
* \param is224 0 = use SHA256, 1 = use SHA224 | ||
*/ | ||
void mbedtls_sha256( const unsigned char *input, size_t ilen, |
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.
no need to define, as it is already defined in sha256.h outside the #ifdef (MBEDTLS_SHA256_ALT)
check
* | ||
* \return 0 if successful, or 1 if the test failed | ||
*/ | ||
int mbedtls_sha256_self_test( int verbose ); |
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.
no need to define, as it is already defined in sha256.h outside the #ifdef (MBEDTLS_SHA256_ALT)
check
int mbedtls_sha256_self_test( int verbose ); | ||
|
||
#ifdef __cplusplus | ||
} |
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.
can be removed
#endif | ||
|
||
#ifdef __cplusplus | ||
extern "C" { |
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.
can be removed
retest uvisor |
Hello @RonEld |
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.
minor comment, other than that, I will approve
} | ||
} | ||
|
||
void mbedtls_sha256_process( mbedtls_sha256_context *ctx, const unsigned char data[64] ) |
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.
change 64 to MBEDTLS_SHA256_BLOCK_SIZE
void mbedtls_sha256_process( mbedtls_sha256_context *ctx, const unsigned char data[64] ) | ||
{ | ||
if (ctx->is224 == 0) { | ||
HAL_HASHEx_SHA256_Accumulate(&ctx->hhash_sha256, (uint8_t *) data, 64); |
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.
change 64 to MBEDTLS_SHA256_BLOCK_SIZE
if (ctx->is224 == 0) { | ||
HAL_HASHEx_SHA256_Accumulate(&ctx->hhash_sha256, (uint8_t *) data, 64); | ||
} else { | ||
HAL_HASHEx_SHA224_Accumulate(&ctx->hhash_sha256, (uint8_t *) data, 64); |
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.
change 64 to MBEDTLS_SHA256_BLOCK_SIZE
void mbedtls_sha256_finish( mbedtls_sha256_context *ctx, unsigned char output[32] ); | ||
|
||
/* Internal use */ | ||
void mbedtls_sha256_process( mbedtls_sha256_context *ctx, const unsigned char data[64] ); |
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.
change 64 to MBEDTLS_SHA256_BLOCK_SIZE
*/ | ||
typedef struct | ||
{ | ||
int is224; /*!< 0 => SHA-256, else SHA-224 */ |
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 suggest making this a bool
(so that it's clear that only two values are allowed) and moving it to the end of the structure (to avoid wasting a little memory for alignment).
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.
Hello,
This is coming from the official sha256.h.
I suggest that you create a change request to mbedtls official release, where it comes from :
https://github.com/ARMmbed/mbed-os/blob/master/features/mbedtls/inc/mbedtls/sha256.h#L51
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.
@adustm I know. We're stuck with this in the portable code because we don't want to change types that are visible in the public API (it would break binary compatibility). Here the backward compatibility constraint does not apply. But it's extremely minor anyway, it would save 4 bytes per context at most.
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.
This is a copy from the input parameter from the void mbedtls_sha256_starts( mbedtls_sha256_context *ctx, int is224 )
function.
I prefer to remain aligned with the public api if you don't mind (as you said, minor 4 bytes saving).
void mbedtls_sha256_clone( mbedtls_sha256_context *dst, | ||
const mbedtls_sha256_context *src ) | ||
{ | ||
*dst = *src; |
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'm not sure this is correct, but again it might be because I am not familiar with the hardware. After calling the clone function, a user of the crypto library can alternate calls to the two contexts. If the context data is copied, in particular if the clones have the same contents in all the HASH_HandleTypeDef
fields, won't they be sharing some resources?
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.
see previous comment
void mbedtls_sha256_update( mbedtls_sha256_context *ctx, const unsigned char *input, size_t ilen ) | ||
{ | ||
size_t currentlen = ilen; | ||
// store mechanism to handle MBEDTLS_SHA256_BLOCK_SIZE bytes per MBEDTLS_SHA256_BLOCK_SIZE bytes |
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 guess you mean “to handle MBEDTLS_SHA256_BLOCK_SIZE bytes at a time”? But looking at the code below it's a bit more complicated than that: buffer up to MBEDTLS_SHA256_BLOCK_SIZE bytes; only call the hardware if there are at least MBEDTLS_SHA256_BLOCK_SIZE bytes to process; if there are at least MBEDTLS_SHA256_BLOCK_SIZE bytes then process the largest possible multiple of 4 (not of 64).
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.
correct, I will change the comment
if( ctx == NULL ) | ||
return; | ||
/* Force the HASH Periheral Clock Reset */ | ||
__HAL_RCC_HASH_FORCE_RESET(); |
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.
Is this the right place to reset the hardware? What about a scenario with two hash calculations, fore example: init(ctx1); init(ctx2); starts(ctx1); starts(ctx2); update(ctx1); update(ctx2); finish(ctx1); update(ctx2); free(ctx1); update(ctx2);
. The free
operation is there to free resources that are associated with a specific calculation, but the hardware is shared between all the hash calculations that are going on.
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.
You are probably right about this. I will create this test to handle the multithread.
// now process every input as long as it is %4 bytes | ||
size_t iter = currentlen / 4; | ||
if (ctx->is224 == 0) { | ||
HAL_HASHEx_SHA256_Accumulate(&ctx->hhash_sha256, (uint8_t *)(input + MBEDTLS_SHA256_BLOCK_SIZE - ctx->sbuf_len), (iter * 4)); |
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 documentation of HAL_HASHEx_SHA256_Accumulate
states: “If the Size is not multiple of 64 bytes, the padding is managed by hardware.” So is it valid to call it with blocks that are not a multiple of 64 bytes (other than the last block)? E.g. with a call mbedtls_sha256_update(ctx, input1, 68); mbedtls_sha256_update(ctx, input2, 60); mbedtls_sha256_finalize(ctx)
, this code processes all 68 bytes of input1
then some padding?? then buffers the 60 bytes of input2
which are processed by finalize(). Is this correct?
Same remark for SHA224.
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.
Please see my answer here : #4162 (comment)
mbedtls_zeroize( ctx, sizeof( mbedtls_sha256_context ) ); | ||
|
||
/* Enable HASH clock */ | ||
__HAL_RCC_HASH_CLK_ENABLE(); |
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.
Is this the right place to power on the hardware? See my comment about reset in mbedtls_sha256_free
.
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.
Powering the hw will have no effect if already done.
This is equivalent to PR #4162 but for a different target. I have already reviewed that one and left my comments there. |
Hello @gilles-peskine-arm @andresag01 , |
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 good overall, see my comments in PR #4162
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.
Hello @andresag01 and @yanesca Kind regards |
Given all the approvals and that mbed TLS 2.5 is part of master can this PR be rebased on master? |
@adustm Is there any problem to base this on master? It was changed a hour ago |
Hello @0xc0170 , forget about it, I have seen just after that it was a modification from Sam. |
bump ? |
/morph test |
Result: SUCCESSYour command has finished executing! Here's what you wrote!
OutputAll builds and test passed! |
It looks like this morph test was lucky and the other were not... At least this one has a chance to be merged soon |
@adustm Can you please rebase? we merged another PR that caused a conflict here, we will then trigger CI |
conflict solved |
retest uvisor |
/morph test |
Result: SUCCESSYour command has finished executing! Here's what you wrote!
OutputAll builds and test passed! |
👍 |
This contains a 'merge' commit which should not have been allowed through. |
@adustm Please always use rebase rather than merge in the future :) . I will manually cherry pick changes to pull this through to 5.5.2 |
@adustm I agree. We will look into what options we allow from the git gui on these PRs ! |
Description
Enable HW acceleration for SHA256 algorithm on STM32F439ZI
is = #3948
Status
READY
Steps to test or reproduce
To test this feature, you have to modify TESTS/mbedtls/selfttest/main.cpp in order to call sha256 self test:
add:
#include "mbedtls/sha256.h"
then
then
Testing