Merge branch 'feature/esp8684_sha' into 'master'

mbedtls: enable hw support for SHA on C2

Closes IDF-3830 and IDF-5141

See merge request espressif/esp-idf!18531
This commit is contained in:
Marius Vikhammer
2022-06-23 14:18:49 +08:00
19 changed files with 921 additions and 85 deletions

View File

@@ -15,12 +15,11 @@
#include "sha/sha_parallel_engine.h" #include "sha/sha_parallel_engine.h"
#elif SOC_SHA_SUPPORT_DMA #elif SOC_SHA_SUPPORT_DMA
#include "sha/sha_dma.h" #include "sha/sha_dma.h"
#else
#include "sha/sha_block.h"
#endif #endif
#include "test_utils.h" #include "test_utils.h"
#if !TEMPORARY_DISABLED_FOR_TARGETS(ESP32C2)
//IDF-5044
const char *test_cert_pem = "-----BEGIN CERTIFICATE-----\n"\ const char *test_cert_pem = "-----BEGIN CERTIFICATE-----\n"\
"MIICrDCCAZQCCQD88gCs5AFs/jANBgkqhkiG9w0BAQsFADAYMRYwFAYDVQQDDA1F\n"\ "MIICrDCCAZQCCQD88gCs5AFs/jANBgkqhkiG9w0BAQsFADAYMRYwFAYDVQQDDA1F\n"\
"U1AtVExTIFRlc3RzMB4XDTIxMDEwNzAxMTc1OVoXDTMxMDEwNTAxMTc1OVowGDEW\n"\ "U1AtVExTIFRlc3RzMB4XDTIxMDEwNzAxMTc1OVoXDTMxMDEwNTAxMTc1OVowGDEW\n"\
@@ -68,6 +67,11 @@ const char *test_key_pem = "-----BEGIN PRIVATE KEY-----\n"\
"Aogx44Fozd1t2hYcozPuZD4s\n"\ "Aogx44Fozd1t2hYcozPuZD4s\n"\
"-----END PRIVATE KEY-----\n"; "-----END PRIVATE KEY-----\n";
#if SOC_SHA_SUPPORT_SHA512
#define SHA_TYPE SHA2_512
#else
#define SHA_TYPE SHA2_256
#endif //SOC_SHA_SUPPORT_SHA512
static void test_leak_setup(const char *file, long line) static void test_leak_setup(const char *file, long line)
{ {
@@ -80,7 +84,7 @@ static void test_leak_setup(const char *file, long line)
// which is considered as leaked otherwise // which is considered as leaked otherwise
const uint8_t input_buffer[64]; const uint8_t input_buffer[64];
uint8_t output_buffer[64]; uint8_t output_buffer[64];
esp_sha(SHA2_512, input_buffer, sizeof(input_buffer), output_buffer); esp_sha(SHA_TYPE, input_buffer, sizeof(input_buffer), output_buffer);
test_utils_record_free_mem(); test_utils_record_free_mem();
} }
@@ -124,5 +128,3 @@ TEST_CASE("esp_tls_server session create delete", "[esp-tls][leaks=0]")
esp_tls_server_session_delete(tls); esp_tls_server_session_delete(tls);
} }
#endif #endif
#endif //!TEMPORARY_DISABLED_FOR_TARGETS(ESP32C2)

View File

@@ -1,19 +0,0 @@
/*
* SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
// Place-holder lock APIs as hardware AES is not supported in ESP32-C2
static inline void esp_crypto_sha_aes_lock_acquire(void) {}
static inline void esp_crypto_sha_aes_lock_release(void) {}
#ifdef __cplusplus
}
#endif

View File

@@ -6,17 +6,10 @@
#pragma once #pragma once
#define IDF_PERFORMANCE_MIN_AES_CBC_THROUGHPUT_MBSEC 43
// SHA256 hardware throughput at 160 MHz, threshold set lower than worst case // SHA256 hardware throughput at 160 MHz, threshold set lower than worst case
#define IDF_PERFORMANCE_MIN_SHA256_THROUGHPUT_MBSEC 90 #define IDF_PERFORMANCE_MIN_SHA256_THROUGHPUT_MBSEC 14
// esp_sha() time to process 32KB of input data from RAM // esp_sha() time to process 32KB of input data from RAM
#define IDF_PERFORMANCE_MAX_TIME_SHA1_32KB 560 #define IDF_PERFORMANCE_MAX_TIME_SHA1_32KB 2500
#define IDF_PERFORMANCE_MAX_RSA_2048KEY_PUBLIC_OP 19000
#define IDF_PERFORMANCE_MAX_RSA_2048KEY_PRIVATE_OP 210000
#define IDF_PERFORMANCE_MAX_RSA_3072KEY_PUBLIC_OP 45000
#define IDF_PERFORMANCE_MAX_RSA_3072KEY_PRIVATE_OP 670000
#define IDF_PERFORMANCE_MAX_SPI_PER_TRANS_POLLING 20 #define IDF_PERFORMANCE_MAX_SPI_PER_TRANS_POLLING 20
#define IDF_PERFORMANCE_MAX_SPI_PER_TRANS_POLLING_NO_DMA 15 #define IDF_PERFORMANCE_MAX_SPI_PER_TRANS_POLLING_NO_DMA 15

View File

@@ -137,8 +137,10 @@ target_sources(mbedtls PRIVATE ${mbedtls_target_sources})
if(CONFIG_SOC_SHA_SUPPORTED) if(CONFIG_SOC_SHA_SUPPORTED)
if(CONFIG_SOC_SHA_SUPPORT_DMA) if(CONFIG_SOC_SHA_SUPPORT_DMA)
set(SHA_PERIPHERAL_TYPE "dma") set(SHA_PERIPHERAL_TYPE "dma")
else() elseif(CONFIG_SOC_SHA_SUPPORT_PARALLEL_ENG)
set(SHA_PERIPHERAL_TYPE "parallel_engine") set(SHA_PERIPHERAL_TYPE "parallel_engine")
else()
set(SHA_PERIPHERAL_TYPE "block")
endif() endif()
endif() endif()
@@ -163,7 +165,6 @@ if(SHA_PERIPHERAL_TYPE STREQUAL "dma")
endif() endif()
if(AES_PERIPHERAL_TYPE STREQUAL "dma") if(AES_PERIPHERAL_TYPE STREQUAL "dma")
if(NOT CONFIG_SOC_AES_GDMA) if(NOT CONFIG_SOC_AES_GDMA)
set(AES_DMA_SRCS "${COMPONENT_DIR}/port/aes/dma/esp_aes_crypto_dma_impl.c") set(AES_DMA_SRCS "${COMPONENT_DIR}/port/aes/dma/esp_aes_crypto_dma_impl.c")
else() else()
@@ -175,6 +176,7 @@ if(AES_PERIPHERAL_TYPE STREQUAL "dma")
target_sources(mbedcrypto PRIVATE "${AES_DMA_SRCS}") target_sources(mbedcrypto PRIVATE "${AES_DMA_SRCS}")
endif() endif()
target_sources(mbedcrypto PRIVATE "${COMPONENT_DIR}/port/esp_hardware.c" target_sources(mbedcrypto PRIVATE "${COMPONENT_DIR}/port/esp_hardware.c"
"${COMPONENT_DIR}/port/esp_mem.c" "${COMPONENT_DIR}/port/esp_mem.c"
"${COMPONENT_DIR}/port/esp_timing.c" "${COMPONENT_DIR}/port/esp_timing.c"

View File

@@ -0,0 +1,113 @@
/*
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include <stddef.h>
#include "hal/sha_types.h"
/** @brief Low-level support functions for the hardware SHA engine
*
* @note If you're looking for a SHA API to use, try mbedtls component
* mbedtls/shaXX.h. That API supports hardware acceleration.
*
* The API in this header provides some building blocks for implementing a
* full SHA API such as the one in mbedtls, and also a basic SHA function esp_sha().
*
*/
#ifdef __cplusplus
extern "C" {
#endif
/** @brief Calculate SHA1 or SHA2 sum of some data, using hardware SHA engine
*
* @note For more versatile SHA calculations, where data doesn't need
* to be passed all at once, try the mbedTLS mbedtls/shaX.h APIs.
*
* @note It is not necessary to lock any SHA hardware before calling
* this function, thread safety is managed internally.
*
* @param sha_type SHA algorithm to use.
*
* @param input Input data buffer.
*
* @param ilen Length of input data in bytes.
*
* @param output Buffer for output SHA digest. Output is 20 bytes for
* sha_type SHA1, 32 bytes for sha_type SHA2_256, 48 bytes for
* sha_type SHA2_384, 64 bytes for sha_type SHA2_512.
*/
void esp_sha(esp_sha_type sha_type, const unsigned char *input, size_t ilen, unsigned char *output);
/** @brief Execute SHA block operation
*
* @note This is a piece of a SHA algorithm, rather than an entire SHA
* algorithm.
*
* @note Call esp_sha_acquire_hardware() before calling this
* function.
*
* @param sha_type SHA algorithm to use.
*
* @param data_block Pointer to the input data. Block size is
* determined by algorithm (SHA1/SHA2_256 = 64 bytes,
* SHA2_384/SHA2_512 = 128 bytes)
*
* @param is_first_block If this parameter is true, the SHA state will
* be initialised (with the initial state of the given SHA algorithm)
* before the block is calculated. If false, the existing state of the
* SHA engine will be used.
*
*/
void esp_sha_block(esp_sha_type sha_type, const void *data_block, bool is_first_block);
/**
* @brief Read out the current state of the SHA digest
*
* @note This is a piece of a SHA algorithm, rather than an entire SHA algorithm.
*
* @note Call esp_sha_aquire_hardware() before calling this
* function.
*
* If the SHA suffix padding block has been executed already, the
* value that is read is the SHA digest.
* Otherwise, the value that is read is an interim SHA state.
*
* @param sha_type SHA algorithm in use.
* @param digest_state Pointer to a memory buffer to hold the SHA state. Size
* is 20 bytes (SHA1), 32 bytes (SHA2_256), or 64 bytes (SHA2_384, SHA2_512).
*/
void esp_sha_read_digest_state(esp_sha_type sha_type, void *digest_state);
/**
* @brief Set the current state of the SHA digest
*
* @note Call esp_sha_aquire_hardware() before calling this
* function.
*
* @param sha_type SHA algorithm in use.
* @param digest_state Digest state to write to hardware
*/
void esp_sha_write_digest_state(esp_sha_type sha_type, void *digest_state);
/**
* @brief Enables the SHA peripheral and takes the lock.
*/
void esp_sha_acquire_hardware(void);
/**
* @brief Disables the SHA peripheral and releases the lock.
*/
void esp_sha_release_hardware(void);
#ifdef __cplusplus
}
#endif

View File

@@ -50,7 +50,7 @@ typedef struct {
esp_mbedtls_sha1_mode mode; esp_mbedtls_sha1_mode mode;
} mbedtls_sha1_context; } mbedtls_sha1_context;
#elif SOC_SHA_SUPPORT_DMA #elif SOC_SHA_SUPPORT_DMA || SOC_SHA_SUPPORT_RESUME
typedef enum { typedef enum {
ESP_SHA1_STATE_INIT, ESP_SHA1_STATE_INIT,

View File

@@ -50,7 +50,7 @@ typedef struct {
esp_mbedtls_sha256_mode mode; esp_mbedtls_sha256_mode mode;
} mbedtls_sha256_context; } mbedtls_sha256_context;
#elif SOC_SHA_SUPPORT_DMA #elif SOC_SHA_SUPPORT_DMA || SOC_SHA_SUPPORT_RESUME
typedef enum { typedef enum {
ESP_SHA256_STATE_INIT, ESP_SHA256_STATE_INIT,
ESP_SHA256_STATE_IN_PROCESS ESP_SHA256_STATE_IN_PROCESS

View File

@@ -52,7 +52,7 @@ typedef struct {
esp_mbedtls_sha512_mode mode; esp_mbedtls_sha512_mode mode;
} mbedtls_sha512_context; } mbedtls_sha512_context;
#elif SOC_SHA_SUPPORT_DMA #elif SOC_SHA_SUPPORT_DMA || SOC_SHA_SUPPORT_RESUME
typedef enum { typedef enum {
ESP_SHA512_STATE_INIT, ESP_SHA512_STATE_INIT,

View File

@@ -0,0 +1,212 @@
/*
* SHA-1 implementation with hardware ESP support added.
*
* SPDX-FileCopyrightText: The Mbed TLS Contributors
*
* SPDX-License-Identifier: Apache-2.0
*
* SPDX-FileContributor: 2016-2022 Espressif Systems (Shanghai) CO LTD
*/
/*
* The SHA-1 standard was published by NIST in 1993.
*
* http://www.itl.nist.gov/fipspubs/fip180-1.htm
*/
#include <mbedtls/build_info.h>
#if defined(MBEDTLS_SHA1_C) && defined(MBEDTLS_SHA1_ALT)
#include "mbedtls/sha1.h"
#include <string.h>
#include <assert.h>
#if defined(MBEDTLS_SELF_TEST)
#if defined(MBEDTLS_PLATFORM_C)
#include "mbedtls/platform.h"
#else
#include <stdio.h>
#define mbedtls_printf printf
#endif /* MBEDTLS_PLATFORM_C */
#endif /* MBEDTLS_SELF_TEST */
#include "sha/sha_block.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;
}
}
/*
* 32-bit integer manipulation macros (big endian)
*/
#ifndef PUT_UINT32_BE
#define PUT_UINT32_BE(n,b,i) \
{ \
(b)[(i) ] = (unsigned char) ( (n) >> 24 ); \
(b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \
(b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \
(b)[(i) + 3] = (unsigned char) ( (n) ); \
}
#endif
void mbedtls_sha1_init( mbedtls_sha1_context *ctx )
{
assert(ctx != NULL);
memset( ctx, 0, sizeof( mbedtls_sha1_context ) );
}
void mbedtls_sha1_free( mbedtls_sha1_context *ctx )
{
if ( ctx == NULL ) {
return;
}
mbedtls_zeroize( ctx, sizeof( mbedtls_sha1_context ) );
}
void mbedtls_sha1_clone( mbedtls_sha1_context *dst,
const mbedtls_sha1_context *src )
{
memcpy(dst, src, sizeof(mbedtls_sha1_context));
}
/*
* SHA-1 context setup
*/
int mbedtls_sha1_starts( mbedtls_sha1_context *ctx )
{
ctx->total[0] = 0;
ctx->total[1] = 0;
memset( ctx, 0, sizeof( mbedtls_sha1_context ) );
ctx->mode = SHA1;
return 0;
}
static void esp_internal_sha1_block_process(mbedtls_sha1_context *ctx, const uint8_t *data)
{
esp_sha_block(SHA1, data, ctx->first_block);
if (ctx->first_block) {
ctx->first_block = false;
}
}
int mbedtls_internal_sha1_process( mbedtls_sha1_context *ctx, const unsigned char data[64] )
{
esp_sha_acquire_hardware();
esp_sha_block(ctx->mode, data, ctx->first_block);
esp_sha_release_hardware();
return 0;
}
int mbedtls_sha1_update( mbedtls_sha1_context *ctx, const unsigned char *input, size_t ilen )
{
size_t fill;
uint32_t left, local_len = 0;
if ( !ilen || (input == NULL)) {
return 0;
}
left = ctx->total[0] & 0x3F;
fill = 64 - left;
ctx->total[0] += (uint32_t) ilen;
ctx->total[0] &= 0xFFFFFFFF;
if ( ctx->total[0] < (uint32_t) ilen ) {
ctx->total[1]++;
}
if ( left && ilen >= fill ) {
memcpy( (void *) (ctx->buffer + left), input, fill );
input += fill;
ilen -= fill;
left = 0;
local_len = 64;
}
if ( (ilen >= 64) || local_len) {
esp_sha_acquire_hardware();
if (ctx->sha_state == ESP_SHA1_STATE_INIT) {
ctx->first_block = true;
ctx->sha_state = ESP_SHA1_STATE_IN_PROCESS;
} else if (ctx->sha_state == ESP_SHA1_STATE_IN_PROCESS) {
esp_sha_write_digest_state(SHA1, ctx->state);
}
/* First process buffered block, if any */
if ( local_len ) {
esp_internal_sha1_block_process(ctx, ctx->buffer);
}
while ( ilen >= 64 ) {
esp_internal_sha1_block_process(ctx, input);
input += 64;
ilen -= 64;
}
esp_sha_read_digest_state(SHA1, ctx->state);
esp_sha_release_hardware();
}
if ( ilen > 0 ) {
memcpy( (void *) (ctx->buffer + left), input, ilen);
}
return 0;
}
static const unsigned char sha1_padding[64] = {
0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
/*
* SHA-1 final digest
*/
int mbedtls_sha1_finish( mbedtls_sha1_context *ctx, unsigned char output[20] )
{
int ret;
uint32_t last, padn;
uint32_t high, low;
unsigned char msglen[8];
high = ( ctx->total[0] >> 29 )
| ( ctx->total[1] << 3 );
low = ( ctx->total[0] << 3 );
PUT_UINT32_BE( high, msglen, 0 );
PUT_UINT32_BE( low, msglen, 4 );
last = ctx->total[0] & 0x3F;
padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
if ( ( ret = mbedtls_sha1_update( ctx, sha1_padding, padn ) ) != 0 ) {
return ret;
}
if ( ( ret = mbedtls_sha1_update( ctx, msglen, 8 ) ) != 0 ) {
return ret;
}
memcpy(output, ctx->state, 20);
return ret;
}
#endif /* MBEDTLS_SHA1_C && MBEDTLS_SHA1_ALT */

View File

@@ -0,0 +1,231 @@
/*
* SHA-256 implementation with hardware ESP support added.
*
* SPDX-FileCopyrightText: The Mbed TLS Contributors
*
* SPDX-License-Identifier: Apache-2.0
*
* SPDX-FileContributor: 2016-2022 Espressif Systems (Shanghai) CO LTD
*/
/*
* The SHA-256 Secure Hash Standard was published by NIST in 2002.
*
* http://csrc.nist.gov/publications/fips/fips180-2/fips180-2.pdf
*/
#include <mbedtls/build_info.h>
#if defined(MBEDTLS_SHA256_C) && defined(MBEDTLS_SHA256_ALT)
#include "mbedtls/sha256.h"
#include <string.h>
#include <assert.h>
#if defined(MBEDTLS_SELF_TEST)
#if defined(MBEDTLS_PLATFORM_C)
#include "mbedtls/platform.h"
#else
#include <stdio.h>
#define mbedtls_printf printf
#endif /* MBEDTLS_PLATFORM_C */
#endif /* MBEDTLS_SELF_TEST */
#include "sha/sha_block.h"
/* Implementation that should never be optimized out by the compiler */
static void mbedtls_zeroize( void *v, size_t n )
{
volatile unsigned char *p = v;
while ( n-- ) {
*p++ = 0;
}
}
/*
* 32-bit integer manipulation macros (big endian)
*/
#ifndef GET_UINT32_BE
#define GET_UINT32_BE(n,b,i) \
do { \
(n) = ( (uint32_t) (b)[(i) ] << 24 ) \
| ( (uint32_t) (b)[(i) + 1] << 16 ) \
| ( (uint32_t) (b)[(i) + 2] << 8 ) \
| ( (uint32_t) (b)[(i) + 3] ); \
} while( 0 )
#endif
#ifndef PUT_UINT32_BE
#define PUT_UINT32_BE(n,b,i) \
do { \
(b)[(i) ] = (unsigned char) ( (n) >> 24 ); \
(b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \
(b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \
(b)[(i) + 3] = (unsigned char) ( (n) ); \
} while( 0 )
#endif
void mbedtls_sha256_init( mbedtls_sha256_context *ctx )
{
assert(ctx != NULL);
memset( ctx, 0, sizeof( mbedtls_sha256_context ) );
}
void mbedtls_sha256_free( mbedtls_sha256_context *ctx )
{
if ( ctx == NULL ) {
return;
}
mbedtls_zeroize( ctx, sizeof( mbedtls_sha256_context ) );
}
void mbedtls_sha256_clone( mbedtls_sha256_context *dst,
const mbedtls_sha256_context *src )
{
*dst = *src;
}
/*
* SHA-256 context setup
*/
int mbedtls_sha256_starts( mbedtls_sha256_context *ctx, int is224 )
{
memset( ctx, 0, sizeof( mbedtls_sha256_context ) );
if ( is224 ) {
ctx->mode = SHA2_224;
} else {
ctx->mode = SHA2_256;
}
return 0;
}
static void esp_internal_sha256_block_process(mbedtls_sha256_context *ctx, const uint8_t *data)
{
esp_sha_block(ctx->mode, data, ctx->first_block);
if (ctx->first_block) {
ctx->first_block = false;
}
}
int mbedtls_internal_sha256_process( mbedtls_sha256_context *ctx, const unsigned char data[64] )
{
esp_sha_acquire_hardware();
esp_sha_block(ctx->mode, data, ctx->first_block);
esp_sha_release_hardware();
return 0;
}
/*
* SHA-256 process buffer
*/
int mbedtls_sha256_update( mbedtls_sha256_context *ctx, const unsigned char *input,
size_t ilen )
{
size_t fill;
uint32_t left, local_len = 0;
if ( ilen == 0 ) {
return 0;
}
left = ctx->total[0] & 0x3F;
fill = 64 - left;
ctx->total[0] += (uint32_t) ilen;
ctx->total[0] &= 0xFFFFFFFF;
if ( ctx->total[0] < (uint32_t) ilen ) {
ctx->total[1]++;
}
/* Check if any data pending from previous call to this API */
if ( left && ilen >= fill ) {
memcpy( (void *) (ctx->buffer + left), input, fill );
input += fill;
ilen -= fill;
left = 0;
local_len = 64;
}
if ( (ilen >= 64) || local_len) {
esp_sha_acquire_hardware();
if (ctx->sha_state == ESP_SHA256_STATE_INIT) {
ctx->first_block = true;
ctx->sha_state = ESP_SHA256_STATE_IN_PROCESS;
} else if (ctx->sha_state == ESP_SHA256_STATE_IN_PROCESS) {
esp_sha_write_digest_state(ctx->mode, ctx->state);
}
/* First process buffered block, if any */
if ( local_len ) {
esp_internal_sha256_block_process(ctx, ctx->buffer);
}
while ( ilen >= 64 ) {
esp_internal_sha256_block_process(ctx, input);
input += 64;
ilen -= 64;
}
esp_sha_read_digest_state(ctx->mode, ctx->state);
esp_sha_release_hardware();
}
if ( ilen > 0 ) {
memcpy( (void *) (ctx->buffer + left), input, ilen);
}
return 0;
}
static const unsigned char sha256_padding[64] = {
0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
/*
* SHA-256 final digest
*/
int mbedtls_sha256_finish( mbedtls_sha256_context *ctx, unsigned char *output )
{
int ret;
uint32_t last, padn;
uint32_t high, low;
unsigned char msglen[8];
high = ( ctx->total[0] >> 29 )
| ( ctx->total[1] << 3 );
low = ( ctx->total[0] << 3 );
PUT_UINT32_BE( high, msglen, 0 );
PUT_UINT32_BE( low, msglen, 4 );
last = ctx->total[0] & 0x3F;
padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
if ( ( ret = mbedtls_sha256_update( ctx, sha256_padding, padn ) ) != 0 ) {
return ret;
}
if ( ( ret = mbedtls_sha256_update( ctx, msglen, 8 ) ) != 0 ) {
return ret;
}
memcpy(output, ctx->state, 32);
return ret;
}
#endif /* MBEDTLS_SHA256_C && MBEDTLS_SHA256_ALT */

View File

@@ -0,0 +1,270 @@
/*
* SHA-512 implementation with hardware ESP support added.
*
* SPDX-FileCopyrightText: The Mbed TLS Contributors
*
* SPDX-License-Identifier: Apache-2.0
*
* SPDX-FileContributor: 2016-2022 Espressif Systems (Shanghai) CO LTD
*/
/*
* The SHA-512 Secure Hash Standard was published by NIST in 2002.
*
* http://csrc.nist.gov/publications/fips/fips180-2/fips180-2.pdf
*/
#include <mbedtls/build_info.h>
#if defined(MBEDTLS_SHA512_C) && defined(MBEDTLS_SHA512_ALT)
#include "mbedtls/sha512.h"
#if defined(_MSC_VER) || defined(__WATCOMC__)
#define UL64(x) x##ui64
#else
#define UL64(x) x##ULL
#endif
#include <string.h>
#include <assert.h>
#if defined(MBEDTLS_SELF_TEST)
#if defined(MBEDTLS_PLATFORM_C)
#include "mbedtls/platform.h"
#else
#include <stdio.h>
#define mbedtls_printf printf
#endif /* MBEDTLS_PLATFORM_C */
#endif /* MBEDTLS_SELF_TEST */
#include "sha/sha_block.h"
/* Implementation that should never be optimized out by the compiler */
static void mbedtls_zeroize( void *v, size_t n )
{
volatile unsigned char *p = v;
while ( n-- ) {
*p++ = 0;
}
}
/*
* 64-bit integer manipulation macros (big endian)
*/
#ifndef PUT_UINT64_BE
#define PUT_UINT64_BE(n,b,i) \
{ \
(b)[(i) ] = (unsigned char) ( (n) >> 56 ); \
(b)[(i) + 1] = (unsigned char) ( (n) >> 48 ); \
(b)[(i) + 2] = (unsigned char) ( (n) >> 40 ); \
(b)[(i) + 3] = (unsigned char) ( (n) >> 32 ); \
(b)[(i) + 4] = (unsigned char) ( (n) >> 24 ); \
(b)[(i) + 5] = (unsigned char) ( (n) >> 16 ); \
(b)[(i) + 6] = (unsigned char) ( (n) >> 8 ); \
(b)[(i) + 7] = (unsigned char) ( (n) ); \
}
#endif /* PUT_UINT64_BE */
void esp_sha512_set_mode(mbedtls_sha512_context *ctx, esp_sha_type type)
{
switch (type) {
case SHA2_384:
case SHA2_512224:
case SHA2_512256:
case SHA2_512T:
ctx->mode = type;
break;
default:
ctx->mode = SHA2_512;
break;
}
}
/* For SHA512/t mode the intial hash value will depend on t */
void esp_sha512_set_t( mbedtls_sha512_context *ctx, uint16_t t_val)
{
ctx->t_val = t_val;
}
void mbedtls_sha512_init( mbedtls_sha512_context *ctx )
{
assert(ctx != NULL);
memset( ctx, 0, sizeof( mbedtls_sha512_context ) );
}
void mbedtls_sha512_free( mbedtls_sha512_context *ctx )
{
if ( ctx == NULL ) {
return;
}
mbedtls_zeroize( ctx, sizeof( mbedtls_sha512_context ) );
}
void mbedtls_sha512_clone( mbedtls_sha512_context *dst,
const mbedtls_sha512_context *src )
{
memcpy(dst, src, sizeof(mbedtls_sha512_context));
}
/*
* SHA-512 context setup
*/
int mbedtls_sha512_starts( mbedtls_sha512_context *ctx, int is384 )
{
mbedtls_zeroize( ctx, sizeof( mbedtls_sha512_context ) );
if ( is384 ) {
ctx->mode = SHA2_384;
} else {
ctx->mode = SHA2_512;
}
return 0;
}
static int esp_internal_sha512_block_process(mbedtls_sha512_context *ctx,
const uint8_t *data, size_t len,
uint8_t *buf, size_t buf_len)
{
esp_sha_block(ctx->mode, data, ctx->first_block);
if (ctx->first_block) {
ctx->first_block = false;
}
}
int mbedtls_internal_sha512_process( mbedtls_sha512_context *ctx, const unsigned char data[128] )
{
esp_sha_acquire_hardware();
esp_sha_block(ctx->mode, data, ctx->first_block);
esp_sha_release_hardware();
return 0;
}
/*
* SHA-512 process buffer
*/
int mbedtls_sha512_update( mbedtls_sha512_context *ctx, const unsigned char *input,
size_t ilen )
{
int ret;
size_t fill;
unsigned int left, len, local_len = 0;
if ( ilen == 0 ) {
return 0;
}
left = (unsigned int) (ctx->total[0] & 0x7F);
fill = 128 - left;
ctx->total[0] += (uint64_t) ilen;
if ( ctx->total[0] < (uint64_t) ilen ) {
ctx->total[1]++;
}
if ( left && ilen >= fill ) {
memcpy( (void *) (ctx->buffer + left), input, fill );
input += fill;
ilen -= fill;
left = 0;
local_len = 128;
}
if ( len || local_len) {
esp_sha_acquire_hardware();
if (ctx->sha_state == ESP_SHA512_STATE_INIT) {
if (ctx->mode == SHA2_512T) {
esp_sha_512_t_init_hash(ctx->t_val);
ctx->first_block = false;
} else {
ctx->first_block = true;
}
ctx->sha_state = ESP_SHA512_STATE_IN_PROCESS;
} else if (ctx->sha_state == ESP_SHA512_STATE_IN_PROCESS) {
esp_sha_write_digest_state(ctx->mode, ctx->state);
}
/* First process buffered block, if any */
if ( local_len ) {
esp_internal_sha256_block_process(ctx, ctx->buffer);
}
while ( ilen >= 128 ) {
esp_internal_sha256_block_process(ctx, input);
input += 64;
ilen -= 64;
}
esp_sha_read_digest_state(ctx->mode, ctx->state);
esp_sha_release_hardware();
}
if ( ilen > 0 ) {
memcpy( (void *) (ctx->buffer + left), input, ilen);
}
return 0;
}
static const unsigned char sha512_padding[128] = {
0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
/*
* SHA-512 final digest
*/
int mbedtls_sha512_finish( mbedtls_sha512_context *ctx, unsigned char *output )
{
int ret;
size_t last, padn;
uint64_t high, low;
unsigned char msglen[16];
high = ( ctx->total[0] >> 61 )
| ( ctx->total[1] << 3 );
low = ( ctx->total[0] << 3 );
PUT_UINT64_BE( high, msglen, 0 );
PUT_UINT64_BE( low, msglen, 8 );
last = (size_t)( ctx->total[0] & 0x7F );
padn = ( last < 112 ) ? ( 112 - last ) : ( 240 - last );
if ( ( ret = mbedtls_sha512_update( ctx, sha512_padding, padn ) ) != 0 ) {
return ret;
}
if ( ( ret = mbedtls_sha512_update( ctx, msglen, 16 ) ) != 0 ) {
return ret;
}
if (ctx->mode == SHA2_384) {
memcpy(output, ctx->state, 48);
} else {
memcpy(output, ctx->state, 64);
}
return ret;
}
#endif /* MBEDTLS_SHA512_C && MBEDTLS_SHA512_ALT */

View File

@@ -0,0 +1,73 @@
/*
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <stddef.h>
#include <sys/lock.h>
#include "soc/soc_caps.h"
#include "soc/periph_defs.h"
#include "esp_private/periph_ctrl.h"
#include "sha/sha_block.h"
#include "hal/sha_hal.h"
static _lock_t s_sha_lock;
void esp_sha_write_digest_state(esp_sha_type sha_type, void *digest_state)
{
sha_hal_write_digest(sha_type, digest_state);
}
void esp_sha_read_digest_state(esp_sha_type sha_type, void *digest_state)
{
sha_hal_read_digest(sha_type, digest_state);
}
/* Return block size (in bytes) for a given SHA type */
inline static size_t block_length(esp_sha_type type)
{
switch (type) {
case SHA1:
case SHA2_224:
case SHA2_256:
return 64;
#if SOC_SHA_SUPPORT_SHA384
case SHA2_384:
#endif
#if SOC_SHA_SUPPORT_SHA512
case SHA2_512:
#endif
#if SOC_SHA_SUPPORT_SHA512_T
case SHA2_512224:
case SHA2_512256:
case SHA2_512T:
#endif
return 128;
default:
return 0;
}
}
/* Lock the SHA peripheral and then enable it */
void esp_sha_acquire_hardware()
{
_lock_acquire(&s_sha_lock); /* Released when releasing hw with esp_sha_release_hardware() */
periph_module_enable(PERIPH_SHA_MODULE);
}
/* Disable SHA peripheral block and then release it */
void esp_sha_release_hardware()
{
periph_module_disable(PERIPH_SHA_MODULE);
_lock_release(&s_sha_lock);
}
void esp_sha_block(esp_sha_type sha_type, const void *data_block, bool is_first_block)
{
sha_hal_hash_block(sha_type, data_block, block_length(sha_type) / 4, is_first_block);
}

View File

@@ -19,6 +19,8 @@
#include "sha/sha_parallel_engine.h" #include "sha/sha_parallel_engine.h"
#elif SOC_SHA_SUPPORT_DMA #elif SOC_SHA_SUPPORT_DMA
#include "sha/sha_dma.h" #include "sha/sha_dma.h"
#else
#include "sha/sha_block.h"
#endif #endif
static const char *TAG = "esp_sha"; static const char *TAG = "esp_sha";

View File

@@ -17,8 +17,6 @@
#include "freertos/semphr.h" #include "freertos/semphr.h"
#if !TEMPORARY_DISABLED_FOR_TARGETS(ESP32C2)
//IDF-5141
static SemaphoreHandle_t done_sem; static SemaphoreHandle_t done_sem;
static const unsigned char *one_hundred_bs = (unsigned char *) static const unsigned char *one_hundred_bs = (unsigned char *)
@@ -133,4 +131,3 @@ TEST_CASE("mbedtls AES/SHA multithreading", "[mbedtls]")
vSemaphoreDelete(done_sem); vSemaphoreDelete(done_sem);
} }
#endif //!TEMPORARY_DISABLED_FOR_TARGETS(ESP32C2)

View File

@@ -44,14 +44,10 @@ static const uint8_t sha256_thousand_as[32] = {
}; };
#if !TEMPORARY_DISABLED_FOR_TARGETS(ESP32C2)
//IDF-5141
static const uint8_t sha256_thousand_bs[32] = { static const uint8_t sha256_thousand_bs[32] = {
0xf6, 0xf1, 0x18, 0xe1, 0x20, 0xe5, 0x2b, 0xe0, 0xbd, 0x0c, 0xfd, 0xf2, 0x79, 0x4c, 0xd1, 0x2c, 0x07, 0x68, 0x6c, 0xc8, 0x71, 0x23, 0x5a, 0xc2, 0xf1, 0x14, 0x59, 0x37, 0x8e, 0x6d, 0x23, 0x5b 0xf6, 0xf1, 0x18, 0xe1, 0x20, 0xe5, 0x2b, 0xe0, 0xbd, 0x0c, 0xfd, 0xf2, 0x79, 0x4c, 0xd1, 0x2c, 0x07, 0x68, 0x6c, 0xc8, 0x71, 0x23, 0x5a, 0xc2, 0xf1, 0x14, 0x59, 0x37, 0x8e, 0x6d, 0x23, 0x5b
}; };
#endif //!TEMPORARY_DISABLED_FOR_TARGETS(ESP32C2)
static const uint8_t sha512_thousand_bs[64] = { static const uint8_t sha512_thousand_bs[64] = {
0xa6, 0x68, 0x68, 0xa3, 0x73, 0x53, 0x2a, 0x5c, 0xc3, 0x3f, 0xbf, 0x43, 0x4e, 0xba, 0x10, 0x86, 0xb3, 0x87, 0x09, 0xe9, 0x14, 0x3f, 0xbf, 0x37, 0x67, 0x8d, 0x43, 0xd9, 0x9b, 0x95, 0x08, 0xd5, 0x80, 0x2d, 0xbe, 0x9d, 0xe9, 0x1a, 0x54, 0xab, 0x9e, 0xbc, 0x8a, 0x08, 0xa0, 0x1a, 0x89, 0xd8, 0x72, 0x68, 0xdf, 0x52, 0x69, 0x7f, 0x1c, 0x70, 0xda, 0xe8, 0x3f, 0xe5, 0xae, 0x5a, 0xfc, 0x9d 0xa6, 0x68, 0x68, 0xa3, 0x73, 0x53, 0x2a, 0x5c, 0xc3, 0x3f, 0xbf, 0x43, 0x4e, 0xba, 0x10, 0x86, 0xb3, 0x87, 0x09, 0xe9, 0x14, 0x3f, 0xbf, 0x37, 0x67, 0x8d, 0x43, 0xd9, 0x9b, 0x95, 0x08, 0xd5, 0x80, 0x2d, 0xbe, 0x9d, 0xe9, 0x1a, 0x54, 0xab, 0x9e, 0xbc, 0x8a, 0x08, 0xa0, 0x1a, 0x89, 0xd8, 0x72, 0x68, 0xdf, 0x52, 0x69, 0x7f, 0x1c, 0x70, 0xda, 0xe8, 0x3f, 0xe5, 0xae, 0x5a, 0xfc, 0x9d
}; };
@@ -103,8 +99,6 @@ TEST_CASE("mbedtls SHA interleaving", "[mbedtls]")
#define SHA_TASK_STACK_SIZE (10*1024) #define SHA_TASK_STACK_SIZE (10*1024)
static SemaphoreHandle_t done_sem; static SemaphoreHandle_t done_sem;
#if !TEMPORARY_DISABLED_FOR_TARGETS(ESP32C2)
//IDF-5141
static void tskRunSHA1Test(void *pvParameters) static void tskRunSHA1Test(void *pvParameters)
{ {
mbedtls_sha1_context sha1_ctx; mbedtls_sha1_context sha1_ctx;
@@ -159,7 +153,6 @@ TEST_CASE("mbedtls SHA multithreading", "[mbedtls]")
} }
vSemaphoreDelete(done_sem); vSemaphoreDelete(done_sem);
} }
#endif //!TEMPORARY_DISABLED_FOR_TARGETS(ESP32C2)
void tskRunSHASelftests(void *param) void tskRunSHASelftests(void *param)
{ {
@@ -274,8 +267,6 @@ TEST_CASE("mbedtls SHA384 clone", "[mbedtls][")
} }
#if !TEMPORARY_DISABLED_FOR_TARGETS(ESP32C2)
//IDF-5141
TEST_CASE("mbedtls SHA256 clone", "[mbedtls]") TEST_CASE("mbedtls SHA256 clone", "[mbedtls]")
{ {
mbedtls_sha256_context ctx; mbedtls_sha256_context ctx;
@@ -351,8 +342,6 @@ TEST_CASE("mbedtls SHA session passed between tasks", "[mbedtls]")
TEST_ASSERT_EQUAL(0, param.ret); TEST_ASSERT_EQUAL(0, param.ret);
TEST_ASSERT_EQUAL_MEMORY_MESSAGE(sha256_thousand_as, param.result, 32, "SHA256 result from other task"); TEST_ASSERT_EQUAL_MEMORY_MESSAGE(sha256_thousand_as, param.result, 32, "SHA256 result from other task");
} }
#endif //!TEMPORARY_DISABLED_FOR_TARGETS(ESP32C2)
@@ -399,8 +388,7 @@ const uint8_t test_vector_digest[] = {
0x98, 0x5d, 0x36, 0xc0, 0xb7, 0xeb, 0x35, 0xe0, 0x98, 0x5d, 0x36, 0xc0, 0xb7, 0xeb, 0x35, 0xe0,
}; };
#if !TEMPORARY_DISABLED_FOR_TARGETS(ESP32C2)
//IDF-5141
TEST_CASE("mbedtls SHA, input in flash", "[mbedtls]") TEST_CASE("mbedtls SHA, input in flash", "[mbedtls]")
{ {
mbedtls_sha256_context sha256_ctx; mbedtls_sha256_context sha256_ctx;
@@ -415,7 +403,6 @@ TEST_CASE("mbedtls SHA, input in flash", "[mbedtls]")
TEST_ASSERT_EQUAL_MEMORY_MESSAGE(test_vector_digest, sha256, 32, "SHA256 calculation"); TEST_ASSERT_EQUAL_MEMORY_MESSAGE(test_vector_digest, sha256, 32, "SHA256 calculation");
} }
#endif //!TEMPORARY_DISABLED_FOR_TARGETS(ESP32C2)
/* Function are not implemented in SW */ /* Function are not implemented in SW */
#if CONFIG_MBEDTLS_HARDWARE_SHA && SOC_SHA_SUPPORT_SHA512_T #if CONFIG_MBEDTLS_HARDWARE_SHA && SOC_SHA_SUPPORT_SHA512_T

View File

@@ -89,8 +89,6 @@ TEST_CASE("Test esp_sha()", "[hw_crypto]")
#endif #endif
} }
#if !TEMPORARY_DISABLED_FOR_TARGETS(ESP32C2)
//IDF-5141
TEST_CASE("Test esp_sha() function with long input", "[hw_crypto]") TEST_CASE("Test esp_sha() function with long input", "[hw_crypto]")
{ {
const void* ptr; const void* ptr;
@@ -137,4 +135,3 @@ TEST_CASE("Test esp_sha() function with long input", "[hw_crypto]")
TEST_ASSERT_EQUAL_MEMORY_MESSAGE(sha512_espsha, sha512_mbedtls, sizeof(sha512_espsha), "SHA512 results should match"); TEST_ASSERT_EQUAL_MEMORY_MESSAGE(sha512_espsha, sha512_mbedtls, sizeof(sha512_espsha), "SHA512 results should match");
#endif #endif
} }
#endif //!TEMPORARY_DISABLED_FOR_TARGETS(ESP32C2)

View File

@@ -18,8 +18,6 @@
#include "ccomp_timer.h" #include "ccomp_timer.h"
#include "test_mbedtls_utils.h" #include "test_mbedtls_utils.h"
#if !TEMPORARY_DISABLED_FOR_TARGETS(ESP32C2)
//IDF-5141
TEST_CASE("mbedtls SHA performance", "[aes]") TEST_CASE("mbedtls SHA performance", "[aes]")
{ {
const unsigned CALLS = 256; const unsigned CALLS = 256;
@@ -62,4 +60,3 @@ TEST_CASE("mbedtls SHA performance", "[aes]")
TEST_PERFORMANCE_CCOMP_GREATER_THAN(SHA256_THROUGHPUT_MBSEC, "%.3fMB/sec", mb_sec); TEST_PERFORMANCE_CCOMP_GREATER_THAN(SHA256_THROUGHPUT_MBSEC, "%.3fMB/sec", mb_sec);
#endif #endif
} }
#endif //!TEMPORARY_DISABLED_FOR_TARGETS(ESP32C2)

View File

@@ -45,7 +45,7 @@ config SOC_EFUSE_CONSISTS_OF_ONE_KEY_BLOCK
config SOC_SHA_SUPPORTED config SOC_SHA_SUPPORTED
bool bool
default n default y
config SOC_ECC_SUPPORTED config SOC_ECC_SUPPORTED
bool bool
@@ -291,22 +291,10 @@ config SOC_RSA_MAX_BIT_LEN
int int
default 3072 default 3072
config SOC_SHA_DMA_MAX_BUFFER_SIZE
int
default 3968
config SOC_SHA_SUPPORT_DMA
bool
default y
config SOC_SHA_SUPPORT_RESUME config SOC_SHA_SUPPORT_RESUME
bool bool
default y default y
config SOC_SHA_GDMA
bool
default y
config SOC_SHA_SUPPORT_SHA1 config SOC_SHA_SUPPORT_SHA1
bool bool
default y default y

View File

@@ -36,7 +36,7 @@
#define SOC_EFUSE_KEY_PURPOSE_FIELD 0 #define SOC_EFUSE_KEY_PURPOSE_FIELD 0
#define SOC_EFUSE_CONSISTS_OF_ONE_KEY_BLOCK 1 #define SOC_EFUSE_CONSISTS_OF_ONE_KEY_BLOCK 1
#define SOC_SHA_SUPPORTED 0 // This will be enabled with IDF-3830 #define SOC_SHA_SUPPORTED 1
#define SOC_ECC_SUPPORTED 1 #define SOC_ECC_SUPPORTED 1
#define SOC_FLASH_ENC_SUPPORTED 1 #define SOC_FLASH_ENC_SUPPORTED 1
#define SOC_SECURE_BOOT_SUPPORTED 1 #define SOC_SECURE_BOOT_SUPPORTED 1
@@ -158,18 +158,9 @@
/*--------------------------- SHA CAPS ---------------------------------------*/ /*--------------------------- SHA CAPS ---------------------------------------*/
/* Max amount of bytes in a single DMA operation is 4095,
for SHA this means that the biggest safe amount of bytes is
31 blocks of 128 bytes = 3968
*/
#define SOC_SHA_DMA_MAX_BUFFER_SIZE (3968)
#define SOC_SHA_SUPPORT_DMA (1)
/* The SHA engine is able to resume hashing from a user */ /* The SHA engine is able to resume hashing from a user */
#define SOC_SHA_SUPPORT_RESUME (1) #define SOC_SHA_SUPPORT_RESUME (1)
/* Has a centralized DMA, which is shared with all peripherals */
#define SOC_SHA_GDMA (1)
/* Supported HW algorithms */ /* Supported HW algorithms */
#define SOC_SHA_SUPPORT_SHA1 (1) #define SOC_SHA_SUPPORT_SHA1 (1)