From ddd186cc61cebdd64e8bbf625d385052a5a02a25 Mon Sep 17 00:00:00 2001 From: adustm Date: Thu, 9 Mar 2017 15:34:09 +0100 Subject: [PATCH 01/13] NUCLEO_F429ZI/mbedtls: add SHA1 hw_acceleration --- .../TARGET_NUCLEO_F439ZI/mbedtls_device.h | 3 +- .../mbedtls/targets/TARGET_STM/sha1_alt.c | 149 ++++++++++++++++++ .../mbedtls/targets/TARGET_STM/sha1_alt.h | 127 +++++++++++++++ 3 files changed, 278 insertions(+), 1 deletion(-) create mode 100644 features/mbedtls/targets/TARGET_STM/sha1_alt.c create mode 100644 features/mbedtls/targets/TARGET_STM/sha1_alt.h diff --git a/features/mbedtls/targets/TARGET_STM/TARGET_STM32F4/TARGET_NUCLEO_F439ZI/mbedtls_device.h b/features/mbedtls/targets/TARGET_STM/TARGET_STM32F4/TARGET_NUCLEO_F439ZI/mbedtls_device.h index 9a06a1cba5..87972a7be5 100644 --- a/features/mbedtls/targets/TARGET_STM/TARGET_STM32F4/TARGET_NUCLEO_F439ZI/mbedtls_device.h +++ b/features/mbedtls/targets/TARGET_STM/TARGET_STM32F4/TARGET_NUCLEO_F439ZI/mbedtls_device.h @@ -21,6 +21,7 @@ #define MBEDTLS_DEVICE_H #define MBEDTLS_AES_ALT +#define MBEDTLS_SHA1_ALT - +#define MBEDTLS_SHA1_C #endif /* MBEDTLS_DEVICE_H */ diff --git a/features/mbedtls/targets/TARGET_STM/sha1_alt.c b/features/mbedtls/targets/TARGET_STM/sha1_alt.c new file mode 100644 index 0000000000..26fad7c60f --- /dev/null +++ b/features/mbedtls/targets/TARGET_STM/sha1_alt.c @@ -0,0 +1,149 @@ +/* + * sha1_alt.c for SHA1 HASH + ******************************************************************************* + * Copyright (c) 2017, STMicroelectronics + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +#include "mbedtls/sha1.h" + +#if defined(MBEDTLS_SHA1_ALT) + +/* Implementation that should never be optimized out by the compiler */ +static void mbedtls_zeroize( void *v, size_t n ) { + volatile unsigned char *p = (unsigned char*)v; while( n-- ) *p++ = 0; +} + +void mbedtls_sha1_init( mbedtls_sha1_context *ctx ) +{ + memset( ctx, 0, sizeof( mbedtls_sha1_context ) ); + + /* Enable HASH clock */ + __HAL_RCC_HASH_CLK_ENABLE(); + + ctx->flag=0; +} + +void mbedtls_sha1_free( mbedtls_sha1_context *ctx ) +{ + if( ctx == NULL ) + return; + + /* Force the HASH Periheral Clock Reset */ + __HAL_RCC_HASH_FORCE_RESET(); + + /* Release the HASH Periheral Clock Reset */ + __HAL_RCC_HASH_RELEASE_RESET(); + + mbedtls_zeroize( ctx, sizeof( mbedtls_sha1_context ) ); +} + +void mbedtls_sha1_clone( mbedtls_sha1_context *dst, + const mbedtls_sha1_context *src ) +{ + *dst = *src; +} + +/* + * SHA-1 context setup + */ +void mbedtls_sha1_starts( mbedtls_sha1_context *ctx ) +{ + /* Deinitializes the HASH peripheral */ + if (HAL_HASH_DeInit(&ctx->hhash_sha1) == HAL_ERROR) { + // error found to be returned + return; + } + + /* HASH Configuration */ + ctx->hhash_sha1.Init.DataType = HASH_DATATYPE_8B; + if (HAL_HASH_Init(&ctx->hhash_sha1) == HAL_ERROR) { + // error found to be returned + return; + } + + ctx->flag=0; +} + +void mbedtls_sha1_process( mbedtls_sha1_context *ctx, const unsigned char data[64] ) +{ + HAL_HASH_SHA1_Accumulate(&ctx->hhash_sha1, (uint8_t *) data, 64); +} + +/* + * SHA-1 process buffer + */ +void mbedtls_sha1_update( mbedtls_sha1_context *ctx, const unsigned char *input, size_t ilen ) +{ + unsigned char *intermediate_buf=NULL; + unsigned char modulus=0; + unsigned char buf_len=0; + + // Accumulate cannot be called for a size <4 unless it is the last call + + modulus = ilen % 4; + + if (ilen <4) + { + ctx->sbuf=malloc(ilen); + memcpy(ctx->sbuf, input, ilen); + ctx->flag = 1; + ctx->sbuf_len=ilen; + } + else + { + if (modulus !=0) + { + buf_len = ilen - modulus; + HAL_HASH_SHA1_Accumulate(&ctx->hhash_sha1, (uint8_t *)input, buf_len); + ctx->sbuf_len=modulus; + ctx->sbuf=malloc(ctx->sbuf_len); + memcpy(ctx->sbuf, input+buf_len, modulus); + ctx->flag = 1; + } + else + { + if (ctx->flag==0) + HAL_HASH_SHA1_Accumulate(&ctx->hhash_sha1, (uint8_t *)input, ilen); + else + { + intermediate_buf=malloc(ilen+ctx->sbuf_len); + memcpy(intermediate_buf, ctx->sbuf, ctx->sbuf_len); + memcpy(intermediate_buf+ctx->sbuf_len, input, ilen); + HAL_HASH_SHA1_Accumulate(&ctx->hhash_sha1, intermediate_buf, ilen+ctx->sbuf_len); + ctx->flag=0; + } + } + } +} + +/* + * SHA-1 final digest + */ +void mbedtls_sha1_finish( mbedtls_sha1_context *ctx, unsigned char output[20] ) +{ + if (ctx->flag == 1) { + HAL_HASH_SHA1_Accumulate(&ctx->hhash_sha1, ctx->sbuf, ctx->sbuf_len); + ctx->flag=0; + } + + __HAL_HASH_START_DIGEST(); + + if (HAL_HASH_SHA1_Finish(&ctx->hhash_sha1, output, 10)){ + // error code to be returned + } +} + +#endif /*MBEDTLS_SHA1_ALT*/ diff --git a/features/mbedtls/targets/TARGET_STM/sha1_alt.h b/features/mbedtls/targets/TARGET_STM/sha1_alt.h new file mode 100644 index 0000000000..fe3295e242 --- /dev/null +++ b/features/mbedtls/targets/TARGET_STM/sha1_alt.h @@ -0,0 +1,127 @@ +/* + * sha1_alt.h SHA-1 hash + ******************************************************************************* + * Copyright (C) 2017, STMicroelectronics + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +#ifndef MBEDTLS_SHA1_ALT_H +#define MBEDTLS_SHA1_ALT_H + +#if defined MBEDTLS_SHA1_ALT + +#include "mbedtls/platform.h" +#include "mbedtls/config.h" + +#include "cmsis.h" +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \brief SHA-1 context structure + */ +typedef struct +{ + unsigned char *sbuf; + unsigned char sbuf_len; + HASH_HandleTypeDef hhash_sha1; + int flag; /* flag to manage buffer constraint of crypto Hw */ +} +mbedtls_sha1_context; + +/** + * \brief Initialize SHA-1 context + * + * \param ctx SHA-1 context to be initialized + */ +void mbedtls_sha1_init( mbedtls_sha1_context *ctx ); + +/** + * \brief Clear SHA-1 context + * + * \param ctx SHA-1 context to be cleared + */ +void mbedtls_sha1_free( mbedtls_sha1_context *ctx ); + +/** + * \brief Clone (the state of) a SHA-1 context + * + * \param dst The destination context + * \param src The context to be cloned + */ +void mbedtls_sha1_clone( mbedtls_sha1_context *dst, + const mbedtls_sha1_context *src ); + +/** + * \brief SHA-1 context setup + * + * \param ctx context to be initialized + */ +void mbedtls_sha1_starts( mbedtls_sha1_context *ctx ); + +/** + * \brief SHA-1 process buffer + * + * \param ctx SHA-1 context + * \param input buffer holding the data + * \param ilen length of the input data + */ +void mbedtls_sha1_update( mbedtls_sha1_context *ctx, const unsigned char *input, size_t ilen ); + +/** + * \brief SHA-1 final digest + * + * \param ctx SHA-1 context + * \param output SHA-1 checksum result + */ +void mbedtls_sha1_finish( mbedtls_sha1_context *ctx, unsigned char output[20] ); + +/* Internal use */ +void mbedtls_sha1_process( mbedtls_sha1_context *ctx, const unsigned char data[64] ); + +#ifdef __cplusplus +} +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \brief Output = SHA-1( input buffer ) + * + * \param input buffer holding the data + * \param ilen length of the input data + * \param output SHA-1 checksum result + */ +void mbedtls_sha1( const unsigned char *input, size_t ilen, unsigned char output[20] ); + +/** + * \brief Checkup routine + * + * \return 0 if successful, or 1 if the test failed + */ +int mbedtls_sha1_self_test( int verbose ); + +#ifdef __cplusplus +} +#endif + +#endif /* MBEDTLS_SHA1_ALT */ + +#endif /* sha1_alt.h */ From 1695e9a7bb70fffc85b2c03db97cfec7e516a2aa Mon Sep 17 00:00:00 2001 From: adustm Date: Mon, 20 Mar 2017 11:18:38 +0100 Subject: [PATCH 02/13] use mbedtls_zeroize instead of memset(xxx,0,xxx) --- features/mbedtls/targets/TARGET_STM/sha1_alt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/features/mbedtls/targets/TARGET_STM/sha1_alt.c b/features/mbedtls/targets/TARGET_STM/sha1_alt.c index 26fad7c60f..a5b61c135f 100644 --- a/features/mbedtls/targets/TARGET_STM/sha1_alt.c +++ b/features/mbedtls/targets/TARGET_STM/sha1_alt.c @@ -28,7 +28,7 @@ static void mbedtls_zeroize( void *v, size_t n ) { void mbedtls_sha1_init( mbedtls_sha1_context *ctx ) { - memset( ctx, 0, sizeof( mbedtls_sha1_context ) ); + mbedtls_zeroize( ctx, sizeof( mbedtls_sha1_context ) ); /* Enable HASH clock */ __HAL_RCC_HASH_CLK_ENABLE(); From 996e093b776c35701d8993bb861beb8cf3711145 Mon Sep 17 00:00:00 2001 From: adustm Date: Mon, 20 Mar 2017 11:19:56 +0100 Subject: [PATCH 03/13] Better explanation of the use of mbedtls_sha1_context fields --- features/mbedtls/targets/TARGET_STM/sha1_alt.h | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/features/mbedtls/targets/TARGET_STM/sha1_alt.h b/features/mbedtls/targets/TARGET_STM/sha1_alt.h index fe3295e242..4f04002ebe 100644 --- a/features/mbedtls/targets/TARGET_STM/sha1_alt.h +++ b/features/mbedtls/targets/TARGET_STM/sha1_alt.h @@ -33,14 +33,19 @@ extern "C" { #endif /** - * \brief SHA-1 context structure + * \brief SHA-1 context structure + * \note HAL_HASH_SHA1_Accumulate cannot handle less than 4 bytes, unless it is the last call to the function + * In case of buffer size < 4, flag is set to 1, remaining bytes are copied in a temp buffer. + * The pointer and the length are saved in sbuf and sbuf_len. + * At the next accumulation, the saved values are taken into account, and flag is set to 0 + * If SHA1_finish is called and flag=1, the remaining bytes are accumulated before the call to HAL_HASH_SHA1_Finish */ typedef struct { - unsigned char *sbuf; - unsigned char sbuf_len; - HASH_HandleTypeDef hhash_sha1; - int flag; /* flag to manage buffer constraint of crypto Hw */ + unsigned char *sbuf; /*!< pointer to the remaining buffer to be processed */ + unsigned char sbuf_len; /*!< number of bytes remaining in sbuf to be processed */ + HASH_HandleTypeDef hhash_sha1; /*!< ST HAL HASH struct */ + int flag; /*!< 1 : there are sbuf_len bytes to be processed in sbuf, 0 : every data have been processed. */ } mbedtls_sha1_context; From f26ae03e48e8a6ae6d7ed61fbf1ecb025553a9e2 Mon Sep 17 00:00:00 2001 From: adustm Date: Tue, 4 Apr 2017 14:33:53 +0200 Subject: [PATCH 04/13] Remove unneeded function declarations + include file Move include platform from sha1_alt.h to sha1_alt.c --- features/mbedtls/targets/TARGET_STM/sha1_alt.c | 10 +++++----- features/mbedtls/targets/TARGET_STM/sha1_alt.h | 18 ------------------ 2 files changed, 5 insertions(+), 23 deletions(-) diff --git a/features/mbedtls/targets/TARGET_STM/sha1_alt.c b/features/mbedtls/targets/TARGET_STM/sha1_alt.c index a5b61c135f..8cc38a8054 100644 --- a/features/mbedtls/targets/TARGET_STM/sha1_alt.c +++ b/features/mbedtls/targets/TARGET_STM/sha1_alt.c @@ -18,8 +18,8 @@ * */ #include "mbedtls/sha1.h" - #if defined(MBEDTLS_SHA1_ALT) +#include "mbedtls/platform.h" /* Implementation that should never be optimized out by the compiler */ static void mbedtls_zeroize( void *v, size_t n ) { @@ -40,7 +40,7 @@ void mbedtls_sha1_free( mbedtls_sha1_context *ctx ) { if( ctx == NULL ) return; - + /* Force the HASH Periheral Clock Reset */ __HAL_RCC_HASH_FORCE_RESET(); @@ -66,7 +66,7 @@ void mbedtls_sha1_starts( mbedtls_sha1_context *ctx ) // error found to be returned return; } - + /* HASH Configuration */ ctx->hhash_sha1.Init.DataType = HASH_DATATYPE_8B; if (HAL_HASH_Init(&ctx->hhash_sha1) == HAL_ERROR) { @@ -126,7 +126,7 @@ void mbedtls_sha1_update( mbedtls_sha1_context *ctx, const unsigned char *input, ctx->flag=0; } } - } + } } /* @@ -140,7 +140,7 @@ void mbedtls_sha1_finish( mbedtls_sha1_context *ctx, unsigned char output[20] ) } __HAL_HASH_START_DIGEST(); - + if (HAL_HASH_SHA1_Finish(&ctx->hhash_sha1, output, 10)){ // error code to be returned } diff --git a/features/mbedtls/targets/TARGET_STM/sha1_alt.h b/features/mbedtls/targets/TARGET_STM/sha1_alt.h index 4f04002ebe..37fa83b770 100644 --- a/features/mbedtls/targets/TARGET_STM/sha1_alt.h +++ b/features/mbedtls/targets/TARGET_STM/sha1_alt.h @@ -22,8 +22,6 @@ #if defined MBEDTLS_SHA1_ALT -#include "mbedtls/platform.h" -#include "mbedtls/config.h" #include "cmsis.h" #include @@ -107,22 +105,6 @@ void mbedtls_sha1_process( mbedtls_sha1_context *ctx, const unsigned char data[6 extern "C" { #endif -/** - * \brief Output = SHA-1( input buffer ) - * - * \param input buffer holding the data - * \param ilen length of the input data - * \param output SHA-1 checksum result - */ -void mbedtls_sha1( const unsigned char *input, size_t ilen, unsigned char output[20] ); - -/** - * \brief Checkup routine - * - * \return 0 if successful, or 1 if the test failed - */ -int mbedtls_sha1_self_test( int verbose ); - #ifdef __cplusplus } #endif From 85d549c9028ad47f9a63c580bd7d779b2f308f82 Mon Sep 17 00:00:00 2001 From: adustm Date: Fri, 7 Apr 2017 13:30:49 +0200 Subject: [PATCH 05/13] Improve memory management --- .../mbedtls/targets/TARGET_STM/sha1_alt.c | 66 ++++++++++++------- 1 file changed, 41 insertions(+), 25 deletions(-) diff --git a/features/mbedtls/targets/TARGET_STM/sha1_alt.c b/features/mbedtls/targets/TARGET_STM/sha1_alt.c index 8cc38a8054..8c2604cf17 100644 --- a/features/mbedtls/targets/TARGET_STM/sha1_alt.c +++ b/features/mbedtls/targets/TARGET_STM/sha1_alt.c @@ -26,6 +26,33 @@ static void mbedtls_zeroize( void *v, size_t n ) { volatile unsigned char *p = (unsigned char*)v; while( n-- ) *p++ = 0; } +/* mbedtls_sha1_store will store in ctx->sbuf size new values located at *ptr */ +/* wether ctx->sbuf already contains something or not */ +static void mbedtls_sha1_store( mbedtls_sha1_context *ctx, uint8_t *ptr, unsigned char size) +{ + if (ctx->sbuf == NULL) { // new allocation + ctx->sbuf = malloc(size); + } else { // realloc + ctx->sbuf = realloc(ptr, size); + } + if (ctx->sbuf !=NULL) { // allocation occured + memcpy(ctx->sbuf, ptr, size); + ctx->flag = 1; + ctx->sbuf_len += size; + } +} + +/* mbedtls_sha1_clear_ctxbuf will clear the ctx buff, free memory */ +static void mbedtls_sha1_clear_ctxbuf( mbedtls_sha1_context *ctx) +{ + ctx->flag=0; + mbedtls_zeroize( ctx->sbuf, ctx->sbuf_len); + free(ctx->sbuf); + ctx->sbuf = NULL; + ctx->sbuf_len = 0; + +} + void mbedtls_sha1_init( mbedtls_sha1_context *ctx ) { mbedtls_zeroize( ctx, sizeof( mbedtls_sha1_context ) ); @@ -90,40 +117,28 @@ void mbedtls_sha1_update( mbedtls_sha1_context *ctx, const unsigned char *input, unsigned char *intermediate_buf=NULL; unsigned char modulus=0; unsigned char buf_len=0; - // Accumulate cannot be called for a size <4 unless it is the last call - modulus = ilen % 4; - if (ilen <4) - { - ctx->sbuf=malloc(ilen); - memcpy(ctx->sbuf, input, ilen); - ctx->flag = 1; - ctx->sbuf_len=ilen; - } - else - { - if (modulus !=0) - { + if (ilen <4) { + mbedtls_sha1_store(ctx, (uint8_t *)input, ilen); + } else { + if (modulus !=0) { buf_len = ilen - modulus; HAL_HASH_SHA1_Accumulate(&ctx->hhash_sha1, (uint8_t *)input, buf_len); - ctx->sbuf_len=modulus; - ctx->sbuf=malloc(ctx->sbuf_len); - memcpy(ctx->sbuf, input+buf_len, modulus); - ctx->flag = 1; - } - else - { + mbedtls_sha1_store(ctx, (uint8_t *)(input+buf_len), modulus); + } else { if (ctx->flag==0) HAL_HASH_SHA1_Accumulate(&ctx->hhash_sha1, (uint8_t *)input, ilen); - else - { - intermediate_buf=malloc(ilen+ctx->sbuf_len); + else { + intermediate_buf=malloc(ilen + ctx->sbuf_len); memcpy(intermediate_buf, ctx->sbuf, ctx->sbuf_len); memcpy(intermediate_buf+ctx->sbuf_len, input, ilen); HAL_HASH_SHA1_Accumulate(&ctx->hhash_sha1, intermediate_buf, ilen+ctx->sbuf_len); - ctx->flag=0; + mbedtls_zeroize( intermediate_buf, (ilen + ctx->sbuf_len ) ); + free(intermediate_buf); + intermediate_buf = NULL; + mbedtls_sha1_clear_ctxbuf(ctx); } } } @@ -134,9 +149,10 @@ void mbedtls_sha1_update( mbedtls_sha1_context *ctx, const unsigned char *input, */ void mbedtls_sha1_finish( mbedtls_sha1_context *ctx, unsigned char output[20] ) { + if (ctx->flag == 1) { HAL_HASH_SHA1_Accumulate(&ctx->hhash_sha1, ctx->sbuf, ctx->sbuf_len); - ctx->flag=0; + mbedtls_sha1_clear_ctxbuf(ctx); } __HAL_HASH_START_DIGEST(); From dac900468448f0e5636ae593ba63542ca604355a Mon Sep 17 00:00:00 2001 From: adustm Date: Mon, 15 May 2017 15:28:10 +0200 Subject: [PATCH 06/13] Move MBEDTLS_SHA1_C from mbedtls_device.h to targets.json --- .../TARGET_STM32F4/TARGET_NUCLEO_F439ZI/mbedtls_device.h | 1 - targets/targets.json | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/features/mbedtls/targets/TARGET_STM/TARGET_STM32F4/TARGET_NUCLEO_F439ZI/mbedtls_device.h b/features/mbedtls/targets/TARGET_STM/TARGET_STM32F4/TARGET_NUCLEO_F439ZI/mbedtls_device.h index 87972a7be5..99fc584633 100644 --- a/features/mbedtls/targets/TARGET_STM/TARGET_STM32F4/TARGET_NUCLEO_F439ZI/mbedtls_device.h +++ b/features/mbedtls/targets/TARGET_STM/TARGET_STM32F4/TARGET_NUCLEO_F439ZI/mbedtls_device.h @@ -23,5 +23,4 @@ #define MBEDTLS_AES_ALT #define MBEDTLS_SHA1_ALT -#define MBEDTLS_SHA1_C #endif /* MBEDTLS_DEVICE_H */ diff --git a/targets/targets.json b/targets/targets.json index 165ac9f6cf..5a5e95063c 100644 --- a/targets/targets.json +++ b/targets/targets.json @@ -955,7 +955,7 @@ "extra_labels": ["STM", "STM32F4", "STM32F439", "STM32F439ZI", "STM32F439xx", "STM32F439xI", "FLASH_CMSIS_ALGO"], "supported_toolchains": ["ARM", "uARM", "GCC_ARM", "IAR"], "progen": {"target": "nucleo-f439zi"}, - "macros": ["TRANSACTION_QUEUE_SIZE_SPI=2", "MBEDTLS_CONFIG_HW_SUPPORT", "USB_STM_HAL", "USBHOST_OTHER"], + "macros": ["TRANSACTION_QUEUE_SIZE_SPI=2", "MBEDTLS_CONFIG_HW_SUPPORT", "USB_STM_HAL", "USBHOST_OTHER", "MBEDTLS_SHA1_C"], "device_has": ["ANALOGIN", "ANALOGOUT", "CAN", "ERROR_RED", "I2C", "I2CSLAVE", "I2C_ASYNCH", "INTERRUPTIN", "LOWPOWERTIMER", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SERIAL_FC", "SLEEP", "SPI", "SPISLAVE", "SPI_ASYNCH", "STDIO_MESSAGES", "TRNG", "FLASH"], "detect_code": ["0797"], "features": ["LWIP"], From ca65e01ffa300738a6f00ee09f6ba81b9bfeba32 Mon Sep 17 00:00:00 2001 From: adustm Date: Tue, 16 May 2017 14:30:43 +0200 Subject: [PATCH 07/13] Handle 64 bytes buffers --- .../mbedtls/targets/TARGET_STM/sha1_alt.c | 95 ++++++------------- .../mbedtls/targets/TARGET_STM/sha1_alt.h | 10 +- 2 files changed, 31 insertions(+), 74 deletions(-) diff --git a/features/mbedtls/targets/TARGET_STM/sha1_alt.c b/features/mbedtls/targets/TARGET_STM/sha1_alt.c index 8c2604cf17..f35667848a 100644 --- a/features/mbedtls/targets/TARGET_STM/sha1_alt.c +++ b/features/mbedtls/targets/TARGET_STM/sha1_alt.c @@ -26,33 +26,6 @@ static void mbedtls_zeroize( void *v, size_t n ) { volatile unsigned char *p = (unsigned char*)v; while( n-- ) *p++ = 0; } -/* mbedtls_sha1_store will store in ctx->sbuf size new values located at *ptr */ -/* wether ctx->sbuf already contains something or not */ -static void mbedtls_sha1_store( mbedtls_sha1_context *ctx, uint8_t *ptr, unsigned char size) -{ - if (ctx->sbuf == NULL) { // new allocation - ctx->sbuf = malloc(size); - } else { // realloc - ctx->sbuf = realloc(ptr, size); - } - if (ctx->sbuf !=NULL) { // allocation occured - memcpy(ctx->sbuf, ptr, size); - ctx->flag = 1; - ctx->sbuf_len += size; - } -} - -/* mbedtls_sha1_clear_ctxbuf will clear the ctx buff, free memory */ -static void mbedtls_sha1_clear_ctxbuf( mbedtls_sha1_context *ctx) -{ - ctx->flag=0; - mbedtls_zeroize( ctx->sbuf, ctx->sbuf_len); - free(ctx->sbuf); - ctx->sbuf = NULL; - ctx->sbuf_len = 0; - -} - void mbedtls_sha1_init( mbedtls_sha1_context *ctx ) { mbedtls_zeroize( ctx, sizeof( mbedtls_sha1_context ) ); @@ -60,7 +33,6 @@ void mbedtls_sha1_init( mbedtls_sha1_context *ctx ) /* Enable HASH clock */ __HAL_RCC_HASH_CLK_ENABLE(); - ctx->flag=0; } void mbedtls_sha1_free( mbedtls_sha1_context *ctx ) @@ -83,9 +55,6 @@ void mbedtls_sha1_clone( mbedtls_sha1_context *dst, *dst = *src; } -/* - * SHA-1 context setup - */ void mbedtls_sha1_starts( mbedtls_sha1_context *ctx ) { /* Deinitializes the HASH peripheral */ @@ -100,61 +69,51 @@ void mbedtls_sha1_starts( mbedtls_sha1_context *ctx ) // error found to be returned return; } - - ctx->flag=0; } -void mbedtls_sha1_process( mbedtls_sha1_context *ctx, const unsigned char data[64] ) +void mbedtls_sha1_process( mbedtls_sha1_context *ctx, const unsigned char data[MBEDTLS_SHA1_BLOCK_SIZE] ) { - HAL_HASH_SHA1_Accumulate(&ctx->hhash_sha1, (uint8_t *) data, 64); + HAL_HASH_SHA1_Accumulate(&ctx->hhash_sha1, (uint8_t *) data, MBEDTLS_SHA1_BLOCK_SIZE); } -/* - * SHA-1 process buffer - */ void mbedtls_sha1_update( mbedtls_sha1_context *ctx, const unsigned char *input, size_t ilen ) { - unsigned char *intermediate_buf=NULL; - unsigned char modulus=0; - unsigned char buf_len=0; - // Accumulate cannot be called for a size <4 unless it is the last call - modulus = ilen % 4; - - if (ilen <4) { - mbedtls_sha1_store(ctx, (uint8_t *)input, ilen); - } else { - if (modulus !=0) { - buf_len = ilen - modulus; - HAL_HASH_SHA1_Accumulate(&ctx->hhash_sha1, (uint8_t *)input, buf_len); - mbedtls_sha1_store(ctx, (uint8_t *)(input+buf_len), modulus); + unsigned char i=0; + int currentlen = ilen; + /* store mechanism to handle 64 bytes per 64 bytes */ + if (currentlen == 0){ // change HW status is size if 0 + HAL_HASH_SHA1_Accumulate(&ctx->hhash_sha1, (uint8_t *) input, ilen); + } + while ((currentlen+ctx->sbuf_len) >=MBEDTLS_SHA1_BLOCK_SIZE) { + if (ctx->sbuf_len ==0) { /* straight forward */ + mbedtls_sha1_process(ctx, input+(i*MBEDTLS_SHA1_BLOCK_SIZE)); } else { - if (ctx->flag==0) - HAL_HASH_SHA1_Accumulate(&ctx->hhash_sha1, (uint8_t *)input, ilen); - else { - intermediate_buf=malloc(ilen + ctx->sbuf_len); - memcpy(intermediate_buf, ctx->sbuf, ctx->sbuf_len); - memcpy(intermediate_buf+ctx->sbuf_len, input, ilen); - HAL_HASH_SHA1_Accumulate(&ctx->hhash_sha1, intermediate_buf, ilen+ctx->sbuf_len); - mbedtls_zeroize( intermediate_buf, (ilen + ctx->sbuf_len ) ); - free(intermediate_buf); - intermediate_buf = NULL; - mbedtls_sha1_clear_ctxbuf(ctx); + unsigned char tmp = ctx->sbuf_len; + memcpy(ctx->sbuf+tmp, input+(i*MBEDTLS_SHA1_BLOCK_SIZE),MBEDTLS_SHA1_BLOCK_SIZE-tmp); + mbedtls_sha1_process(ctx, ctx->sbuf); + if ((currentlen-(MBEDTLS_SHA1_BLOCK_SIZE-tmp)) < tmp) { + ctx->sbuf_len = currentlen-(MBEDTLS_SHA1_BLOCK_SIZE-tmp); } + memcpy(ctx->sbuf,input+(i+1)*MBEDTLS_SHA1_BLOCK_SIZE-tmp, ctx->sbuf_len); } + currentlen -= MBEDTLS_SHA1_BLOCK_SIZE; + i++; + } + if (currentlen >0) { + /* Store the remaining <64 values */ + memcpy(ctx->sbuf+ctx->sbuf_len, input+(i*MBEDTLS_SHA1_BLOCK_SIZE), currentlen); + ctx->sbuf_len += currentlen; } } -/* - * SHA-1 final digest - */ void mbedtls_sha1_finish( mbedtls_sha1_context *ctx, unsigned char output[20] ) { - if (ctx->flag == 1) { + if (ctx->sbuf_len > 0) { HAL_HASH_SHA1_Accumulate(&ctx->hhash_sha1, ctx->sbuf, ctx->sbuf_len); - mbedtls_sha1_clear_ctxbuf(ctx); } - + mbedtls_zeroize(ctx->sbuf, MBEDTLS_SHA1_BLOCK_SIZE); + ctx->sbuf_len = 0; __HAL_HASH_START_DIGEST(); if (HAL_HASH_SHA1_Finish(&ctx->hhash_sha1, output, 10)){ diff --git a/features/mbedtls/targets/TARGET_STM/sha1_alt.h b/features/mbedtls/targets/TARGET_STM/sha1_alt.h index 37fa83b770..814f9569f9 100644 --- a/features/mbedtls/targets/TARGET_STM/sha1_alt.h +++ b/features/mbedtls/targets/TARGET_STM/sha1_alt.h @@ -30,20 +30,18 @@ extern "C" { #endif +#define MBEDTLS_SHA1_BLOCK_SIZE (64) /** * \brief SHA-1 context structure * \note HAL_HASH_SHA1_Accumulate cannot handle less than 4 bytes, unless it is the last call to the function - * In case of buffer size < 4, flag is set to 1, remaining bytes are copied in a temp buffer. - * The pointer and the length are saved in sbuf and sbuf_len. - * At the next accumulation, the saved values are taken into account, and flag is set to 0 - * If SHA1_finish is called and flag=1, the remaining bytes are accumulated before the call to HAL_HASH_SHA1_Finish + * A 64 bytes buffer is used to save values and handle the processing 64 bytes per 64 bytes + * If SHA1_finish is called and sbuf_len>0, the remaining bytes are accumulated before the call to HAL_HASH_SHA1_Finish */ typedef struct { - unsigned char *sbuf; /*!< pointer to the remaining buffer to be processed */ + unsigned char sbuf[MBEDTLS_SHA1_BLOCK_SIZE]; /*!< 64 buffer to store values so that algorithm is caled once the buffer is filled */ unsigned char sbuf_len; /*!< number of bytes remaining in sbuf to be processed */ HASH_HandleTypeDef hhash_sha1; /*!< ST HAL HASH struct */ - int flag; /*!< 1 : there are sbuf_len bytes to be processed in sbuf, 0 : every data have been processed. */ } mbedtls_sha1_context; From c2a85fb12a2b4f47f77f48a23c98c14a5d50a9cc Mon Sep 17 00:00:00 2001 From: adustm Date: Thu, 18 May 2017 18:28:19 +0200 Subject: [PATCH 08/13] Rework SHA1 update for buffer <4 bytes management --- .../mbedtls/targets/TARGET_STM/sha1_alt.c | 50 +++++++++---------- 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/features/mbedtls/targets/TARGET_STM/sha1_alt.c b/features/mbedtls/targets/TARGET_STM/sha1_alt.c index f35667848a..9e963c7a05 100644 --- a/features/mbedtls/targets/TARGET_STM/sha1_alt.c +++ b/features/mbedtls/targets/TARGET_STM/sha1_alt.c @@ -73,42 +73,42 @@ void mbedtls_sha1_starts( mbedtls_sha1_context *ctx ) void mbedtls_sha1_process( mbedtls_sha1_context *ctx, const unsigned char data[MBEDTLS_SHA1_BLOCK_SIZE] ) { - HAL_HASH_SHA1_Accumulate(&ctx->hhash_sha1, (uint8_t *) data, MBEDTLS_SHA1_BLOCK_SIZE); + HAL_HASH_SHA1_Accumulate(&ctx->hhash_sha1, (uint8_t *) data, MBEDTLS_SHA1_BLOCK_SIZE); } void mbedtls_sha1_update( mbedtls_sha1_context *ctx, const unsigned char *input, size_t ilen ) { - unsigned char i=0; - int currentlen = ilen; - /* store mechanism to handle 64 bytes per 64 bytes */ - if (currentlen == 0){ // change HW status is size if 0 - HAL_HASH_SHA1_Accumulate(&ctx->hhash_sha1, (uint8_t *) input, ilen); - } - while ((currentlen+ctx->sbuf_len) >=MBEDTLS_SHA1_BLOCK_SIZE) { - if (ctx->sbuf_len ==0) { /* straight forward */ - mbedtls_sha1_process(ctx, input+(i*MBEDTLS_SHA1_BLOCK_SIZE)); - } else { - unsigned char tmp = ctx->sbuf_len; - memcpy(ctx->sbuf+tmp, input+(i*MBEDTLS_SHA1_BLOCK_SIZE),MBEDTLS_SHA1_BLOCK_SIZE-tmp); - mbedtls_sha1_process(ctx, ctx->sbuf); - if ((currentlen-(MBEDTLS_SHA1_BLOCK_SIZE-tmp)) < tmp) { - ctx->sbuf_len = currentlen-(MBEDTLS_SHA1_BLOCK_SIZE-tmp); - } - memcpy(ctx->sbuf,input+(i+1)*MBEDTLS_SHA1_BLOCK_SIZE-tmp, ctx->sbuf_len); + size_t currentlen = ilen; + // store mechanism to handle MBEDTLS_SHA1_BLOCK_SIZE bytes per MBEDTLS_SHA1_BLOCK_SIZE bytes + if (currentlen == 0){ // only change HW status is size if 0 + if(ctx->hhash_sha1.Phase == HAL_HASH_PHASE_READY) { + /* Select the SHA1 mode and reset the HASH processor core, so that the HASH will be ready to compute + the message digest of a new message */ + HASH->CR |= HASH_ALGOSELECTION_SHA1 | HASH_CR_INIT; } - currentlen -= MBEDTLS_SHA1_BLOCK_SIZE; - i++; - } - if (currentlen >0) { - /* Store the remaining <64 values */ - memcpy(ctx->sbuf+ctx->sbuf_len, input+(i*MBEDTLS_SHA1_BLOCK_SIZE), currentlen); + ctx->hhash_sha1.Phase = HAL_HASH_PHASE_PROCESS; + } else if (currentlen < (MBEDTLS_SHA1_BLOCK_SIZE-ctx->sbuf_len)) { + // only buffurize + memcpy(ctx->sbuf+ctx->sbuf_len, input, currentlen); ctx->sbuf_len += currentlen; + } else { + // fill buffer and process it + memcpy(ctx->sbuf + ctx->sbuf_len, input, (MBEDTLS_SHA1_BLOCK_SIZE-ctx->sbuf_len)); + currentlen -= (MBEDTLS_SHA1_BLOCK_SIZE-ctx->sbuf_len); + mbedtls_sha1_process(ctx, ctx->sbuf); + // now process every input as long as it is %4 bytes + size_t iter = currentlen / 4; + HAL_HASH_SHA1_Accumulate(&ctx->hhash_sha1, (uint8_t *)(input+MBEDTLS_SHA1_BLOCK_SIZE-ctx->sbuf_len), (iter*4)); + // sbuf is now fully accumulated, now copy 1 / 2 or 3 remaining bytes + ctx->sbuf_len = currentlen % 4; + if (ctx->sbuf_len !=0) { + memcpy(ctx->sbuf, input+iter, ctx->sbuf_len); + } } } void mbedtls_sha1_finish( mbedtls_sha1_context *ctx, unsigned char output[20] ) { - if (ctx->sbuf_len > 0) { HAL_HASH_SHA1_Accumulate(&ctx->hhash_sha1, ctx->sbuf, ctx->sbuf_len); } From b38eea2caf57890a90c917c734c09cd05ecaf187 Mon Sep 17 00:00:00 2001 From: adustm Date: Mon, 22 May 2017 13:32:16 +0200 Subject: [PATCH 09/13] Remove tabs, fix doxygen comments --- .../mbedtls/targets/TARGET_STM/sha1_alt.c | 2 +- .../mbedtls/targets/TARGET_STM/sha1_alt.h | 23 ++++++++----------- 2 files changed, 10 insertions(+), 15 deletions(-) diff --git a/features/mbedtls/targets/TARGET_STM/sha1_alt.c b/features/mbedtls/targets/TARGET_STM/sha1_alt.c index 9e963c7a05..10e5a1dc82 100644 --- a/features/mbedtls/targets/TARGET_STM/sha1_alt.c +++ b/features/mbedtls/targets/TARGET_STM/sha1_alt.c @@ -40,7 +40,7 @@ void mbedtls_sha1_free( mbedtls_sha1_context *ctx ) if( ctx == NULL ) return; - /* Force the HASH Periheral Clock Reset */ + /* Force the HASH Periheral Clock Reset */ __HAL_RCC_HASH_FORCE_RESET(); /* Release the HASH Periheral Clock Reset */ diff --git a/features/mbedtls/targets/TARGET_STM/sha1_alt.h b/features/mbedtls/targets/TARGET_STM/sha1_alt.h index 814f9569f9..2421ba20d8 100644 --- a/features/mbedtls/targets/TARGET_STM/sha1_alt.h +++ b/features/mbedtls/targets/TARGET_STM/sha1_alt.h @@ -1,6 +1,8 @@ /* - * sha1_alt.h SHA-1 hash - ******************************************************************************* + * \file sha1_alt.h + * + * \brief SHA1 hw acceleration (hash function) + * * Copyright (C) 2017, STMicroelectronics * SPDX-License-Identifier: Apache-2.0 * @@ -30,16 +32,17 @@ extern "C" { #endif -#define MBEDTLS_SHA1_BLOCK_SIZE (64) +#define MBEDTLS_SHA1_BLOCK_SIZE (64) // must be a multiple of 4 /** * \brief SHA-1 context structure * \note HAL_HASH_SHA1_Accumulate cannot handle less than 4 bytes, unless it is the last call to the function - * A 64 bytes buffer is used to save values and handle the processing 64 bytes per 64 bytes - * If SHA1_finish is called and sbuf_len>0, the remaining bytes are accumulated before the call to HAL_HASH_SHA1_Finish + * A MBEDTLS_SHA1_BLOCK_SIZE bytes buffer is used to save values and handle the processing + * MBEDTLS_SHA1_BLOCK_SIZE bytes per MBEDTLS_SHA1_BLOCK_SIZE bytes + * If SHA1_finish is called and sbuf_len>0, the remaining bytes are accumulated prior to the call to HAL_HASH_SHA1_Finish */ typedef struct { - unsigned char sbuf[MBEDTLS_SHA1_BLOCK_SIZE]; /*!< 64 buffer to store values so that algorithm is caled once the buffer is filled */ + unsigned char sbuf[MBEDTLS_SHA1_BLOCK_SIZE]; /*!< MBEDTLS_SHA1_BLOCK_SIZE buffer to store values so that algorithm is caled once the buffer is filled */ unsigned char sbuf_len; /*!< number of bytes remaining in sbuf to be processed */ HASH_HandleTypeDef hhash_sha1; /*!< ST HAL HASH struct */ } @@ -99,14 +102,6 @@ void mbedtls_sha1_process( mbedtls_sha1_context *ctx, const unsigned char data[6 } #endif -#ifdef __cplusplus -extern "C" { -#endif - -#ifdef __cplusplus -} -#endif - #endif /* MBEDTLS_SHA1_ALT */ #endif /* sha1_alt.h */ From fe94a0e2693a033592889c091d5d1b75c2e64a30 Mon Sep 17 00:00:00 2001 From: adustm Date: Mon, 22 May 2017 17:56:58 +0200 Subject: [PATCH 10/13] Remove MBEDTLS_SHA1_C --- targets/targets.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/targets/targets.json b/targets/targets.json index 5a5e95063c..165ac9f6cf 100644 --- a/targets/targets.json +++ b/targets/targets.json @@ -955,7 +955,7 @@ "extra_labels": ["STM", "STM32F4", "STM32F439", "STM32F439ZI", "STM32F439xx", "STM32F439xI", "FLASH_CMSIS_ALGO"], "supported_toolchains": ["ARM", "uARM", "GCC_ARM", "IAR"], "progen": {"target": "nucleo-f439zi"}, - "macros": ["TRANSACTION_QUEUE_SIZE_SPI=2", "MBEDTLS_CONFIG_HW_SUPPORT", "USB_STM_HAL", "USBHOST_OTHER", "MBEDTLS_SHA1_C"], + "macros": ["TRANSACTION_QUEUE_SIZE_SPI=2", "MBEDTLS_CONFIG_HW_SUPPORT", "USB_STM_HAL", "USBHOST_OTHER"], "device_has": ["ANALOGIN", "ANALOGOUT", "CAN", "ERROR_RED", "I2C", "I2CSLAVE", "I2C_ASYNCH", "INTERRUPTIN", "LOWPOWERTIMER", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SERIAL_FC", "SLEEP", "SPI", "SPISLAVE", "SPI_ASYNCH", "STDIO_MESSAGES", "TRNG", "FLASH"], "detect_code": ["0797"], "features": ["LWIP"], From 85d68e32f7982d083ed1cc6f1cce885f12d63a3e Mon Sep 17 00:00:00 2001 From: adustm Date: Tue, 23 May 2017 14:03:17 +0200 Subject: [PATCH 11/13] replace 64 by define --- features/mbedtls/targets/TARGET_STM/sha1_alt.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/features/mbedtls/targets/TARGET_STM/sha1_alt.h b/features/mbedtls/targets/TARGET_STM/sha1_alt.h index 2421ba20d8..f1c4a8a4ff 100644 --- a/features/mbedtls/targets/TARGET_STM/sha1_alt.h +++ b/features/mbedtls/targets/TARGET_STM/sha1_alt.h @@ -96,7 +96,7 @@ void mbedtls_sha1_update( mbedtls_sha1_context *ctx, const unsigned char *input, void mbedtls_sha1_finish( mbedtls_sha1_context *ctx, unsigned char output[20] ); /* Internal use */ -void mbedtls_sha1_process( mbedtls_sha1_context *ctx, const unsigned char data[64] ); +void mbedtls_sha1_process( mbedtls_sha1_context *ctx, const unsigned char data[MBEDTLS_SHA1_BLOCK_SIZE] ); #ifdef __cplusplus } From 842791bef79552ced022b8ced05b4f194c138309 Mon Sep 17 00:00:00 2001 From: adustm Date: Fri, 2 Jun 2017 16:01:29 +0200 Subject: [PATCH 12/13] handle context swap + change macro name --- .../mbedtls/targets/TARGET_STM/sha1_alt.c | 79 +++++++++++++------ .../mbedtls/targets/TARGET_STM/sha1_alt.h | 17 ++-- 2 files changed, 65 insertions(+), 31 deletions(-) diff --git a/features/mbedtls/targets/TARGET_STM/sha1_alt.c b/features/mbedtls/targets/TARGET_STM/sha1_alt.c index 10e5a1dc82..58b749c7d7 100644 --- a/features/mbedtls/targets/TARGET_STM/sha1_alt.c +++ b/features/mbedtls/targets/TARGET_STM/sha1_alt.c @@ -26,6 +26,28 @@ static void mbedtls_zeroize( void *v, size_t n ) { volatile unsigned char *p = (unsigned char*)v; while( n-- ) *p++ = 0; } +static void st_sha1_restore_hw_context(mbedtls_sha1_context *ctx) +{ + uint32_t i; + /* allow multi-instance of HASH use: save context for HASH HW module CR */ + HASH->STR = ctx->ctx_save_str; + HASH->CR = (ctx->ctx_save_cr|HASH_CR_INIT); + for (i=0;i<38;i++) { + HASH->CSR[i] = ctx->ctx_save_csr[i]; + } +} + +static void st_sha1_save_hw_context(mbedtls_sha1_context *ctx) +{ + uint32_t i; + /* allow multi-instance of HASH use: restore context for HASH HW module CR */ + ctx->ctx_save_cr = HASH->CR; + ctx->ctx_save_str = HASH->STR; + for (i=0;i<38;i++) { + ctx->ctx_save_csr[i] = HASH->CSR[i]; + } +} + void mbedtls_sha1_init( mbedtls_sha1_context *ctx ) { mbedtls_zeroize( ctx, sizeof( mbedtls_sha1_context ) ); @@ -39,13 +61,6 @@ void mbedtls_sha1_free( mbedtls_sha1_context *ctx ) { if( ctx == NULL ) return; - - /* Force the HASH Periheral Clock Reset */ - __HAL_RCC_HASH_FORCE_RESET(); - - /* Release the HASH Periheral Clock Reset */ - __HAL_RCC_HASH_RELEASE_RESET(); - mbedtls_zeroize( ctx, sizeof( mbedtls_sha1_context ) ); } @@ -69,17 +84,25 @@ void mbedtls_sha1_starts( mbedtls_sha1_context *ctx ) // error found to be returned return; } + st_sha1_save_hw_context(ctx); } -void mbedtls_sha1_process( mbedtls_sha1_context *ctx, const unsigned char data[MBEDTLS_SHA1_BLOCK_SIZE] ) +void mbedtls_sha1_process( mbedtls_sha1_context *ctx, const unsigned char data[ST_SHA1_BLOCK_SIZE] ) { - HAL_HASH_SHA1_Accumulate(&ctx->hhash_sha1, (uint8_t *) data, MBEDTLS_SHA1_BLOCK_SIZE); + st_sha1_restore_hw_context(ctx); + if (HAL_HASH_SHA1_Accumulate(&ctx->hhash_sha1, (uint8_t *) data, ST_SHA1_BLOCK_SIZE) != 0) { + return; // Return error code + } + + st_sha1_save_hw_context(ctx); } void mbedtls_sha1_update( mbedtls_sha1_context *ctx, const unsigned char *input, size_t ilen ) { size_t currentlen = ilen; - // store mechanism to handle MBEDTLS_SHA1_BLOCK_SIZE bytes per MBEDTLS_SHA1_BLOCK_SIZE bytes + st_sha1_restore_hw_context(ctx); + + // store mechanism to accumulate ST_SHA1_BLOCK_SIZE bytes (512 bits) in the HW if (currentlen == 0){ // only change HW status is size if 0 if(ctx->hhash_sha1.Phase == HAL_HASH_PHASE_READY) { /* Select the SHA1 mode and reset the HASH processor core, so that the HASH will be ready to compute @@ -87,38 +110,46 @@ void mbedtls_sha1_update( mbedtls_sha1_context *ctx, const unsigned char *input, HASH->CR |= HASH_ALGOSELECTION_SHA1 | HASH_CR_INIT; } ctx->hhash_sha1.Phase = HAL_HASH_PHASE_PROCESS; - } else if (currentlen < (MBEDTLS_SHA1_BLOCK_SIZE-ctx->sbuf_len)) { + } else if (currentlen < (ST_SHA1_BLOCK_SIZE - ctx->sbuf_len)) { // only buffurize - memcpy(ctx->sbuf+ctx->sbuf_len, input, currentlen); + memcpy(ctx->sbuf + ctx->sbuf_len, input, currentlen); ctx->sbuf_len += currentlen; } else { // fill buffer and process it - memcpy(ctx->sbuf + ctx->sbuf_len, input, (MBEDTLS_SHA1_BLOCK_SIZE-ctx->sbuf_len)); - currentlen -= (MBEDTLS_SHA1_BLOCK_SIZE-ctx->sbuf_len); + memcpy(ctx->sbuf + ctx->sbuf_len, input, (ST_SHA1_BLOCK_SIZE - ctx->sbuf_len)); + currentlen -= (ST_SHA1_BLOCK_SIZE - ctx->sbuf_len); mbedtls_sha1_process(ctx, ctx->sbuf); - // now process every input as long as it is %4 bytes - size_t iter = currentlen / 4; - HAL_HASH_SHA1_Accumulate(&ctx->hhash_sha1, (uint8_t *)(input+MBEDTLS_SHA1_BLOCK_SIZE-ctx->sbuf_len), (iter*4)); - // sbuf is now fully accumulated, now copy 1 / 2 or 3 remaining bytes - ctx->sbuf_len = currentlen % 4; + // Process every input as long as it is %64 bytes, ie 512 bits + size_t iter = currentlen / ST_SHA1_BLOCK_SIZE; + if (HAL_HASH_SHA1_Accumulate(&ctx->hhash_sha1, (uint8_t *)(input + ST_SHA1_BLOCK_SIZE - ctx->sbuf_len), (iter * ST_SHA1_BLOCK_SIZE)) != 0) { + return; // Return error code here + } + // sbuf is completely accumulated, now copy up to 63 remaining bytes + ctx->sbuf_len = currentlen % ST_SHA1_BLOCK_SIZE; if (ctx->sbuf_len !=0) { - memcpy(ctx->sbuf, input+iter, ctx->sbuf_len); + memcpy(ctx->sbuf, input + ilen - ctx->sbuf_len, ctx->sbuf_len); } } + st_sha1_save_hw_context(ctx); } void mbedtls_sha1_finish( mbedtls_sha1_context *ctx, unsigned char output[20] ) { + st_sha1_restore_hw_context(ctx); + if (ctx->sbuf_len > 0) { - HAL_HASH_SHA1_Accumulate(&ctx->hhash_sha1, ctx->sbuf, ctx->sbuf_len); + if (HAL_HASH_SHA1_Accumulate(&ctx->hhash_sha1, ctx->sbuf, ctx->sbuf_len) != 0) { + return; // Return error code here + } } - mbedtls_zeroize(ctx->sbuf, MBEDTLS_SHA1_BLOCK_SIZE); + mbedtls_zeroize(ctx->sbuf, ST_SHA1_BLOCK_SIZE); ctx->sbuf_len = 0; __HAL_HASH_START_DIGEST(); - if (HAL_HASH_SHA1_Finish(&ctx->hhash_sha1, output, 10)){ - // error code to be returned + if (HAL_HASH_SHA1_Finish(&ctx->hhash_sha1, output, 10) != 0){ + return; // error code to be returned } + st_sha1_save_hw_context(ctx); } #endif /*MBEDTLS_SHA1_ALT*/ diff --git a/features/mbedtls/targets/TARGET_STM/sha1_alt.h b/features/mbedtls/targets/TARGET_STM/sha1_alt.h index f1c4a8a4ff..804eccd97f 100644 --- a/features/mbedtls/targets/TARGET_STM/sha1_alt.h +++ b/features/mbedtls/targets/TARGET_STM/sha1_alt.h @@ -22,7 +22,7 @@ #ifndef MBEDTLS_SHA1_ALT_H #define MBEDTLS_SHA1_ALT_H -#if defined MBEDTLS_SHA1_ALT +#if defined (MBEDTLS_SHA1_ALT) #include "cmsis.h" @@ -32,19 +32,22 @@ extern "C" { #endif -#define MBEDTLS_SHA1_BLOCK_SIZE (64) // must be a multiple of 4 +#define ST_SHA1_BLOCK_SIZE (64) // HW handles 512 bits, ie 64 bytes /** * \brief SHA-1 context structure - * \note HAL_HASH_SHA1_Accumulate cannot handle less than 4 bytes, unless it is the last call to the function - * A MBEDTLS_SHA1_BLOCK_SIZE bytes buffer is used to save values and handle the processing - * MBEDTLS_SHA1_BLOCK_SIZE bytes per MBEDTLS_SHA1_BLOCK_SIZE bytes + * \note HAL_HASH_SHA1_Accumulate will accumulate 512 bits packets, unless it is the last call to the function + * A ST_SHA1_BLOCK_SIZE bytes buffer is used to save values and handle the processing + * multiples of ST_SHA1_BLOCK_SIZE bytes * If SHA1_finish is called and sbuf_len>0, the remaining bytes are accumulated prior to the call to HAL_HASH_SHA1_Finish */ typedef struct { - unsigned char sbuf[MBEDTLS_SHA1_BLOCK_SIZE]; /*!< MBEDTLS_SHA1_BLOCK_SIZE buffer to store values so that algorithm is caled once the buffer is filled */ + unsigned char sbuf[ST_SHA1_BLOCK_SIZE]; /*!< MBEDTLS_SHA1_BLOCK_SIZE buffer to store values so that algorithm is caled once the buffer is filled */ unsigned char sbuf_len; /*!< number of bytes remaining in sbuf to be processed */ HASH_HandleTypeDef hhash_sha1; /*!< ST HAL HASH struct */ + uint32_t ctx_save_cr; + uint32_t ctx_save_str; + uint32_t ctx_save_csr[38]; } mbedtls_sha1_context; @@ -96,7 +99,7 @@ void mbedtls_sha1_update( mbedtls_sha1_context *ctx, const unsigned char *input, void mbedtls_sha1_finish( mbedtls_sha1_context *ctx, unsigned char output[20] ); /* Internal use */ -void mbedtls_sha1_process( mbedtls_sha1_context *ctx, const unsigned char data[MBEDTLS_SHA1_BLOCK_SIZE] ); +void mbedtls_sha1_process( mbedtls_sha1_context *ctx, const unsigned char data[ST_SHA1_BLOCK_SIZE] ); #ifdef __cplusplus } From e63912ff44d18cd02ce20f8a04fd0bd04ae23325 Mon Sep 17 00:00:00 2001 From: adustm Date: Thu, 8 Jun 2017 17:00:08 +0200 Subject: [PATCH 13/13] Check that the HASH is not busy before save and restore iHW registers --- .../mbedtls/targets/TARGET_STM/sha1_alt.c | 52 +++++++++++++++---- .../mbedtls/targets/TARGET_STM/sha1_alt.h | 3 +- 2 files changed, 44 insertions(+), 11 deletions(-) diff --git a/features/mbedtls/targets/TARGET_STM/sha1_alt.c b/features/mbedtls/targets/TARGET_STM/sha1_alt.c index 58b749c7d7..98317c21fa 100644 --- a/features/mbedtls/targets/TARGET_STM/sha1_alt.c +++ b/features/mbedtls/targets/TARGET_STM/sha1_alt.c @@ -26,26 +26,44 @@ static void mbedtls_zeroize( void *v, size_t n ) { volatile unsigned char *p = (unsigned char*)v; while( n-- ) *p++ = 0; } -static void st_sha1_restore_hw_context(mbedtls_sha1_context *ctx) +static int st_sha1_restore_hw_context(mbedtls_sha1_context *ctx) { uint32_t i; + uint32_t tickstart; /* allow multi-instance of HASH use: save context for HASH HW module CR */ + /* Check that there is no HASH activity on going */ + tickstart = HAL_GetTick(); + while ((HASH->SR & (HASH_FLAG_BUSY | HASH_FLAG_DMAS)) != 0) { + if ((HAL_GetTick() - tickstart) > ST_SHA1_TIMEOUT) { + return 0; // timeout: HASH processor is busy + } + } HASH->STR = ctx->ctx_save_str; - HASH->CR = (ctx->ctx_save_cr|HASH_CR_INIT); + HASH->CR = (ctx->ctx_save_cr | HASH_CR_INIT); for (i=0;i<38;i++) { HASH->CSR[i] = ctx->ctx_save_csr[i]; } + return 1; } -static void st_sha1_save_hw_context(mbedtls_sha1_context *ctx) +static int st_sha1_save_hw_context(mbedtls_sha1_context *ctx) { uint32_t i; + uint32_t tickstart; + /* Check that there is no HASH activity on going */ + tickstart = HAL_GetTick(); + while ((HASH->SR & (HASH_FLAG_BUSY | HASH_FLAG_DMAS)) != 0) { + if ((HAL_GetTick() - tickstart) > ST_SHA1_TIMEOUT) { + return 0; // timeout: HASH processor is busy + } + } /* allow multi-instance of HASH use: restore context for HASH HW module CR */ ctx->ctx_save_cr = HASH->CR; ctx->ctx_save_str = HASH->STR; for (i=0;i<38;i++) { ctx->ctx_save_csr[i] = HASH->CSR[i]; } + return 1; } void mbedtls_sha1_init( mbedtls_sha1_context *ctx ) @@ -84,23 +102,31 @@ void mbedtls_sha1_starts( mbedtls_sha1_context *ctx ) // error found to be returned return; } - st_sha1_save_hw_context(ctx); + if (st_sha1_save_hw_context(ctx) != 1) { + return; // return HASH_BUSY timeout Error here + } } void mbedtls_sha1_process( mbedtls_sha1_context *ctx, const unsigned char data[ST_SHA1_BLOCK_SIZE] ) { - st_sha1_restore_hw_context(ctx); + if (st_sha1_restore_hw_context(ctx) != 1) { + return; // Return HASH_BUSY timout error here + } if (HAL_HASH_SHA1_Accumulate(&ctx->hhash_sha1, (uint8_t *) data, ST_SHA1_BLOCK_SIZE) != 0) { return; // Return error code } - st_sha1_save_hw_context(ctx); + if (st_sha1_save_hw_context(ctx) != 1) { + return; // return HASH_BUSY timeout Error here + } } void mbedtls_sha1_update( mbedtls_sha1_context *ctx, const unsigned char *input, size_t ilen ) { size_t currentlen = ilen; - st_sha1_restore_hw_context(ctx); + if (st_sha1_restore_hw_context(ctx) != 1) { + return; // Return HASH_BUSY timout error here + } // store mechanism to accumulate ST_SHA1_BLOCK_SIZE bytes (512 bits) in the HW if (currentlen == 0){ // only change HW status is size if 0 @@ -130,12 +156,16 @@ void mbedtls_sha1_update( mbedtls_sha1_context *ctx, const unsigned char *input, memcpy(ctx->sbuf, input + ilen - ctx->sbuf_len, ctx->sbuf_len); } } - st_sha1_save_hw_context(ctx); + if (st_sha1_save_hw_context(ctx) != 1) { + return; // return HASH_BUSY timeout Error here + } } void mbedtls_sha1_finish( mbedtls_sha1_context *ctx, unsigned char output[20] ) { - st_sha1_restore_hw_context(ctx); + if (st_sha1_restore_hw_context(ctx) != 1) { + return; // Return HASH_BUSY timout error here + } if (ctx->sbuf_len > 0) { if (HAL_HASH_SHA1_Accumulate(&ctx->hhash_sha1, ctx->sbuf, ctx->sbuf_len) != 0) { @@ -149,7 +179,9 @@ void mbedtls_sha1_finish( mbedtls_sha1_context *ctx, unsigned char output[20] ) if (HAL_HASH_SHA1_Finish(&ctx->hhash_sha1, output, 10) != 0){ return; // error code to be returned } - st_sha1_save_hw_context(ctx); + if (st_sha1_save_hw_context(ctx) != 1) { + return; // return HASH_BUSY timeout Error here + } } #endif /*MBEDTLS_SHA1_ALT*/ diff --git a/features/mbedtls/targets/TARGET_STM/sha1_alt.h b/features/mbedtls/targets/TARGET_STM/sha1_alt.h index 804eccd97f..4db4880bea 100644 --- a/features/mbedtls/targets/TARGET_STM/sha1_alt.h +++ b/features/mbedtls/targets/TARGET_STM/sha1_alt.h @@ -32,7 +32,8 @@ extern "C" { #endif -#define ST_SHA1_BLOCK_SIZE (64) // HW handles 512 bits, ie 64 bytes +#define ST_SHA1_BLOCK_SIZE ((size_t) 64) // HW handles 512 bits, ie 64 bytes +#define ST_SHA1_TIMEOUT ((uint32_t) 3) /** * \brief SHA-1 context structure * \note HAL_HASH_SHA1_Accumulate will accumulate 512 bits packets, unless it is the last call to the function