Skip to content
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

Merged
merged 9 commits into from
Jun 28, 2017

Conversation

adustm
Copy link
Member

@adustm adustm commented Apr 11, 2017

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

#if defined(MBEDTLS_SHA256_C)
MBEDTLS_SELF_TEST_TEST_CASE(mbedtls_sha256_self_test)
#endif

then

#if defined(MBEDTLS_SHA256_C)
    Case("mbedtls_sha256_self_test", mbedtls_sha256_self_test_test_case),
#endif

Testing

  • /morph test-nightly

@adustm
Copy link
Member Author

adustm commented Apr 11, 2017

@sg-

Copy link
Contributor

@RonEld RonEld left a 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);
Copy link
Contributor

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"
Copy link
Contributor

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,
Copy link
Contributor

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

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
}
Copy link
Contributor

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" {
Copy link
Contributor

Choose a reason for hiding this comment

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

can be removed

@0xc0170
Copy link
Contributor

0xc0170 commented May 16, 2017

retest uvisor

@adustm adustm force-pushed the STM_sha256_F439ZI branch from ece7870 to 959ecce Compare May 23, 2017 09:39
@adustm
Copy link
Member Author

adustm commented May 23, 2017

Hello @RonEld
I just implemented SHA256 in the same way it was done for SHA1 and MD5.
Could you handle the review please ?
Cheers
Armelle

Copy link
Contributor

@RonEld RonEld left a 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] )
Copy link
Contributor

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

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

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

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 */

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

Copy link
Member Author

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

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.

Copy link
Member Author

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;

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?

Copy link
Member Author

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

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

Copy link
Member Author

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();

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.

Copy link
Member Author

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

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.

Copy link
Member Author

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();

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.

Copy link
Member Author

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.

@andresag01
Copy link

This is equivalent to PR #4162 but for a different target. I have already reviewed that one and left my comments there.

@adustm
Copy link
Member Author

adustm commented Jun 2, 2017

Hello @gilles-peskine-arm @andresag01 ,
I have reworked this branch to allow multiple context.
Let me know if you think it's ok.
Kind regards

Copy link

@gilles-peskine-arm gilles-peskine-arm left a 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

Copy link

@andresag01 andresag01 left a comment

Choose a reason for hiding this comment

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

@adustm: Many thanks for considering our comments and reworking. This PR is is very similar to #4160, please refer to my most recent comments there.

@adustm
Copy link
Member Author

adustm commented Jun 12, 2017

Hello @andresag01 and @yanesca
Could you approve this PR or let me know if anything is missing ?
@0xc0170 could you let me know what is wrong in the Cam-CI uvisor Build & Test script ?

Kind regards
Armelle

@sg-
Copy link
Contributor

sg- commented Jun 15, 2017

Given all the approvals and that mbed TLS 2.5 is part of master can this PR be rebased on master?

@sg- sg- changed the base branch from mbed-os-workshop-17q2 to master June 15, 2017 14:59
@adustm adustm changed the base branch from master to mbed-os-workshop-17q2 June 16, 2017 07:22
@0xc0170
Copy link
Contributor

0xc0170 commented Jun 16, 2017

@adustm Is there any problem to base this on master? It was changed a hour ago

@adustm adustm changed the base branch from mbed-os-workshop-17q2 to master June 16, 2017 08:35
@adustm
Copy link
Member Author

adustm commented Jun 16, 2017

Hello @0xc0170 , forget about it, I have seen just after that it was a modification from Sam.
The rebase on master shows many conflicts. I think I 'd better cherry-pick, isn't it ?

@adustm
Copy link
Member Author

adustm commented Jun 22, 2017

bump ?

@adbridge
Copy link
Contributor

/morph test

@mbed-bot
Copy link

Result: SUCCESS

Your command has finished executing! Here's what you wrote!

/morph test

Output

mbed Build Number: 623

All builds and test passed!

@adustm
Copy link
Member Author

adustm commented Jun 23, 2017

It looks like this morph test was lucky and the other were not...

At least this one has a chance to be merged soon
:-s
kind regards
Armelle
cc @screamerbg

@screamerbg
Copy link
Contributor

@0xc0170 @adbridge What is gating this PR?

@0xc0170
Copy link
Contributor

0xc0170 commented Jun 26, 2017

@adustm Can you please rebase? we merged another PR that caused a conflict here, we will then trigger CI

@adustm
Copy link
Member Author

adustm commented Jun 27, 2017

conflict solved

@adbridge adbridge closed this Jun 27, 2017
@adbridge adbridge reopened this Jun 27, 2017
@sg- sg- removed the needs: CI label Jun 27, 2017
@adbridge
Copy link
Contributor

retest uvisor

@adbridge
Copy link
Contributor

/morph test

@theotherjimmy
Copy link
Contributor

@adustm I have restarted Travis for you. If that does not resolve the issue we fixed on master I will rebase this PR for you to get travis passing.

@Patater You aborted this one too. Do you have plans to restart it?

@mbed-bot
Copy link

Result: SUCCESS

Your command has finished executing! Here's what you wrote!

/morph test

Output

mbed Build Number: 662

All builds and test passed!

@adustm
Copy link
Member Author

adustm commented Jun 29, 2017

👍

@adustm adustm deleted the STM_sha256_F439ZI branch June 29, 2017 08:17
@adbridge
Copy link
Contributor

adbridge commented Jul 3, 2017

This contains a 'merge' commit which should not have been allowed through.

@adbridge
Copy link
Contributor

adbridge commented Jul 3, 2017

@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
Copy link
Member Author

adustm commented Jul 3, 2017

Hello @adbridge
Thank you.
For your information, this merge commit ec72ac0 is done through the github web interface when it shows a conflict and suggests to fix it directly there.
If it is a problem to use that option, somebody should remove this possibility.
Cheers
Armelle

@adbridge
Copy link
Contributor

adbridge commented Jul 3, 2017

@adustm I agree. We will look into what options we allow from the git gui on these PRs !

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.