Skip to content

NUCLEO_F756ZG / mbedTLS_SHA1 hw acceleration #3957

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

Closed
wants to merge 9 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#define MBEDTLS_DEVICE_H

#define MBEDTLS_AES_ALT
#define MBEDTLS_SHA1_ALT


#define MBEDTLS_SHA1_C
Copy link
Contributor

Choose a reason for hiding this comment

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

This is an application specific definition, and should be defined by the end user. Please remove it

Copy link
Member Author

Choose a reason for hiding this comment

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

OK, I'll put that into targets.json

#endif /* MBEDTLS_DEVICE_H */
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/*
* mbedtls_device.h
*******************************************************************************
* 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_DEVICE_H
#define MBEDTLS_DEVICE_H

#define MBEDTLS_AES_ALT
Copy link
Contributor

Choose a reason for hiding this comment

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

This adds alternative AES support, but this PR is for SHA1 only.

Copy link
Member Author

Choose a reason for hiding this comment

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

Same comment as in PR for MD5. I based my PR on AES' one because I think it causes merge issues if I create new folders and new files with the same names in separate PRs, sorry for that.

#define MBEDTLS_SHA1_ALT

#endif /* MBEDTLS_DEVICE_H */
165 changes: 165 additions & 0 deletions features/mbedtls/targets/TARGET_STM/sha1_alt.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,165 @@
/*
* 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)
#include "mbedtls/platform.h"

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

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

/* 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) {
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);
} 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);
}
}
}
}

/*
* 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);
mbedtls_sha1_clear_ctxbuf(ctx);
}

__HAL_HASH_START_DIGEST();

if (HAL_HASH_SHA1_Finish(&ctx->hhash_sha1, output, 10)){
// error code to be returned
}
}

#endif /*MBEDTLS_SHA1_ALT*/
114 changes: 114 additions & 0 deletions features/mbedtls/targets/TARGET_STM/sha1_alt.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
/*
* 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 "cmsis.h"
#include <string.h>

#ifdef __cplusplus
extern "C" {
#endif

/**
* \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; /*!< 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;

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

#ifdef __cplusplus
}
#endif

#endif /* MBEDTLS_SHA1_ALT */

#endif /* sha1_alt.h */
1 change: 1 addition & 0 deletions targets/targets.json
Original file line number Diff line number Diff line change
Expand Up @@ -969,6 +969,7 @@
"extra_labels": ["STM", "STM32F7", "STM32F756", "STM32F756xG", "STM32F756ZG"],
"supported_toolchains": ["ARM", "uARM", "GCC_ARM", "IAR"],
"default_toolchain": "ARM",
"macros": ["TRANSACTION_QUEUE_SIZE_SPI=2", "USBHOST_OTHER", "MBEDTLS_CONFIG_HW_SUPPORT", "MBEDTLS_SHA1_C"],
"supported_form_factors": ["ARDUINO"],
"detect_code": ["0819"],
"device_has": ["ANALOGIN", "ANALOGOUT", "CAN", "I2C", "I2CSLAVE", "I2C_ASYNCH", "INTERRUPTIN", "LOWPOWERTIMER", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SERIAL_ASYNCH", "SLEEP", "SPI", "SPISLAVE", "STDIO_MESSAGES", "TRNG"],
Expand Down