From f4c79687f800e37aff7a6b198d0d1058ecf58877 Mon Sep 17 00:00:00 2001 From: Marius Vikhammer Date: Fri, 24 Sep 2021 14:32:58 +0800 Subject: [PATCH] SHA: added hardware support for SHA on C2. --- components/esp-tls/test/test_esp_tls.c | 14 +- .../include/soc/esp32c2/esp_crypto_lock.h | 19 -- .../include/esp32c2/idf_performance_target.h | 11 +- components/mbedtls/CMakeLists.txt | 6 +- .../mbedtls/port/include/sha/sha_block.h | 113 ++++++++ components/mbedtls/port/include/sha1_alt.h | 2 +- components/mbedtls/port/include/sha256_alt.h | 2 +- components/mbedtls/port/include/sha512_alt.h | 2 +- components/mbedtls/port/sha/block/esp_sha1.c | 212 ++++++++++++++ .../mbedtls/port/sha/block/esp_sha256.c | 231 +++++++++++++++ .../mbedtls/port/sha/block/esp_sha512.c | 270 ++++++++++++++++++ components/mbedtls/port/sha/block/sha.c | 73 +++++ components/mbedtls/port/sha/esp_sha.c | 2 + .../mbedtls/test/test_aes_sha_parallel.c | 3 - components/mbedtls/test/test_mbedtls_sha.c | 15 +- components/mbedtls/test/test_sha.c | 3 - components/mbedtls/test/test_sha_perf.c | 3 - .../esp32c2/include/soc/Kconfig.soc_caps.in | 14 +- components/soc/esp32c2/include/soc/soc_caps.h | 11 +- 19 files changed, 921 insertions(+), 85 deletions(-) delete mode 100644 components/esp_hw_support/include/soc/esp32c2/esp_crypto_lock.h create mode 100644 components/mbedtls/port/include/sha/sha_block.h create mode 100644 components/mbedtls/port/sha/block/esp_sha1.c create mode 100644 components/mbedtls/port/sha/block/esp_sha256.c create mode 100644 components/mbedtls/port/sha/block/esp_sha512.c create mode 100644 components/mbedtls/port/sha/block/sha.c diff --git a/components/esp-tls/test/test_esp_tls.c b/components/esp-tls/test/test_esp_tls.c index f410df6ba8..a2cf344463 100644 --- a/components/esp-tls/test/test_esp_tls.c +++ b/components/esp-tls/test/test_esp_tls.c @@ -15,12 +15,11 @@ #include "sha/sha_parallel_engine.h" #elif SOC_SHA_SUPPORT_DMA #include "sha/sha_dma.h" +#else +#include "sha/sha_block.h" #endif #include "test_utils.h" -#if !TEMPORARY_DISABLED_FOR_TARGETS(ESP32C2) -//IDF-5044 - const char *test_cert_pem = "-----BEGIN CERTIFICATE-----\n"\ "MIICrDCCAZQCCQD88gCs5AFs/jANBgkqhkiG9w0BAQsFADAYMRYwFAYDVQQDDA1F\n"\ "U1AtVExTIFRlc3RzMB4XDTIxMDEwNzAxMTc1OVoXDTMxMDEwNTAxMTc1OVowGDEW\n"\ @@ -68,6 +67,11 @@ const char *test_key_pem = "-----BEGIN PRIVATE KEY-----\n"\ "Aogx44Fozd1t2hYcozPuZD4s\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) { @@ -80,7 +84,7 @@ static void test_leak_setup(const char *file, long line) // which is considered as leaked otherwise const uint8_t input_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(); } @@ -124,5 +128,3 @@ TEST_CASE("esp_tls_server session create delete", "[esp-tls][leaks=0]") esp_tls_server_session_delete(tls); } #endif - -#endif //!TEMPORARY_DISABLED_FOR_TARGETS(ESP32C2) diff --git a/components/esp_hw_support/include/soc/esp32c2/esp_crypto_lock.h b/components/esp_hw_support/include/soc/esp32c2/esp_crypto_lock.h deleted file mode 100644 index 0b39af1654..0000000000 --- a/components/esp_hw_support/include/soc/esp32c2/esp_crypto_lock.h +++ /dev/null @@ -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 diff --git a/components/idf_test/include/esp32c2/idf_performance_target.h b/components/idf_test/include/esp32c2/idf_performance_target.h index ef8752c70c..3a1c7910f8 100644 --- a/components/idf_test/include/esp32c2/idf_performance_target.h +++ b/components/idf_test/include/esp32c2/idf_performance_target.h @@ -6,17 +6,10 @@ #pragma once -#define IDF_PERFORMANCE_MIN_AES_CBC_THROUGHPUT_MBSEC 43 - // 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 -#define IDF_PERFORMANCE_MAX_TIME_SHA1_32KB 560 - -#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_TIME_SHA1_32KB 2500 #define IDF_PERFORMANCE_MAX_SPI_PER_TRANS_POLLING 20 #define IDF_PERFORMANCE_MAX_SPI_PER_TRANS_POLLING_NO_DMA 15 diff --git a/components/mbedtls/CMakeLists.txt b/components/mbedtls/CMakeLists.txt index 0105ada73f..b43fc52c04 100644 --- a/components/mbedtls/CMakeLists.txt +++ b/components/mbedtls/CMakeLists.txt @@ -137,8 +137,10 @@ target_sources(mbedtls PRIVATE ${mbedtls_target_sources}) if(CONFIG_SOC_SHA_SUPPORTED) if(CONFIG_SOC_SHA_SUPPORT_DMA) set(SHA_PERIPHERAL_TYPE "dma") - else() + elseif(CONFIG_SOC_SHA_SUPPORT_PARALLEL_ENG) set(SHA_PERIPHERAL_TYPE "parallel_engine") + else() + set(SHA_PERIPHERAL_TYPE "block") endif() endif() @@ -163,7 +165,6 @@ if(SHA_PERIPHERAL_TYPE STREQUAL "dma") endif() if(AES_PERIPHERAL_TYPE STREQUAL "dma") - if(NOT CONFIG_SOC_AES_GDMA) set(AES_DMA_SRCS "${COMPONENT_DIR}/port/aes/dma/esp_aes_crypto_dma_impl.c") else() @@ -175,6 +176,7 @@ if(AES_PERIPHERAL_TYPE STREQUAL "dma") target_sources(mbedcrypto PRIVATE "${AES_DMA_SRCS}") endif() + target_sources(mbedcrypto PRIVATE "${COMPONENT_DIR}/port/esp_hardware.c" "${COMPONENT_DIR}/port/esp_mem.c" "${COMPONENT_DIR}/port/esp_timing.c" diff --git a/components/mbedtls/port/include/sha/sha_block.h b/components/mbedtls/port/include/sha/sha_block.h new file mode 100644 index 0000000000..d1752e772e --- /dev/null +++ b/components/mbedtls/port/include/sha/sha_block.h @@ -0,0 +1,113 @@ +/* + * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#include + +#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 diff --git a/components/mbedtls/port/include/sha1_alt.h b/components/mbedtls/port/include/sha1_alt.h index f97c0e49b8..530eb5319c 100644 --- a/components/mbedtls/port/include/sha1_alt.h +++ b/components/mbedtls/port/include/sha1_alt.h @@ -50,7 +50,7 @@ typedef struct { esp_mbedtls_sha1_mode mode; } mbedtls_sha1_context; -#elif SOC_SHA_SUPPORT_DMA +#elif SOC_SHA_SUPPORT_DMA || SOC_SHA_SUPPORT_RESUME typedef enum { ESP_SHA1_STATE_INIT, diff --git a/components/mbedtls/port/include/sha256_alt.h b/components/mbedtls/port/include/sha256_alt.h index 5d3b6135c5..641f5e8930 100644 --- a/components/mbedtls/port/include/sha256_alt.h +++ b/components/mbedtls/port/include/sha256_alt.h @@ -50,7 +50,7 @@ typedef struct { esp_mbedtls_sha256_mode mode; } mbedtls_sha256_context; -#elif SOC_SHA_SUPPORT_DMA +#elif SOC_SHA_SUPPORT_DMA || SOC_SHA_SUPPORT_RESUME typedef enum { ESP_SHA256_STATE_INIT, ESP_SHA256_STATE_IN_PROCESS diff --git a/components/mbedtls/port/include/sha512_alt.h b/components/mbedtls/port/include/sha512_alt.h index 9472abceff..d0de4623e9 100644 --- a/components/mbedtls/port/include/sha512_alt.h +++ b/components/mbedtls/port/include/sha512_alt.h @@ -52,7 +52,7 @@ typedef struct { esp_mbedtls_sha512_mode mode; } mbedtls_sha512_context; -#elif SOC_SHA_SUPPORT_DMA +#elif SOC_SHA_SUPPORT_DMA || SOC_SHA_SUPPORT_RESUME typedef enum { ESP_SHA512_STATE_INIT, diff --git a/components/mbedtls/port/sha/block/esp_sha1.c b/components/mbedtls/port/sha/block/esp_sha1.c new file mode 100644 index 0000000000..2a0c55aec0 --- /dev/null +++ b/components/mbedtls/port/sha/block/esp_sha1.c @@ -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 + +#if defined(MBEDTLS_SHA1_C) && defined(MBEDTLS_SHA1_ALT) + +#include "mbedtls/sha1.h" + +#include +#include + +#if defined(MBEDTLS_SELF_TEST) +#if defined(MBEDTLS_PLATFORM_C) +#include "mbedtls/platform.h" +#else +#include +#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 */ diff --git a/components/mbedtls/port/sha/block/esp_sha256.c b/components/mbedtls/port/sha/block/esp_sha256.c new file mode 100644 index 0000000000..0b5f5f01bc --- /dev/null +++ b/components/mbedtls/port/sha/block/esp_sha256.c @@ -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 + +#if defined(MBEDTLS_SHA256_C) && defined(MBEDTLS_SHA256_ALT) + +#include "mbedtls/sha256.h" + +#include +#include + +#if defined(MBEDTLS_SELF_TEST) +#if defined(MBEDTLS_PLATFORM_C) +#include "mbedtls/platform.h" +#else +#include +#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 */ diff --git a/components/mbedtls/port/sha/block/esp_sha512.c b/components/mbedtls/port/sha/block/esp_sha512.c new file mode 100644 index 0000000000..b3245a2474 --- /dev/null +++ b/components/mbedtls/port/sha/block/esp_sha512.c @@ -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 + +#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 +#include + +#if defined(MBEDTLS_SELF_TEST) +#if defined(MBEDTLS_PLATFORM_C) +#include "mbedtls/platform.h" +#else +#include +#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 */ diff --git a/components/mbedtls/port/sha/block/sha.c b/components/mbedtls/port/sha/block/sha.c new file mode 100644 index 0000000000..9cffe5e89f --- /dev/null +++ b/components/mbedtls/port/sha/block/sha.c @@ -0,0 +1,73 @@ +/* + * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include +#include + +#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); +} diff --git a/components/mbedtls/port/sha/esp_sha.c b/components/mbedtls/port/sha/esp_sha.c index 00be97f0e1..4648e4afc2 100644 --- a/components/mbedtls/port/sha/esp_sha.c +++ b/components/mbedtls/port/sha/esp_sha.c @@ -19,6 +19,8 @@ #include "sha/sha_parallel_engine.h" #elif SOC_SHA_SUPPORT_DMA #include "sha/sha_dma.h" +#else +#include "sha/sha_block.h" #endif static const char *TAG = "esp_sha"; diff --git a/components/mbedtls/test/test_aes_sha_parallel.c b/components/mbedtls/test/test_aes_sha_parallel.c index a6ba18b687..ddbb5baffa 100644 --- a/components/mbedtls/test/test_aes_sha_parallel.c +++ b/components/mbedtls/test/test_aes_sha_parallel.c @@ -17,8 +17,6 @@ #include "freertos/semphr.h" -#if !TEMPORARY_DISABLED_FOR_TARGETS(ESP32C2) -//IDF-5141 static SemaphoreHandle_t done_sem; static const unsigned char *one_hundred_bs = (unsigned char *) @@ -133,4 +131,3 @@ TEST_CASE("mbedtls AES/SHA multithreading", "[mbedtls]") vSemaphoreDelete(done_sem); } -#endif //!TEMPORARY_DISABLED_FOR_TARGETS(ESP32C2) diff --git a/components/mbedtls/test/test_mbedtls_sha.c b/components/mbedtls/test/test_mbedtls_sha.c index a8081d39d1..aebc624c96 100644 --- a/components/mbedtls/test/test_mbedtls_sha.c +++ b/components/mbedtls/test/test_mbedtls_sha.c @@ -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] = { 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] = { 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) static SemaphoreHandle_t done_sem; -#if !TEMPORARY_DISABLED_FOR_TARGETS(ESP32C2) -//IDF-5141 static void tskRunSHA1Test(void *pvParameters) { mbedtls_sha1_context sha1_ctx; @@ -159,7 +153,6 @@ TEST_CASE("mbedtls SHA multithreading", "[mbedtls]") } vSemaphoreDelete(done_sem); } -#endif //!TEMPORARY_DISABLED_FOR_TARGETS(ESP32C2) 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]") { 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_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, }; -#if !TEMPORARY_DISABLED_FOR_TARGETS(ESP32C2) -//IDF-5141 + TEST_CASE("mbedtls SHA, input in flash", "[mbedtls]") { 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"); } -#endif //!TEMPORARY_DISABLED_FOR_TARGETS(ESP32C2) /* Function are not implemented in SW */ #if CONFIG_MBEDTLS_HARDWARE_SHA && SOC_SHA_SUPPORT_SHA512_T diff --git a/components/mbedtls/test/test_sha.c b/components/mbedtls/test/test_sha.c index 66ff02cfb9..c6a771f67c 100644 --- a/components/mbedtls/test/test_sha.c +++ b/components/mbedtls/test/test_sha.c @@ -89,8 +89,6 @@ TEST_CASE("Test esp_sha()", "[hw_crypto]") #endif } -#if !TEMPORARY_DISABLED_FOR_TARGETS(ESP32C2) -//IDF-5141 TEST_CASE("Test esp_sha() function with long input", "[hw_crypto]") { 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"); #endif } -#endif //!TEMPORARY_DISABLED_FOR_TARGETS(ESP32C2) diff --git a/components/mbedtls/test/test_sha_perf.c b/components/mbedtls/test/test_sha_perf.c index 3fe909b852..41101e712f 100644 --- a/components/mbedtls/test/test_sha_perf.c +++ b/components/mbedtls/test/test_sha_perf.c @@ -18,8 +18,6 @@ #include "ccomp_timer.h" #include "test_mbedtls_utils.h" -#if !TEMPORARY_DISABLED_FOR_TARGETS(ESP32C2) -//IDF-5141 TEST_CASE("mbedtls SHA performance", "[aes]") { 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); #endif } -#endif //!TEMPORARY_DISABLED_FOR_TARGETS(ESP32C2) diff --git a/components/soc/esp32c2/include/soc/Kconfig.soc_caps.in b/components/soc/esp32c2/include/soc/Kconfig.soc_caps.in index 782de0c75a..65e56677a8 100644 --- a/components/soc/esp32c2/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32c2/include/soc/Kconfig.soc_caps.in @@ -45,7 +45,7 @@ config SOC_EFUSE_CONSISTS_OF_ONE_KEY_BLOCK config SOC_SHA_SUPPORTED bool - default n + default y config SOC_ECC_SUPPORTED bool @@ -291,22 +291,10 @@ config SOC_RSA_MAX_BIT_LEN int 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 bool default y -config SOC_SHA_GDMA - bool - default y - config SOC_SHA_SUPPORT_SHA1 bool default y diff --git a/components/soc/esp32c2/include/soc/soc_caps.h b/components/soc/esp32c2/include/soc/soc_caps.h index c196611c0d..2dd859991b 100644 --- a/components/soc/esp32c2/include/soc/soc_caps.h +++ b/components/soc/esp32c2/include/soc/soc_caps.h @@ -36,7 +36,7 @@ #define SOC_EFUSE_KEY_PURPOSE_FIELD 0 #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_FLASH_ENC_SUPPORTED 1 #define SOC_SECURE_BOOT_SUPPORTED 1 @@ -158,18 +158,9 @@ /*--------------------------- 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 */ #define SOC_SHA_SUPPORT_RESUME (1) -/* Has a centralized DMA, which is shared with all peripherals */ -#define SOC_SHA_GDMA (1) /* Supported HW algorithms */ #define SOC_SHA_SUPPORT_SHA1 (1)