mirror of
https://github.com/espressif/esp-idf.git
synced 2024-10-05 20:47:46 -04:00
hw crypto: activated hardware acceleration for esp32s2beta
Activated AES, RSA and SHA hardware acceleration for esp32s2 and enabled related unit tests. Updated with changes made for ESP32 from0a04034
,961f59f
andcaea288
. Added performance targets for esp32s2beta Closes IDF-757
This commit is contained in:
parent
3b52eddf6b
commit
c63684cf6c
@ -62,8 +62,8 @@ TEST_CASE("Test esp_sha()", "[hw_crypto]")
|
||||
|
||||
free(buffer);
|
||||
|
||||
TEST_PERFORMANCE_LESS_THAN(ESP32_TIME_SHA1_32KB, "%dus", us_sha1);
|
||||
TEST_PERFORMANCE_LESS_THAN(ESP32_TIME_SHA512_32KB, "%dus", us_sha512);
|
||||
TEST_PERFORMANCE_LESS_THAN(TIME_SHA1_32KB, "%dus", us_sha1);
|
||||
TEST_PERFORMANCE_LESS_THAN(TIME_SHA512_32KB, "%dus", us_sha512);
|
||||
}
|
||||
|
||||
TEST_CASE("Test esp_sha() function with long input", "[hw_crypto]")
|
||||
|
108
components/esp32s2beta/test/test_sha.c
Normal file
108
components/esp32s2beta/test/test_sha.c
Normal file
@ -0,0 +1,108 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "esp_types.h"
|
||||
#include "esp32s2beta/clk.h"
|
||||
#include "esp_log.h"
|
||||
#include "esp_timer.h"
|
||||
#include "esp_heap_caps.h"
|
||||
#include "idf_performance.h"
|
||||
|
||||
#include "unity.h"
|
||||
#include "test_utils.h"
|
||||
#include "mbedtls/sha1.h"
|
||||
#include "mbedtls/sha256.h"
|
||||
#include "mbedtls/sha512.h"
|
||||
#include "esp32s2beta/sha.h"
|
||||
|
||||
/* Note: Most of the SHA functions are called as part of mbedTLS, so
|
||||
are tested as part of mbedTLS tests. Only esp_sha() is different.
|
||||
*/
|
||||
|
||||
#define TAG "sha_test"
|
||||
|
||||
TEST_CASE("Test esp_sha()", "[hw_crypto]")
|
||||
{
|
||||
const size_t BUFFER_SZ = 32 * 1024 + 6; // NB: not an exact multiple of SHA block size
|
||||
|
||||
int64_t begin, end;
|
||||
uint32_t us_sha1, us_sha512;
|
||||
uint8_t sha1_result[20] = { 0 };
|
||||
uint8_t sha512_result[64] = { 0 };
|
||||
void *buffer = heap_caps_malloc(BUFFER_SZ, MALLOC_CAP_8BIT|MALLOC_CAP_INTERNAL);
|
||||
TEST_ASSERT_NOT_NULL(buffer);
|
||||
memset(buffer, 0xEE, BUFFER_SZ);
|
||||
|
||||
const uint8_t sha1_expected[20] = { 0xc7, 0xbb, 0xd3, 0x74, 0xf2, 0xf6, 0x20, 0x86,
|
||||
0x61, 0xf4, 0x50, 0xd5, 0xf5, 0x18, 0x44, 0xcc,
|
||||
0x7a, 0xb7, 0xa5, 0x4a };
|
||||
const uint8_t sha512_expected[64] = { 0xc7, 0x7f, 0xda, 0x8c, 0xb3, 0x58, 0x14, 0x8a,
|
||||
0x52, 0x3b, 0x46, 0x04, 0xc0, 0x85, 0xc5, 0xf0,
|
||||
0x46, 0x64, 0x14, 0xd5, 0x96, 0x7a, 0xa2, 0x80,
|
||||
0x20, 0x9c, 0x04, 0x27, 0x7d, 0x3b, 0xf9, 0x1f,
|
||||
0xb2, 0xa3, 0x45, 0x3c, 0xa1, 0x6a, 0x8d, 0xdd,
|
||||
0x35, 0x5e, 0x35, 0x57, 0x76, 0x22, 0x74, 0xd8,
|
||||
0x1e, 0x07, 0xc6, 0xa2, 0x9e, 0x3b, 0x65, 0x75,
|
||||
0x80, 0x7d, 0xe6, 0x6e, 0x47, 0x61, 0x2c, 0x94 };
|
||||
|
||||
begin = esp_timer_get_time();
|
||||
esp_sha(SHA1, buffer, BUFFER_SZ, sha1_result);
|
||||
end = esp_timer_get_time();
|
||||
TEST_ASSERT_EQUAL_HEX8_ARRAY(sha1_expected, sha1_result, sizeof(sha1_expected));
|
||||
us_sha1 = end - begin;
|
||||
ESP_LOGI(TAG, "esp_sha() 32KB SHA1 in %u us", us_sha1);
|
||||
|
||||
begin = esp_timer_get_time();
|
||||
esp_sha(SHA2_512, buffer, BUFFER_SZ, sha512_result);
|
||||
end = esp_timer_get_time();
|
||||
TEST_ASSERT_EQUAL_HEX8_ARRAY(sha512_expected, sha512_result, sizeof(sha512_expected));
|
||||
|
||||
us_sha512 = end - begin;
|
||||
ESP_LOGI(TAG, "esp_sha() 32KB SHA512 in %u us", us_sha512);
|
||||
|
||||
free(buffer);
|
||||
|
||||
TEST_PERFORMANCE_LESS_THAN(TIME_SHA1_32KB, "%dus", us_sha1);
|
||||
TEST_PERFORMANCE_LESS_THAN(TIME_SHA512_32KB, "%dus", us_sha512);
|
||||
}
|
||||
|
||||
TEST_CASE("Test esp_sha() function with long input", "[hw_crypto]")
|
||||
{
|
||||
const void* ptr;
|
||||
spi_flash_mmap_handle_t handle;
|
||||
uint8_t sha1_espsha[20] = { 0 };
|
||||
uint8_t sha1_mbedtls[20] = { 0 };
|
||||
uint8_t sha256_espsha[32] = { 0 };
|
||||
uint8_t sha256_mbedtls[32] = { 0 };
|
||||
uint8_t sha512_espsha[64] = { 0 };
|
||||
uint8_t sha512_mbedtls[64] = { 0 };
|
||||
|
||||
const size_t LEN = 1024 * 1024;
|
||||
|
||||
/* mmap() 1MB of flash, we don't care what it is really */
|
||||
esp_err_t err = spi_flash_mmap(0x0, LEN, SPI_FLASH_MMAP_DATA, &ptr, &handle);
|
||||
|
||||
TEST_ASSERT_EQUAL_HEX32(ESP_OK, err);
|
||||
TEST_ASSERT_NOT_NULL(ptr);
|
||||
|
||||
/* Compare esp_sha() result to the mbedTLS result, should always be the same */
|
||||
|
||||
esp_sha(SHA1, ptr, LEN, sha1_espsha);
|
||||
int r = mbedtls_sha1_ret(ptr, LEN, sha1_mbedtls);
|
||||
TEST_ASSERT_EQUAL(0, r);
|
||||
|
||||
esp_sha(SHA2_256, ptr, LEN, sha256_espsha);
|
||||
r = mbedtls_sha256_ret(ptr, LEN, sha256_mbedtls, 0);
|
||||
TEST_ASSERT_EQUAL(0, r);
|
||||
|
||||
esp_sha(SHA2_512, ptr, LEN, sha512_espsha);
|
||||
r = mbedtls_sha512_ret(ptr, LEN, sha512_mbedtls, 0);
|
||||
TEST_ASSERT_EQUAL(0, r);
|
||||
|
||||
TEST_ASSERT_EQUAL_MEMORY_MESSAGE(sha1_espsha, sha1_mbedtls, sizeof(sha1_espsha), "SHA1 results should match");
|
||||
|
||||
TEST_ASSERT_EQUAL_MEMORY_MESSAGE(sha256_espsha, sha256_mbedtls, sizeof(sha256_espsha), "SHA256 results should match");
|
||||
|
||||
TEST_ASSERT_EQUAL_MEMORY_MESSAGE(sha512_espsha, sha512_mbedtls, sizeof(sha512_espsha), "SHA512 results should match");
|
||||
}
|
||||
|
@ -22,30 +22,50 @@
|
||||
// events dispatched per second by event loop library
|
||||
#define IDF_PERFORMANCE_MIN_EVENT_DISPATCH 25000
|
||||
#define IDF_PERFORMANCE_MIN_EVENT_DISPATCH_PSRAM 21000
|
||||
// esp_sha() time to process 32KB of input data from RAM
|
||||
#define IDF_PERFORMANCE_MAX_ESP32_TIME_SHA1_32KB 5000
|
||||
#define IDF_PERFORMANCE_MAX_ESP32_TIME_SHA512_32KB 4500
|
||||
|
||||
// floating point instructions per divide and per sqrt (configured for worst-case with PSRAM workaround)
|
||||
#define IDF_PERFORMANCE_MAX_ESP32_CYCLES_PER_DIV 70
|
||||
#define IDF_PERFORMANCE_MAX_ESP32_CYCLES_PER_SQRT 140
|
||||
|
||||
#define IDF_PERFORMANCE_MAX_SPILL_REG_CYCLES 150
|
||||
#define IDF_PERFORMANCE_MAX_ISR_ENTER_CYCLES 290
|
||||
#define IDF_PERFORMANCE_MAX_ISR_EXIT_CYCLES 565
|
||||
|
||||
#define IDF_PERFORMANCE_MIN_SDIO_THROUGHPUT_MBSEC_TOHOST_4BIT 13000
|
||||
#define IDF_PERFORMANCE_MIN_SDIO_THROUGHPUT_MBSEC_FRHOST_4BIT 13000
|
||||
#define IDF_PERFORMANCE_MIN_SDIO_THROUGHPUT_MBSEC_TOHOST_1BIT 4000
|
||||
#define IDF_PERFORMANCE_MIN_SDIO_THROUGHPUT_MBSEC_FRHOST_1BIT 4000
|
||||
#define IDF_PERFORMANCE_MIN_SDIO_THROUGHPUT_MBSEC_TOHOST_SPI 1000
|
||||
#define IDF_PERFORMANCE_MIN_SDIO_THROUGHPUT_MBSEC_FRHOST_SPI 1000
|
||||
|
||||
#ifdef CONFIG_IDF_TARGET_ESP32
|
||||
// AES-CBC hardware throughput (accounts for worst-case performance with PSRAM workaround)
|
||||
#define IDF_PERFORMANCE_MIN_AES_CBC_THROUGHPUT_MBSEC 8.2
|
||||
// floating point instructions per divide and per sqrt (configured for worst-case with PSRAM workaround)
|
||||
#define IDF_PERFORMANCE_MAX_ESP32_CYCLES_PER_DIV 70
|
||||
#define IDF_PERFORMANCE_MAX_ESP32_CYCLES_PER_SQRT 140
|
||||
|
||||
// SHA256 hardware throughput at 240MHz, threshold set lower than worst case
|
||||
#define IDF_PERFORMANCE_MIN_SHA256_THROUGHPUT_MBSEC 9.0
|
||||
#define IDF_PERFORMANCE_MAX_SPILL_REG_CYCLES 150
|
||||
#define IDF_PERFORMANCE_MAX_ISR_ENTER_CYCLES 290
|
||||
#define IDF_PERFORMANCE_MAX_ISR_EXIT_CYCLES 565
|
||||
// esp_sha() time to process 32KB of input data from RAM
|
||||
#define IDF_PERFORMANCE_MAX_TIME_SHA1_32KB 5000
|
||||
#define IDF_PERFORMANCE_MAX_TIME_SHA512_32KB 4500
|
||||
|
||||
#define IDF_PERFORMANCE_MAX_RSA_2048KEY_PUBLIC_OP 19000
|
||||
#define IDF_PERFORMANCE_MAX_RSA_2048KEY_PRIVATE_OP 180000
|
||||
#define IDF_PERFORMANCE_MAX_RSA_4096KEY_PUBLIC_OP 65000
|
||||
#define IDF_PERFORMANCE_MAX_RSA_4096KEY_PRIVATE_OP 850000
|
||||
|
||||
#define IDF_PERFORMANCE_MAX_RSA_2048KEY_PUBLIC_OP 19000
|
||||
#define IDF_PERFORMANCE_MAX_RSA_2048KEY_PRIVATE_OP 180000
|
||||
#define IDF_PERFORMANCE_MAX_RSA_4096KEY_PUBLIC_OP 65000
|
||||
#define IDF_PERFORMANCE_MAX_RSA_4096KEY_PRIVATE_OP 850000
|
||||
#elif defined CONFIG_IDF_TARGET_ESP32S2BETA
|
||||
#define IDF_PERFORMANCE_MIN_AES_CBC_THROUGHPUT_MBSEC 14.4
|
||||
|
||||
#define IDF_PERFORMANCE_MIN_SDIO_THROUGHPUT_MBSEC_TOHOST_4BIT 13000
|
||||
#define IDF_PERFORMANCE_MIN_SDIO_THROUGHPUT_MBSEC_FRHOST_4BIT 13000
|
||||
#define IDF_PERFORMANCE_MIN_SDIO_THROUGHPUT_MBSEC_TOHOST_1BIT 4000
|
||||
#define IDF_PERFORMANCE_MIN_SDIO_THROUGHPUT_MBSEC_FRHOST_1BIT 4000
|
||||
#define IDF_PERFORMANCE_MIN_SDIO_THROUGHPUT_MBSEC_TOHOST_SPI 1000
|
||||
#define IDF_PERFORMANCE_MIN_SDIO_THROUGHPUT_MBSEC_FRHOST_SPI 1000
|
||||
// SHA256 hardware throughput at 240MHz, threshold set lower than worst case
|
||||
#define IDF_PERFORMANCE_MIN_SHA256_THROUGHPUT_MBSEC 19.8
|
||||
// esp_sha() time to process 32KB of input data from RAM
|
||||
#define IDF_PERFORMANCE_MAX_TIME_SHA1_32KB 1000
|
||||
#define IDF_PERFORMANCE_MAX_TIME_SHA512_32KB 900
|
||||
|
||||
#define IDF_PERFORMANCE_MAX_RSA_2048KEY_PUBLIC_OP 14000
|
||||
#define IDF_PERFORMANCE_MAX_RSA_2048KEY_PRIVATE_OP 100000
|
||||
#define IDF_PERFORMANCE_MAX_RSA_4096KEY_PUBLIC_OP 60000
|
||||
#define IDF_PERFORMANCE_MAX_RSA_4096KEY_PRIVATE_OP 600000
|
||||
|
||||
#endif //CONFIG_IDF_TARGET_ESP32S2BETA
|
||||
|
||||
|
@ -131,8 +131,6 @@ menu "mbedTLS"
|
||||
|
||||
config MBEDTLS_HARDWARE_AES
|
||||
bool "Enable hardware AES acceleration"
|
||||
depends on IDF_TARGET_ESP32
|
||||
# ToDo: remove once hardware AES acceleration is supported on esp32s2
|
||||
default y
|
||||
help
|
||||
Enable hardware accelerated AES encryption & decryption.
|
||||
|
@ -39,6 +39,7 @@
|
||||
|
||||
#define AES_BLOCK_BYTES 16
|
||||
|
||||
|
||||
/* AES uses a spinlock mux not a lock as the underlying block operation
|
||||
only takes a small number of cycles, much less than using
|
||||
a mutex for this.
|
||||
@ -48,6 +49,11 @@
|
||||
*/
|
||||
static portMUX_TYPE aes_spinlock = portMUX_INITIALIZER_UNLOCKED;
|
||||
|
||||
static inline bool valid_key_length(const esp_aes_context *ctx)
|
||||
{
|
||||
return ctx->key_bytes == 128/8 || ctx->key_bytes == 192/8 || ctx->key_bytes == 256/8;
|
||||
}
|
||||
|
||||
void esp_aes_acquire_hardware( void )
|
||||
{
|
||||
/* newlib locks lazy initialize on ESP-IDF */
|
||||
@ -99,6 +105,7 @@ int esp_aes_setkey( esp_aes_context *ctx, const unsigned char *key,
|
||||
}
|
||||
ctx->key_bytes = keybits / 8;
|
||||
memcpy(ctx->key, key, ctx->key_bytes);
|
||||
ctx->key_in_hardware = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -113,22 +120,46 @@ static inline void esp_aes_setkey_hardware( esp_aes_context *ctx, int mode)
|
||||
const uint32_t MODE_DECRYPT_BIT = 4;
|
||||
unsigned mode_reg_base = (mode == ESP_AES_ENCRYPT) ? 0 : MODE_DECRYPT_BIT;
|
||||
|
||||
memcpy((uint32_t *)AES_KEY_BASE, ctx->key, ctx->key_bytes);
|
||||
ctx->key_in_hardware = 0;
|
||||
|
||||
for (int i = 0; i < ctx->key_bytes/4; ++i) {
|
||||
REG_WRITE(AES_KEY_BASE + i * 4, *(((uint32_t *)ctx->key) + i));
|
||||
ctx->key_in_hardware += 4;
|
||||
}
|
||||
|
||||
REG_WRITE(AES_MODE_REG, mode_reg_base + ((ctx->key_bytes / 8) - 2));
|
||||
|
||||
/* Fault injection check: all words of key data should have been written to hardware */
|
||||
if (ctx->key_in_hardware < 16
|
||||
|| ctx->key_in_hardware != ctx->key_bytes) {
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
/* Run a single 16 byte block of AES, using the hardware engine.
|
||||
*
|
||||
* Call only while holding esp_aes_acquire_hardware().
|
||||
*/
|
||||
static inline void esp_aes_block(const void *input, void *output)
|
||||
static inline int esp_aes_block(esp_aes_context *ctx, const void *input, void *output)
|
||||
{
|
||||
/* If no key is written to hardware yet, either the user hasn't called
|
||||
mbedtls_aes_setkey_enc/mbedtls_aes_setkey_dec - meaning we also don't
|
||||
know which mode to use - or a fault skipped the
|
||||
key write to hardware. Treat this as a fatal error and zero the output block.
|
||||
*/
|
||||
if (ctx->key_in_hardware != ctx->key_bytes) {
|
||||
bzero(output, 16);
|
||||
return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH;
|
||||
}
|
||||
|
||||
memcpy((void *)AES_TEXT_IN_BASE, input, AES_BLOCK_BYTES);
|
||||
|
||||
REG_WRITE(AES_TRIGGER_REG, 1);
|
||||
while (REG_READ(AES_STATE_REG) != 0) { }
|
||||
|
||||
memcpy(output, (void *)AES_TEXT_OUT_BASE, AES_BLOCK_BYTES);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -138,11 +169,17 @@ int esp_internal_aes_encrypt( esp_aes_context *ctx,
|
||||
const unsigned char input[16],
|
||||
unsigned char output[16] )
|
||||
{
|
||||
int r;
|
||||
|
||||
if (!valid_key_length(ctx)) {
|
||||
return MBEDTLS_ERR_AES_INVALID_KEY_LENGTH;
|
||||
}
|
||||
|
||||
esp_aes_acquire_hardware();
|
||||
esp_aes_setkey_hardware(ctx, ESP_AES_ENCRYPT);
|
||||
esp_aes_block(input, output);
|
||||
r = esp_aes_block(ctx, input, output);
|
||||
esp_aes_release_hardware();
|
||||
return 0;
|
||||
return r;
|
||||
}
|
||||
|
||||
void esp_aes_encrypt( esp_aes_context *ctx,
|
||||
@ -160,11 +197,17 @@ int esp_internal_aes_decrypt( esp_aes_context *ctx,
|
||||
const unsigned char input[16],
|
||||
unsigned char output[16] )
|
||||
{
|
||||
int r;
|
||||
|
||||
if (!valid_key_length(ctx)) {
|
||||
return MBEDTLS_ERR_AES_INVALID_KEY_LENGTH;
|
||||
}
|
||||
|
||||
esp_aes_acquire_hardware();
|
||||
esp_aes_setkey_hardware(ctx, ESP_AES_DECRYPT);
|
||||
esp_aes_block(input, output);
|
||||
r = esp_aes_block(ctx, input, output);
|
||||
esp_aes_release_hardware();
|
||||
return 0;
|
||||
return r;
|
||||
}
|
||||
|
||||
void esp_aes_decrypt( esp_aes_context *ctx,
|
||||
@ -183,12 +226,19 @@ int esp_aes_crypt_ecb( esp_aes_context *ctx,
|
||||
const unsigned char input[16],
|
||||
unsigned char output[16] )
|
||||
{
|
||||
int r;
|
||||
|
||||
if (!valid_key_length(ctx)) {
|
||||
return MBEDTLS_ERR_AES_INVALID_KEY_LENGTH;
|
||||
}
|
||||
|
||||
esp_aes_acquire_hardware();
|
||||
ctx->key_in_hardware = 0;
|
||||
esp_aes_setkey_hardware(ctx, mode);
|
||||
esp_aes_block(input, output);
|
||||
r = esp_aes_block(ctx, input, output);
|
||||
esp_aes_release_hardware();
|
||||
|
||||
return 0;
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
@ -211,15 +261,18 @@ int esp_aes_crypt_cbc( esp_aes_context *ctx,
|
||||
if ( length % 16 ) {
|
||||
return ( ERR_ESP_AES_INVALID_INPUT_LENGTH );
|
||||
}
|
||||
if (!valid_key_length(ctx)) {
|
||||
return MBEDTLS_ERR_AES_INVALID_KEY_LENGTH;
|
||||
}
|
||||
|
||||
esp_aes_acquire_hardware();
|
||||
|
||||
ctx->key_in_hardware = 0;
|
||||
esp_aes_setkey_hardware(ctx, mode);
|
||||
|
||||
if ( mode == ESP_AES_DECRYPT ) {
|
||||
while ( length > 0 ) {
|
||||
memcpy(temp, input_words, 16);
|
||||
esp_aes_block(input_words, output_words);
|
||||
esp_aes_block(ctx, input_words, output_words);
|
||||
|
||||
for ( i = 0; i < 4; i++ ) {
|
||||
output_words[i] = output_words[i] ^ iv_words[i];
|
||||
@ -238,7 +291,7 @@ int esp_aes_crypt_cbc( esp_aes_context *ctx,
|
||||
output_words[i] = input_words[i] ^ iv_words[i];
|
||||
}
|
||||
|
||||
esp_aes_block(output_words, output_words);
|
||||
esp_aes_block(ctx, output_words, output_words);
|
||||
memcpy( iv_words, output_words, 16 );
|
||||
|
||||
input_words += 4;
|
||||
@ -266,14 +319,19 @@ int esp_aes_crypt_cfb128( esp_aes_context *ctx,
|
||||
int c;
|
||||
size_t n = *iv_off;
|
||||
|
||||
if (!valid_key_length(ctx)) {
|
||||
return MBEDTLS_ERR_AES_INVALID_KEY_LENGTH;
|
||||
}
|
||||
|
||||
esp_aes_acquire_hardware();
|
||||
ctx->key_in_hardware = 0;
|
||||
|
||||
esp_aes_setkey_hardware(ctx, ESP_AES_ENCRYPT);
|
||||
|
||||
if ( mode == ESP_AES_DECRYPT ) {
|
||||
while ( length-- ) {
|
||||
if ( n == 0 ) {
|
||||
esp_aes_block(iv, iv );
|
||||
esp_aes_block(ctx, iv, iv );
|
||||
}
|
||||
|
||||
c = *input++;
|
||||
@ -285,7 +343,7 @@ int esp_aes_crypt_cfb128( esp_aes_context *ctx,
|
||||
} else {
|
||||
while ( length-- ) {
|
||||
if ( n == 0 ) {
|
||||
esp_aes_block(iv, iv );
|
||||
esp_aes_block(ctx, iv, iv );
|
||||
}
|
||||
|
||||
iv[n] = *output++ = (unsigned char)( iv[n] ^ *input++ );
|
||||
@ -314,13 +372,18 @@ int esp_aes_crypt_cfb8( esp_aes_context *ctx,
|
||||
unsigned char c;
|
||||
unsigned char ov[17];
|
||||
|
||||
if (!valid_key_length(ctx)) {
|
||||
return MBEDTLS_ERR_AES_INVALID_KEY_LENGTH;
|
||||
}
|
||||
|
||||
esp_aes_acquire_hardware();
|
||||
ctx->key_in_hardware = 0;
|
||||
|
||||
esp_aes_setkey_hardware(ctx, ESP_AES_ENCRYPT);
|
||||
|
||||
while ( length-- ) {
|
||||
memcpy( ov, iv, 16 );
|
||||
esp_aes_block(iv, iv);
|
||||
esp_aes_block(ctx, iv, iv);
|
||||
|
||||
if ( mode == ESP_AES_DECRYPT ) {
|
||||
ov[16] = *input;
|
||||
@ -354,13 +417,18 @@ int esp_aes_crypt_ctr( esp_aes_context *ctx,
|
||||
int c, i;
|
||||
size_t n = *nc_off;
|
||||
|
||||
if (!valid_key_length(ctx)) {
|
||||
return MBEDTLS_ERR_AES_INVALID_KEY_LENGTH;
|
||||
}
|
||||
|
||||
esp_aes_acquire_hardware();
|
||||
ctx->key_in_hardware = 0;
|
||||
|
||||
esp_aes_setkey_hardware(ctx, ESP_AES_ENCRYPT);
|
||||
|
||||
while ( length-- ) {
|
||||
if ( n == 0 ) {
|
||||
esp_aes_block(nonce_counter, stream_block);
|
||||
esp_aes_block(ctx, nonce_counter, stream_block);
|
||||
|
||||
for ( i = 16; i > 0; i-- )
|
||||
if ( ++nonce_counter[i - 1] != 0 ) {
|
||||
@ -379,3 +447,296 @@ int esp_aes_crypt_ctr( esp_aes_context *ctx,
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* AES-OFB (Output Feedback Mode) buffer encryption/decryption
|
||||
*/
|
||||
int esp_aes_crypt_ofb( esp_aes_context *ctx,
|
||||
size_t length,
|
||||
size_t *iv_off,
|
||||
unsigned char iv[16],
|
||||
const unsigned char *input,
|
||||
unsigned char *output )
|
||||
{
|
||||
int ret = 0;
|
||||
size_t n;
|
||||
|
||||
if ( ctx == NULL || iv_off == NULL || iv == NULL ||
|
||||
input == NULL || output == NULL ) {
|
||||
return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
|
||||
}
|
||||
|
||||
n = *iv_off;
|
||||
|
||||
if( n > 15 ) {
|
||||
return( MBEDTLS_ERR_AES_BAD_INPUT_DATA );
|
||||
}
|
||||
|
||||
if (!valid_key_length(ctx)) {
|
||||
return MBEDTLS_ERR_AES_INVALID_KEY_LENGTH;
|
||||
}
|
||||
|
||||
esp_aes_acquire_hardware();
|
||||
ctx->key_in_hardware = 0;
|
||||
|
||||
esp_aes_setkey_hardware(ctx, ESP_AES_ENCRYPT);
|
||||
|
||||
while( length-- ) {
|
||||
if( n == 0 ) {
|
||||
esp_aes_block(ctx, iv, iv);
|
||||
}
|
||||
*output++ = *input++ ^ iv[n];
|
||||
|
||||
n = ( n + 1 ) & 0x0F;
|
||||
}
|
||||
|
||||
*iv_off = n;
|
||||
|
||||
esp_aes_release_hardware();
|
||||
|
||||
return( ret );
|
||||
}
|
||||
|
||||
|
||||
/* Below XTS implementation is copied aes.c of mbedtls library.
|
||||
* When MBEDTLS_AES_ALT is defined mbedtls expects alternate
|
||||
* definition of XTS functions to be available. Even if this
|
||||
* could have been avoided, it is done for consistency reason.
|
||||
*/
|
||||
|
||||
void esp_aes_xts_init( esp_aes_xts_context *ctx )
|
||||
{
|
||||
esp_aes_init( &ctx->crypt );
|
||||
esp_aes_init( &ctx->tweak );
|
||||
}
|
||||
|
||||
void esp_aes_xts_free( esp_aes_xts_context *ctx )
|
||||
{
|
||||
esp_aes_free( &ctx->crypt );
|
||||
esp_aes_free( &ctx->tweak );
|
||||
}
|
||||
|
||||
static int esp_aes_xts_decode_keys( const unsigned char *key,
|
||||
unsigned int keybits,
|
||||
const unsigned char **key1,
|
||||
unsigned int *key1bits,
|
||||
const unsigned char **key2,
|
||||
unsigned int *key2bits )
|
||||
{
|
||||
const unsigned int half_keybits = keybits / 2;
|
||||
const unsigned int half_keybytes = half_keybits / 8;
|
||||
|
||||
switch( keybits )
|
||||
{
|
||||
case 256: break;
|
||||
case 512: break;
|
||||
default : return( MBEDTLS_ERR_AES_INVALID_KEY_LENGTH );
|
||||
}
|
||||
|
||||
*key1bits = half_keybits;
|
||||
*key2bits = half_keybits;
|
||||
*key1 = &key[0];
|
||||
*key2 = &key[half_keybytes];
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int esp_aes_xts_setkey_enc( esp_aes_xts_context *ctx,
|
||||
const unsigned char *key,
|
||||
unsigned int keybits)
|
||||
{
|
||||
int ret;
|
||||
const unsigned char *key1, *key2;
|
||||
unsigned int key1bits, key2bits;
|
||||
|
||||
ret = esp_aes_xts_decode_keys( key, keybits, &key1, &key1bits,
|
||||
&key2, &key2bits );
|
||||
if( ret != 0 )
|
||||
return( ret );
|
||||
|
||||
/* Set the tweak key. Always set tweak key for the encryption mode. */
|
||||
ret = esp_aes_setkey( &ctx->tweak, key2, key2bits );
|
||||
if( ret != 0 )
|
||||
return( ret );
|
||||
|
||||
/* Set crypt key for encryption. */
|
||||
return esp_aes_setkey( &ctx->crypt, key1, key1bits );
|
||||
}
|
||||
|
||||
int esp_aes_xts_setkey_dec( esp_aes_xts_context *ctx,
|
||||
const unsigned char *key,
|
||||
unsigned int keybits)
|
||||
{
|
||||
int ret;
|
||||
const unsigned char *key1, *key2;
|
||||
unsigned int key1bits, key2bits;
|
||||
|
||||
ret = esp_aes_xts_decode_keys( key, keybits, &key1, &key1bits,
|
||||
&key2, &key2bits );
|
||||
if( ret != 0 )
|
||||
return( ret );
|
||||
|
||||
/* Set the tweak key. Always set tweak key for encryption. */
|
||||
ret = esp_aes_setkey( &ctx->tweak, key2, key2bits );
|
||||
if( ret != 0 )
|
||||
return( ret );
|
||||
|
||||
/* Set crypt key for decryption. */
|
||||
return esp_aes_setkey( &ctx->crypt, key1, key1bits );
|
||||
}
|
||||
|
||||
/* Endianess with 64 bits values */
|
||||
#ifndef GET_UINT64_LE
|
||||
#define GET_UINT64_LE(n,b,i) \
|
||||
{ \
|
||||
(n) = ( (uint64_t) (b)[(i) + 7] << 56 ) \
|
||||
| ( (uint64_t) (b)[(i) + 6] << 48 ) \
|
||||
| ( (uint64_t) (b)[(i) + 5] << 40 ) \
|
||||
| ( (uint64_t) (b)[(i) + 4] << 32 ) \
|
||||
| ( (uint64_t) (b)[(i) + 3] << 24 ) \
|
||||
| ( (uint64_t) (b)[(i) + 2] << 16 ) \
|
||||
| ( (uint64_t) (b)[(i) + 1] << 8 ) \
|
||||
| ( (uint64_t) (b)[(i) ] ); \
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef PUT_UINT64_LE
|
||||
#define PUT_UINT64_LE(n,b,i) \
|
||||
{ \
|
||||
(b)[(i) + 7] = (unsigned char) ( (n) >> 56 ); \
|
||||
(b)[(i) + 6] = (unsigned char) ( (n) >> 48 ); \
|
||||
(b)[(i) + 5] = (unsigned char) ( (n) >> 40 ); \
|
||||
(b)[(i) + 4] = (unsigned char) ( (n) >> 32 ); \
|
||||
(b)[(i) + 3] = (unsigned char) ( (n) >> 24 ); \
|
||||
(b)[(i) + 2] = (unsigned char) ( (n) >> 16 ); \
|
||||
(b)[(i) + 1] = (unsigned char) ( (n) >> 8 ); \
|
||||
(b)[(i) ] = (unsigned char) ( (n) ); \
|
||||
}
|
||||
#endif
|
||||
|
||||
typedef unsigned char esp_be128[16];
|
||||
|
||||
/*
|
||||
* GF(2^128) multiplication function
|
||||
*
|
||||
* This function multiplies a field element by x in the polynomial field
|
||||
* representation. It uses 64-bit word operations to gain speed but compensates
|
||||
* for machine endianess and hence works correctly on both big and little
|
||||
* endian machines.
|
||||
*/
|
||||
static void esp_gf128mul_x_ble( unsigned char r[16],
|
||||
const unsigned char x[16] )
|
||||
{
|
||||
uint64_t a, b, ra, rb;
|
||||
|
||||
GET_UINT64_LE( a, x, 0 );
|
||||
GET_UINT64_LE( b, x, 8 );
|
||||
|
||||
ra = ( a << 1 ) ^ 0x0087 >> ( 8 - ( ( b >> 63 ) << 3 ) );
|
||||
rb = ( a >> 63 ) | ( b << 1 );
|
||||
|
||||
PUT_UINT64_LE( ra, r, 0 );
|
||||
PUT_UINT64_LE( rb, r, 8 );
|
||||
}
|
||||
|
||||
/*
|
||||
* AES-XTS buffer encryption/decryption
|
||||
*/
|
||||
int esp_aes_crypt_xts( esp_aes_xts_context *ctx,
|
||||
int mode,
|
||||
size_t length,
|
||||
const unsigned char data_unit[16],
|
||||
const unsigned char *input,
|
||||
unsigned char *output )
|
||||
{
|
||||
int ret;
|
||||
size_t blocks = length / 16;
|
||||
size_t leftover = length % 16;
|
||||
unsigned char tweak[16];
|
||||
unsigned char prev_tweak[16];
|
||||
unsigned char tmp[16];
|
||||
|
||||
/* Sectors must be at least 16 bytes. */
|
||||
if( length < 16 )
|
||||
return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH;
|
||||
|
||||
/* NIST SP 80-38E disallows data units larger than 2**20 blocks. */
|
||||
if( length > ( 1 << 20 ) * 16 )
|
||||
return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH;
|
||||
|
||||
/* Compute the tweak. */
|
||||
ret = esp_aes_crypt_ecb( &ctx->tweak, MBEDTLS_AES_ENCRYPT,
|
||||
data_unit, tweak );
|
||||
if( ret != 0 )
|
||||
return( ret );
|
||||
|
||||
while( blocks-- )
|
||||
{
|
||||
size_t i;
|
||||
|
||||
if( leftover && ( mode == MBEDTLS_AES_DECRYPT ) && blocks == 0 )
|
||||
{
|
||||
/* We are on the last block in a decrypt operation that has
|
||||
* leftover bytes, so we need to use the next tweak for this block,
|
||||
* and this tweak for the lefover bytes. Save the current tweak for
|
||||
* the leftovers and then update the current tweak for use on this,
|
||||
* the last full block. */
|
||||
memcpy( prev_tweak, tweak, sizeof( tweak ) );
|
||||
esp_gf128mul_x_ble( tweak, tweak );
|
||||
}
|
||||
|
||||
for( i = 0; i < 16; i++ )
|
||||
tmp[i] = input[i] ^ tweak[i];
|
||||
|
||||
ret = esp_aes_crypt_ecb( &ctx->crypt, mode, tmp, tmp );
|
||||
if( ret != 0 )
|
||||
return( ret );
|
||||
|
||||
for( i = 0; i < 16; i++ )
|
||||
output[i] = tmp[i] ^ tweak[i];
|
||||
|
||||
/* Update the tweak for the next block. */
|
||||
esp_gf128mul_x_ble( tweak, tweak );
|
||||
|
||||
output += 16;
|
||||
input += 16;
|
||||
}
|
||||
|
||||
if( leftover )
|
||||
{
|
||||
/* If we are on the leftover bytes in a decrypt operation, we need to
|
||||
* use the previous tweak for these bytes (as saved in prev_tweak). */
|
||||
unsigned char *t = mode == MBEDTLS_AES_DECRYPT ? prev_tweak : tweak;
|
||||
|
||||
/* We are now on the final part of the data unit, which doesn't divide
|
||||
* evenly by 16. It's time for ciphertext stealing. */
|
||||
size_t i;
|
||||
unsigned char *prev_output = output - 16;
|
||||
|
||||
/* Copy ciphertext bytes from the previous block to our output for each
|
||||
* byte of cyphertext we won't steal. At the same time, copy the
|
||||
* remainder of the input for this final round (since the loop bounds
|
||||
* are the same). */
|
||||
for( i = 0; i < leftover; i++ )
|
||||
{
|
||||
output[i] = prev_output[i];
|
||||
tmp[i] = input[i] ^ t[i];
|
||||
}
|
||||
|
||||
/* Copy ciphertext bytes from the previous block for input in this
|
||||
* round. */
|
||||
for( ; i < 16; i++ )
|
||||
tmp[i] = prev_output[i] ^ t[i];
|
||||
|
||||
ret = esp_aes_crypt_ecb( &ctx->crypt, mode, tmp, tmp );
|
||||
if( ret != 0 )
|
||||
return ret;
|
||||
|
||||
/* Write the result back to the previous block, overriding the previous
|
||||
* output we copied. */
|
||||
for( i = 0; i < 16; i++ )
|
||||
prev_output[i] = tmp[i] ^ t[i];
|
||||
}
|
||||
|
||||
return( 0 );
|
||||
}
|
@ -48,28 +48,6 @@ static const __attribute__((unused)) char *TAG = "bignum";
|
||||
#define ciL (sizeof(mbedtls_mpi_uint)) /* chars in limb */
|
||||
#define biL (ciL << 3) /* bits in limb */
|
||||
|
||||
#if defined(CONFIG_MBEDTLS_MPI_USE_INTERRUPT)
|
||||
static SemaphoreHandle_t op_complete_sem;
|
||||
|
||||
static IRAM_ATTR void rsa_complete_isr(void *arg)
|
||||
{
|
||||
BaseType_t higher_woken;
|
||||
DPORT_REG_WRITE(RSA_CLEAR_INTERRUPT_REG, 1);
|
||||
xSemaphoreGiveFromISR(op_complete_sem, &higher_woken);
|
||||
if (higher_woken) {
|
||||
portYIELD_FROM_ISR();
|
||||
}
|
||||
}
|
||||
|
||||
static void rsa_isr_initialise(void)
|
||||
{
|
||||
if (op_complete_sem == NULL) {
|
||||
op_complete_sem = xSemaphoreCreateBinary();
|
||||
esp_intr_alloc(ETS_RSA_INTR_SOURCE, 0, rsa_complete_isr, NULL, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* CONFIG_MBEDTLS_MPI_USE_INTERRUPT */
|
||||
|
||||
static _lock_t mpi_lock;
|
||||
|
||||
@ -89,10 +67,6 @@ void esp_mpi_acquire_hardware( void )
|
||||
while(DPORT_REG_READ(RSA_QUERY_CLEAN_REG) != 1) {
|
||||
}
|
||||
// Note: from enabling RSA clock to here takes about 1.3us
|
||||
|
||||
#ifdef CONFIG_MBEDTLS_MPI_USE_INTERRUPT
|
||||
rsa_isr_initialise();
|
||||
#endif
|
||||
}
|
||||
|
||||
void esp_mpi_release_hardware( void )
|
||||
@ -106,6 +80,13 @@ void esp_mpi_release_hardware( void )
|
||||
_lock_release(&mpi_lock);
|
||||
}
|
||||
|
||||
/* Convert bit count to word count
|
||||
*/
|
||||
static inline size_t bits_to_words(size_t bits)
|
||||
{
|
||||
return (bits + 31) / 32;
|
||||
}
|
||||
|
||||
|
||||
/* Return the number of words actually used to represent an mpi
|
||||
number.
|
||||
@ -124,9 +105,6 @@ static size_t mpi_words(const mbedtls_mpi *mpi)
|
||||
|
||||
If num_words is higher than the number of words in the bignum then
|
||||
these additional words will be zeroed in the memory buffer.
|
||||
|
||||
As this function only writes to DPORT memory, no DPORT_STALL_OTHER_CPU_START()
|
||||
is required.
|
||||
*/
|
||||
static inline void mpi_to_mem_block(uint32_t mem_base, const mbedtls_mpi *mpi, size_t num_words)
|
||||
{
|
||||
@ -152,7 +130,6 @@ static inline void mpi_to_mem_block(uint32_t mem_base, const mbedtls_mpi *mpi, s
|
||||
|
||||
Can return a failure result if fails to grow the MPI result.
|
||||
|
||||
Cannot be called inside DPORT_STALL_OTHER_CPU_START() (as may allocate memory).
|
||||
*/
|
||||
static inline int mem_block_to_mpi(mbedtls_mpi *x, uint32_t mem_base, int num_words)
|
||||
{
|
||||
@ -231,9 +208,6 @@ static int calculate_rinv(mbedtls_mpi *Rinv, const mbedtls_mpi *M, int num_words
|
||||
|
||||
/* Begin an RSA operation. op_reg specifies which 'START' register
|
||||
to write to.
|
||||
|
||||
Because the only DPORT operations here are writes,
|
||||
does not need protecting via DPORT_STALL_OTHER_CPU_START();
|
||||
*/
|
||||
static inline void start_op(uint32_t op_reg)
|
||||
{
|
||||
@ -247,26 +221,14 @@ static inline void start_op(uint32_t op_reg)
|
||||
}
|
||||
|
||||
/* Wait for an RSA operation to complete.
|
||||
|
||||
This should NOT be called inside a DPORT_STALL_OTHER_CPU_START(), as it will stall the other CPU for an unacceptably long
|
||||
period (and - depending on config - may require interrupts enabled).
|
||||
*/
|
||||
static inline void wait_op_complete(uint32_t op_reg)
|
||||
{
|
||||
#ifdef CONFIG_MBEDTLS_MPI_USE_INTERRUPT
|
||||
if (!xSemaphoreTake(op_complete_sem, 2000 / portTICK_PERIOD_MS)) {
|
||||
ESP_LOGE(TAG, "Timed out waiting for RSA operation (op_reg 0x%x int_reg 0x%x)",
|
||||
op_reg, DPORT_REG_READ(RSA_QUERY_INTERRUPT_REG));
|
||||
abort(); /* indicates a fundamental problem with driver */
|
||||
}
|
||||
#else
|
||||
while(DPORT_REG_READ(RSA_QUERY_INTERRUPT_REG) != 1)
|
||||
{ }
|
||||
|
||||
/* clear the interrupt */
|
||||
DPORT_REG_WRITE(RSA_CLEAR_INTERRUPT_REG, 1);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
/* Z = (X * Y) mod M
|
||||
@ -275,12 +237,16 @@ static inline void wait_op_complete(uint32_t op_reg)
|
||||
*/
|
||||
int esp_mpi_mul_mpi_mod(mbedtls_mpi *Z, const mbedtls_mpi *X, const mbedtls_mpi *Y, const mbedtls_mpi *M)
|
||||
{
|
||||
|
||||
int ret;
|
||||
size_t y_bits = mbedtls_mpi_bitlen(Y);
|
||||
size_t x_words = mpi_words(X);
|
||||
size_t y_words = mpi_words(Y);
|
||||
size_t m_words = mpi_words(M);
|
||||
mbedtls_mpi Rinv;
|
||||
mbedtls_mpi_uint Mprime;
|
||||
|
||||
size_t num_words = MAX(MAX(m_words, mpi_words(X)), mpi_words(Y));
|
||||
size_t num_words = MAX(MAX(m_words, x_words), y_words);
|
||||
|
||||
if (num_words * 32 > 4096) {
|
||||
return MBEDTLS_ERR_MPI_NOT_ACCEPTABLE;
|
||||
@ -288,25 +254,31 @@ int esp_mpi_mul_mpi_mod(mbedtls_mpi *Z, const mbedtls_mpi *X, const mbedtls_mpi
|
||||
|
||||
/* Calculate and load the first stage montgomery multiplication */
|
||||
mbedtls_mpi_init(&Rinv);
|
||||
MBEDTLS_MPI_CHK(calculate_rinv(&Rinv, M, m_words));
|
||||
MBEDTLS_MPI_CHK(calculate_rinv(&Rinv, M, num_words));
|
||||
Mprime = modular_inverse(M);
|
||||
|
||||
esp_mpi_acquire_hardware();
|
||||
|
||||
DPORT_REG_WRITE(RSA_LENGTH_REG, (num_words - 1));
|
||||
DPORT_REG_WRITE(RSA_LENGTH_REG, (num_words-1));
|
||||
DPORT_REG_WRITE(RSA_M_DASH_REG, (uint32_t)Mprime);
|
||||
|
||||
/* Load M, X, Rinv, Mprime (Mprime is mod 2^32) */
|
||||
mpi_to_mem_block(RSA_MEM_M_BLOCK_BASE, M, num_words);
|
||||
mpi_to_mem_block(RSA_MEM_RB_BLOCK_BASE, &Rinv, num_words);
|
||||
mpi_to_mem_block(RSA_MEM_X_BLOCK_BASE, X, num_words);
|
||||
mpi_to_mem_block(RSA_MEM_Y_BLOCK_BASE, Y, num_words);
|
||||
mpi_to_mem_block(RSA_MEM_RB_BLOCK_BASE, &Rinv, num_words);
|
||||
|
||||
/* Enable acceleration options */
|
||||
DPORT_REG_WRITE(RSA_CONSTANT_TIME_REG, 0);
|
||||
DPORT_REG_WRITE(RSA_SEARCH_OPEN_REG, 1);
|
||||
DPORT_REG_WRITE(RSA_SEARCH_POS_REG, y_bits - 1);
|
||||
|
||||
/* Execute first stage montgomery multiplication */
|
||||
start_op(RSA_MOD_MULT_START_REG);
|
||||
|
||||
wait_op_complete(RSA_MOD_MULT_START_REG);
|
||||
|
||||
DPORT_REG_WRITE(RSA_SEARCH_OPEN_REG, 1);
|
||||
|
||||
mem_block_to_mpi(Z, RSA_MEM_Z_BLOCK_BASE, m_words);
|
||||
|
||||
esp_mpi_release_hardware();
|
||||
@ -329,6 +301,7 @@ int esp_mpi_mul_mpi_mod(mbedtls_mpi *Z, const mbedtls_mpi *X, const mbedtls_mpi
|
||||
int mbedtls_mpi_exp_mod( mbedtls_mpi* Z, const mbedtls_mpi* X, const mbedtls_mpi* Y, const mbedtls_mpi* M, mbedtls_mpi* _Rinv )
|
||||
{
|
||||
int ret = 0;
|
||||
size_t y_bits = mbedtls_mpi_bitlen(Y);
|
||||
size_t x_words = mpi_words(X);
|
||||
size_t y_words = mpi_words(Y);
|
||||
size_t m_words = mpi_words(M);
|
||||
@ -343,6 +316,18 @@ int mbedtls_mpi_exp_mod( mbedtls_mpi* Z, const mbedtls_mpi* X, const mbedtls_mpi
|
||||
*/
|
||||
num_words = MAX(m_words, MAX(x_words, y_words));
|
||||
|
||||
if (mbedtls_mpi_cmp_int(M, 0) <= 0 || (M->p[0] & 1) == 0) {
|
||||
return MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
|
||||
}
|
||||
|
||||
if (mbedtls_mpi_cmp_int(Y, 0) < 0) {
|
||||
return MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
|
||||
}
|
||||
|
||||
if (mbedtls_mpi_cmp_int(Y, 0) == 0) {
|
||||
return mbedtls_mpi_lset(Z, 1);
|
||||
}
|
||||
|
||||
if (num_words * 32 > 4096) {
|
||||
return MBEDTLS_ERR_MPI_NOT_ACCEPTABLE;
|
||||
}
|
||||
@ -372,20 +357,28 @@ int mbedtls_mpi_exp_mod( mbedtls_mpi* Z, const mbedtls_mpi* X, const mbedtls_mpi
|
||||
mpi_to_mem_block(RSA_MEM_RB_BLOCK_BASE, Rinv, num_words);
|
||||
DPORT_REG_WRITE(RSA_M_DASH_REG, Mprime);
|
||||
|
||||
/* Enable acceleration options */
|
||||
DPORT_REG_WRITE(RSA_CONSTANT_TIME_REG, 0);
|
||||
DPORT_REG_WRITE(RSA_SEARCH_OPEN_REG, 1);
|
||||
DPORT_REG_WRITE(RSA_SEARCH_POS_REG, (y_words * 32) - 1);
|
||||
DPORT_REG_WRITE(RSA_SEARCH_POS_REG, y_bits - 1);
|
||||
|
||||
start_op(RSA_MODEXP_START_REG);
|
||||
wait_op_complete(RSA_MODEXP_START_REG);
|
||||
|
||||
DPORT_REG_WRITE(RSA_SEARCH_OPEN_REG, 0);
|
||||
DPORT_REG_WRITE(RSA_SEARCH_POS_REG, (m_words * 32) - 1);
|
||||
|
||||
ret = mem_block_to_mpi(Z, RSA_MEM_Z_BLOCK_BASE, m_words);
|
||||
|
||||
esp_mpi_release_hardware();
|
||||
|
||||
// Compensate for negative X
|
||||
if (X->s == -1 && (Y->p[0] & 1) != 0) {
|
||||
Z->s = -1;
|
||||
MBEDTLS_MPI_CHK(mbedtls_mpi_add_mpi(Z, M, Z));
|
||||
} else {
|
||||
Z->s = 1;
|
||||
}
|
||||
|
||||
cleanup:
|
||||
if (_Rinv == NULL) {
|
||||
mbedtls_mpi_free(&Rinv_new);
|
||||
@ -398,23 +391,21 @@ int mbedtls_mpi_exp_mod( mbedtls_mpi* Z, const mbedtls_mpi* X, const mbedtls_mpi
|
||||
|
||||
#if defined(MBEDTLS_MPI_MUL_MPI_ALT) /* MBEDTLS_MPI_MUL_MPI_ALT */
|
||||
|
||||
static int mpi_mult_mpi_failover_mod_mult(mbedtls_mpi *Z, const mbedtls_mpi *X, const mbedtls_mpi *Y, size_t num_words);
|
||||
static int mpi_mult_mpi_overlong(mbedtls_mpi *Z, const mbedtls_mpi *X, const mbedtls_mpi *Y, size_t Y_bits, size_t words_result);
|
||||
static int mpi_mult_mpi_failover_mod_mult(mbedtls_mpi *Z, const mbedtls_mpi *X, const mbedtls_mpi *Y, size_t z_words);
|
||||
static int mpi_mult_mpi_overlong(mbedtls_mpi *Z, const mbedtls_mpi *X, const mbedtls_mpi *Y, size_t y_words, size_t z_words);
|
||||
|
||||
/* Z = X * Y */
|
||||
int mbedtls_mpi_mul_mpi( mbedtls_mpi *Z, const mbedtls_mpi *X, const mbedtls_mpi *Y )
|
||||
{
|
||||
int ret = 0;
|
||||
size_t bits_x, bits_y, words_x, words_y, words_mult, words_z;
|
||||
size_t x_bits = mbedtls_mpi_bitlen(X);
|
||||
size_t y_bits = mbedtls_mpi_bitlen(Y);
|
||||
size_t x_words = bits_to_words(x_bits);
|
||||
size_t y_words = bits_to_words(y_bits);
|
||||
size_t num_words = MAX(x_words, y_words);
|
||||
size_t z_words = x_words + y_words;
|
||||
|
||||
/* Count words needed for X & Y in hardware */
|
||||
bits_x = mbedtls_mpi_bitlen(X);
|
||||
bits_y = mbedtls_mpi_bitlen(Y);
|
||||
|
||||
words_x = (bits_x + 7) / 8;
|
||||
words_y = (bits_y + 7) / 8;
|
||||
|
||||
/* Short-circuit eval if either argument is 0 or 1.
|
||||
/* Short-circuit eval if either argument is 0 or 1.
|
||||
|
||||
This is needed as the mpi modular division
|
||||
argument will sometimes call in here when one
|
||||
@ -424,26 +415,21 @@ int mbedtls_mpi_mul_mpi( mbedtls_mpi *Z, const mbedtls_mpi *X, const mbedtls_mpi
|
||||
This leaks some timing information, although overall there is a
|
||||
lot less timing variation than a software MPI approach.
|
||||
*/
|
||||
if (bits_x == 0 || bits_y == 0) {
|
||||
if (x_bits == 0 || y_bits== 0) {
|
||||
mbedtls_mpi_lset(Z, 0);
|
||||
return 0;
|
||||
}
|
||||
if (bits_x == 1) {
|
||||
if (x_bits == 1) {
|
||||
ret = mbedtls_mpi_copy(Z, Y);
|
||||
Z->s *= X->s;
|
||||
return ret;
|
||||
}
|
||||
if (bits_y == 1) {
|
||||
if (y_bits == 1) {
|
||||
ret = mbedtls_mpi_copy(Z, X);
|
||||
Z->s *= Y->s;
|
||||
return ret;
|
||||
}
|
||||
|
||||
words_mult = (words_x > words_y ? words_x : words_y);
|
||||
|
||||
/* Result Z has to have room for double the larger factor */
|
||||
words_z = words_mult * 2;
|
||||
|
||||
/* If either factor is over 2048 bits, we can't use the standard hardware multiplier
|
||||
(it assumes result is double longest factor, and result is max 4096 bits.)
|
||||
|
||||
@ -451,44 +437,44 @@ int mbedtls_mpi_mul_mpi( mbedtls_mpi *Z, const mbedtls_mpi *X, const mbedtls_mpi
|
||||
multiplication doesn't have the same restriction, so result is simply the
|
||||
number of bits in X plus number of bits in in Y.)
|
||||
*/
|
||||
if (words_mult * 32 > 2048) {
|
||||
/* Calculate new length of Z */
|
||||
words_z = (bits_x + bits_y + 31) / 32;
|
||||
if (words_z * 32 <= 4096) {
|
||||
|
||||
|
||||
|
||||
if (num_words * 32 > 2048) {
|
||||
if (z_words * 32 <= 4096) {
|
||||
/* Note: it's possible to use mpi_mult_mpi_overlong
|
||||
for this case as well, but it's very slightly
|
||||
slower and requires a memory allocation.
|
||||
*/
|
||||
return mpi_mult_mpi_failover_mod_mult(Z, X, Y, words_z);
|
||||
return mpi_mult_mpi_failover_mod_mult(Z, X, Y, z_words);
|
||||
} else {
|
||||
/* Still too long for the hardware unit... */
|
||||
if(bits_y > bits_x) {
|
||||
return mpi_mult_mpi_overlong(Z, X, Y, bits_y, words_z);
|
||||
if(y_words > x_words) {
|
||||
return mpi_mult_mpi_overlong(Z, X, Y, y_words, z_words);
|
||||
} else {
|
||||
return mpi_mult_mpi_overlong(Z, Y, X, bits_x, words_z);
|
||||
return mpi_mult_mpi_overlong(Z, Y, X, x_words, z_words);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Otherwise, we can use the (faster) multiply hardware unit */
|
||||
|
||||
esp_mpi_acquire_hardware();
|
||||
|
||||
/* Copy X (right-extended) & Y (left-extended) to memory block */
|
||||
mpi_to_mem_block(RSA_MEM_X_BLOCK_BASE, X, words_mult);
|
||||
mpi_to_mem_block(RSA_MEM_Z_BLOCK_BASE + words_mult * 4, Y, words_mult);
|
||||
mpi_to_mem_block(RSA_MEM_X_BLOCK_BASE, X, num_words);
|
||||
mpi_to_mem_block(RSA_MEM_Z_BLOCK_BASE + num_words * 4, Y, num_words);
|
||||
/* NB: as Y is left-extended, we don't zero the bottom words_mult words of Y block.
|
||||
This is OK for now because zeroing is done by hardware when we do esp_mpi_acquire_hardware().
|
||||
*/
|
||||
|
||||
DPORT_REG_WRITE(RSA_M_DASH_REG, 0);
|
||||
DPORT_REG_WRITE(RSA_LENGTH_REG, (words_z - 1));
|
||||
DPORT_REG_WRITE(RSA_LENGTH_REG, (num_words*2 - 1));
|
||||
start_op(RSA_MULT_START_REG);
|
||||
|
||||
wait_op_complete(RSA_MULT_START_REG);
|
||||
|
||||
/* Read back the result */
|
||||
ret = mem_block_to_mpi(Z, RSA_MEM_Z_BLOCK_BASE, words_z);
|
||||
ret = mem_block_to_mpi(Z, RSA_MEM_Z_BLOCK_BASE, z_words);
|
||||
|
||||
Z->s = X->s * Y->s;
|
||||
|
||||
@ -501,7 +487,7 @@ int mbedtls_mpi_mul_mpi( mbedtls_mpi *Z, const mbedtls_mpi *X, const mbedtls_mpi
|
||||
multiplication to calculate an mbedtls_mpi_mult_mpi result where either
|
||||
A or B are >2048 bits so can't use the standard multiplication method.
|
||||
|
||||
Result (A bits + B bits) must still be less than 4096 bits.
|
||||
Result (number of words, based on A bits + B bits) must still be less than 4096 bits.
|
||||
|
||||
This case is simpler than the general case modulo multiply of
|
||||
esp_mpi_mul_mpi_mod() because we can control the other arguments:
|
||||
@ -567,29 +553,28 @@ static int mpi_mult_mpi_failover_mod_mult(mbedtls_mpi *Z, const mbedtls_mpi *X,
|
||||
Note that this function may recurse multiple times, if both X & Y
|
||||
are too long for the hardware multiplication unit.
|
||||
*/
|
||||
static int mpi_mult_mpi_overlong(mbedtls_mpi *Z, const mbedtls_mpi *X, const mbedtls_mpi *Y, size_t bits_y, size_t words_result)
|
||||
static int mpi_mult_mpi_overlong(mbedtls_mpi *Z, const mbedtls_mpi *X, const mbedtls_mpi *Y, size_t y_words, size_t z_words)
|
||||
{
|
||||
int ret = 0;
|
||||
mbedtls_mpi Ztemp;
|
||||
const size_t limbs_y = (bits_y + biL - 1) / biL;
|
||||
/* Rather than slicing in two on bits we slice on limbs (32 bit words) */
|
||||
const size_t limbs_slice = limbs_y / 2;
|
||||
const size_t words_slice = y_words / 2;
|
||||
/* Yp holds lower bits of Y (declared to reuse Y's array contents to save on copying) */
|
||||
const mbedtls_mpi Yp = {
|
||||
.p = Y->p,
|
||||
.n = limbs_slice,
|
||||
.n = words_slice,
|
||||
.s = Y->s
|
||||
};
|
||||
/* Ypp holds upper bits of Y, right shifted (also reuses Y's array contents) */
|
||||
const mbedtls_mpi Ypp = {
|
||||
.p = Y->p + limbs_slice,
|
||||
.n = limbs_y - limbs_slice,
|
||||
.p = Y->p + words_slice,
|
||||
.n = y_words - words_slice,
|
||||
.s = Y->s
|
||||
};
|
||||
mbedtls_mpi_init(&Ztemp);
|
||||
|
||||
/* Grow Z to result size early, avoid interim allocations */
|
||||
mbedtls_mpi_grow(Z, words_result);
|
||||
mbedtls_mpi_grow(Z, z_words);
|
||||
|
||||
/* Get result Ztemp = Yp * X (need temporary variable Ztemp) */
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi(&Ztemp, X, &Yp) );
|
||||
@ -598,7 +583,7 @@ static int mpi_mult_mpi_overlong(mbedtls_mpi *Z, const mbedtls_mpi *X, const mbe
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi(Z, X, &Ypp) );
|
||||
|
||||
/* Z = Z << b */
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l(Z, limbs_slice * biL) );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l(Z, words_slice * 32) );
|
||||
|
||||
/* Z += Ztemp */
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi(Z, Z, &Ztemp) );
|
||||
|
@ -15,12 +15,18 @@
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <assert.h>
|
||||
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
#include "esp32/sha.h"
|
||||
#elif CONFIG_IDF_TARGET_ESP32S2BETA
|
||||
#include "esp32s2beta/sha.h"
|
||||
#endif
|
||||
|
||||
#include <mbedtls/sha1.h>
|
||||
#include <mbedtls/sha256.h>
|
||||
#include <mbedtls/sha512.h>
|
||||
|
||||
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
void esp_sha(esp_sha_type sha_type, const unsigned char *input, size_t ilen, unsigned char *output)
|
||||
{
|
||||
int ret;
|
||||
@ -77,3 +83,4 @@ void esp_sha(esp_sha_type sha_type, const unsigned char *input, size_t ilen, uns
|
||||
}
|
||||
|
||||
}
|
||||
#endif
|
||||
|
@ -47,7 +47,11 @@
|
||||
#endif /* MBEDTLS_PLATFORM_C */
|
||||
#endif /* MBEDTLS_SELF_TEST */
|
||||
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
#include "esp32/sha.h"
|
||||
#elif CONFIG_IDF_TARGET_ESP32S2BETA
|
||||
#include "esp32s2beta/sha.h"
|
||||
#endif
|
||||
|
||||
/* Implementation that should never be optimized out by the compiler */
|
||||
static void mbedtls_zeroize( void *v, size_t n ) {
|
||||
|
@ -48,7 +48,11 @@
|
||||
#endif /* MBEDTLS_PLATFORM_C */
|
||||
#endif /* MBEDTLS_SELF_TEST */
|
||||
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
#include "esp32/sha.h"
|
||||
#elif CONFIG_IDF_TARGET_ESP32S2BETA
|
||||
#include "esp32s2beta/sha.h"
|
||||
#endif
|
||||
|
||||
/* Implementation that should never be optimized out by the compiler */
|
||||
static void mbedtls_zeroize( void *v, size_t n ) {
|
||||
|
@ -54,7 +54,11 @@
|
||||
#endif /* MBEDTLS_PLATFORM_C */
|
||||
#endif /* MBEDTLS_SELF_TEST */
|
||||
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
#include "esp32/sha.h"
|
||||
#elif CONFIG_IDF_TARGET_ESP32S2BETA
|
||||
#include "esp32s2beta/sha.h"
|
||||
#endif
|
||||
|
||||
inline static esp_sha_type sha_type(const mbedtls_sha512_context *ctx)
|
||||
{
|
||||
|
@ -28,7 +28,11 @@ extern "C" {
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_AES_ALT)
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
#include "esp32/aes.h"
|
||||
#elif CONFIG_IDF_TARGET_ESP32S2BETA
|
||||
#include "esp32s2beta/aes.h"
|
||||
#endif
|
||||
|
||||
typedef esp_aes_context mbedtls_aes_context;
|
||||
|
||||
|
@ -48,9 +48,21 @@ extern "C" {
|
||||
*/
|
||||
typedef struct {
|
||||
uint8_t key_bytes;
|
||||
volatile uint8_t key_in_hardware; /* This variable is used for fault injection checks, so marked volatile to avoid optimisation */
|
||||
uint8_t key[32];
|
||||
} esp_aes_context;
|
||||
|
||||
/**
|
||||
* \brief The AES XTS context-type definition.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
esp_aes_context crypt; /*!< The AES context to use for AES block
|
||||
encryption or decryption. */
|
||||
esp_aes_context tweak; /*!< The AES context used for tweak
|
||||
computation. */
|
||||
} esp_aes_xts_context;
|
||||
|
||||
/**
|
||||
* \brief Lock access to AES hardware unit
|
||||
*
|
||||
@ -86,6 +98,33 @@ void esp_aes_init( esp_aes_context *ctx );
|
||||
*/
|
||||
void esp_aes_free( esp_aes_context *ctx );
|
||||
|
||||
/*
|
||||
* \brief This function initializes the specified AES XTS context.
|
||||
*
|
||||
* It must be the first API called before using
|
||||
* the context.
|
||||
*
|
||||
* \param ctx The AES XTS context to initialize.
|
||||
*/
|
||||
void esp_aes_xts_init( esp_aes_xts_context *ctx );
|
||||
|
||||
/**
|
||||
* \brief This function releases and clears the specified AES XTS context.
|
||||
*
|
||||
* \param ctx The AES XTS context to clear.
|
||||
*/
|
||||
void esp_aes_xts_free( esp_aes_xts_context *ctx );
|
||||
|
||||
/**
|
||||
* \brief AES set key schedule (encryption or decryption)
|
||||
*
|
||||
* \param ctx AES context to be initialized
|
||||
* \param key encryption key
|
||||
* \param keybits must be 128, 192 or 256
|
||||
*
|
||||
* \return 0 if successful, or ERR_AES_INVALID_KEY_LENGTH
|
||||
*/
|
||||
|
||||
/**
|
||||
* \brief AES set key schedule (encryption or decryption)
|
||||
*
|
||||
@ -233,6 +272,62 @@ int esp_aes_crypt_ctr( esp_aes_context *ctx,
|
||||
const unsigned char *input,
|
||||
unsigned char *output );
|
||||
|
||||
/**
|
||||
* \brief This function performs an AES-OFB (Output Feedback Mode)
|
||||
* encryption or decryption operation.
|
||||
*
|
||||
* \param ctx The AES context to use for encryption or decryption.
|
||||
* It must be initialized and bound to a key.
|
||||
* \param length The length of the input data.
|
||||
* \param iv_off The offset in IV (updated after use).
|
||||
* It must point to a valid \c size_t.
|
||||
* \param iv The initialization vector (updated after use).
|
||||
* It must be a readable and writeable buffer of \c 16 Bytes.
|
||||
* \param input The buffer holding the input data.
|
||||
* It must be readable and of size \p length Bytes.
|
||||
* \param output The buffer holding the output data.
|
||||
* It must be writeable and of size \p length Bytes.
|
||||
*
|
||||
* \return \c 0 on success.
|
||||
*/
|
||||
int esp_aes_crypt_ofb( esp_aes_context *ctx,
|
||||
size_t length,
|
||||
size_t *iv_off,
|
||||
unsigned char iv[16],
|
||||
const unsigned char *input,
|
||||
unsigned char *output );
|
||||
|
||||
/**
|
||||
* \brief This function prepares an XTS context for encryption and
|
||||
* sets the encryption key.
|
||||
*
|
||||
* \param ctx The AES XTS context to which the key should be bound.
|
||||
* \param key The encryption key. This is comprised of the XTS key1
|
||||
* concatenated with the XTS key2.
|
||||
* \param keybits The size of \p key passed in bits. Valid options are:
|
||||
* <ul><li>256 bits (each of key1 and key2 is a 128-bit key)</li>
|
||||
* <li>512 bits (each of key1 and key2 is a 256-bit key)</li></ul>
|
||||
*
|
||||
* \return \c 0 on success.
|
||||
* \return #MBEDTLS_ERR_AES_INVALID_KEY_LENGTH on failure.
|
||||
*/
|
||||
int esp_aes_xts_setkey_enc( esp_aes_xts_context *ctx,
|
||||
const unsigned char *key,
|
||||
unsigned int keybits );
|
||||
|
||||
/**
|
||||
* \brief Internal AES block encryption function
|
||||
* (Only exposed to allow overriding it,
|
||||
* see AES_ENCRYPT_ALT)
|
||||
*
|
||||
* \param ctx AES context
|
||||
* \param input Plaintext block
|
||||
* \param output Output (ciphertext) block
|
||||
*/
|
||||
int esp_aes_xts_setkey_dec( esp_aes_xts_context *ctx,
|
||||
const unsigned char *key,
|
||||
unsigned int keybits );
|
||||
|
||||
|
||||
/**
|
||||
* \brief Internal AES block encryption function
|
||||
@ -262,6 +357,10 @@ int esp_internal_aes_decrypt( esp_aes_context *ctx, const unsigned char input[16
|
||||
/** Deprecated, see esp_aes_internal_decrypt */
|
||||
void esp_aes_decrypt( esp_aes_context *ctx, const unsigned char input[16], unsigned char output[16] ) __attribute__((deprecated));
|
||||
|
||||
/** AES-XTS buffer encryption/decryption */
|
||||
int esp_aes_crypt_xts( esp_aes_xts_context *ctx, int mode, size_t length, const unsigned char data_unit[16], const unsigned char *input, unsigned char *output );
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -21,7 +21,7 @@
|
||||
error hex value (mbedTLS uses -N for error codes) */
|
||||
#define TEST_ASSERT_MBEDTLS_OK(X) TEST_ASSERT_EQUAL_HEX32(0, -(X))
|
||||
|
||||
TEST_CASE_ESP32("mbedtls ECDH Generate Key", "[mbedtls]")
|
||||
TEST_CASE("mbedtls ECDH Generate Key", "[mbedtls]")
|
||||
{
|
||||
mbedtls_ecdh_context ctx;
|
||||
mbedtls_entropy_context entropy;
|
||||
@ -48,7 +48,7 @@ TEST_CASE("mbedtls ECP self-tests", "[mbedtls]")
|
||||
TEST_ASSERT_EQUAL(0, mbedtls_ecp_self_test(1));
|
||||
}
|
||||
|
||||
TEST_CASE_ESP32("mbedtls ECP mul w/ koblitz", "[mbedtls]")
|
||||
TEST_CASE("mbedtls ECP mul w/ koblitz", "[mbedtls]")
|
||||
{
|
||||
/* Test case code via https://github.com/espressif/esp-idf/issues/1556 */
|
||||
mbedtls_entropy_context ctxEntropy;
|
||||
|
@ -165,7 +165,7 @@ static bool test_bignum_modexp(const char *z_str, const char *x_str, const char
|
||||
return fail;
|
||||
}
|
||||
|
||||
TEST_CASE_ESP32("test MPI modexp", "[bignum]")
|
||||
TEST_CASE("test MPI modexp", "[bignum]")
|
||||
{
|
||||
bool test_error = false;
|
||||
printf("Z = (X ^ Y) mod M \n");
|
||||
|
@ -15,7 +15,7 @@
|
||||
#include "sdkconfig.h"
|
||||
#include "test_apb_dport_access.h"
|
||||
|
||||
TEST_CASE_ESP32("mbedtls SHA self-tests", "[mbedtls]")
|
||||
TEST_CASE("mbedtls SHA self-tests", "[mbedtls]")
|
||||
{
|
||||
start_apb_access_loop();
|
||||
TEST_ASSERT_FALSE_MESSAGE(mbedtls_sha1_self_test(1), "SHA1 self-tests should pass.");
|
||||
@ -121,7 +121,7 @@ static void tskRunSHA256Test(void *pvParameters)
|
||||
|
||||
#define SHA_TASK_STACK_SIZE (10*1024)
|
||||
|
||||
TEST_CASE_ESP32("mbedtls SHA multithreading", "[mbedtls]")
|
||||
TEST_CASE("mbedtls SHA multithreading", "[mbedtls]")
|
||||
{
|
||||
done_sem = xSemaphoreCreateCounting(4, 0);
|
||||
xTaskCreate(tskRunSHA1Test, "SHA1Task1", SHA_TASK_STACK_SIZE, NULL, 3, NULL);
|
||||
@ -164,13 +164,13 @@ void tskRunSHASelftests(void *param)
|
||||
vTaskDelete(NULL);
|
||||
}
|
||||
|
||||
TEST_CASE_ESP32("mbedtls SHA self-tests multithreaded", "[mbedtls]")
|
||||
TEST_CASE("mbedtls SHA self-tests multithreaded", "[mbedtls]")
|
||||
{
|
||||
done_sem = xSemaphoreCreateCounting(2, 0);
|
||||
xTaskCreate(tskRunSHASelftests, "SHASelftests1", SHA_TASK_STACK_SIZE, NULL, 3, NULL);
|
||||
xTaskCreate(tskRunSHASelftests, "SHASelftests2", SHA_TASK_STACK_SIZE, NULL, 3, NULL);
|
||||
|
||||
const int TIMEOUT_MS = 20000;
|
||||
const int TIMEOUT_MS = 40000;
|
||||
|
||||
for(int i = 0; i < 2; i++) {
|
||||
if(!xSemaphoreTake(done_sem, TIMEOUT_MS/portTICK_PERIOD_MS)) {
|
||||
@ -180,7 +180,7 @@ TEST_CASE_ESP32("mbedtls SHA self-tests multithreaded", "[mbedtls]")
|
||||
vSemaphoreDelete(done_sem);
|
||||
}
|
||||
|
||||
TEST_CASE_ESP32("mbedtls SHA512 clone", "[mbedtls]")
|
||||
TEST_CASE("mbedtls SHA512 clone", "[mbedtls]")
|
||||
{
|
||||
mbedtls_sha512_context ctx;
|
||||
mbedtls_sha512_context clone;
|
||||
@ -205,7 +205,7 @@ TEST_CASE_ESP32("mbedtls SHA512 clone", "[mbedtls]")
|
||||
TEST_ASSERT_EQUAL_MEMORY_MESSAGE(sha512_thousand_bs, sha512, 64, "SHA512 cloned calculation");
|
||||
}
|
||||
|
||||
TEST_CASE_ESP32("mbedtls SHA384 clone", "[mbedtls]")
|
||||
TEST_CASE("mbedtls SHA384 clone", "[mbedtls]")
|
||||
{
|
||||
mbedtls_sha512_context ctx;
|
||||
mbedtls_sha512_context clone;
|
||||
@ -231,7 +231,7 @@ TEST_CASE_ESP32("mbedtls SHA384 clone", "[mbedtls]")
|
||||
}
|
||||
|
||||
|
||||
TEST_CASE_ESP32("mbedtls SHA256 clone", "[mbedtls]")
|
||||
TEST_CASE("mbedtls SHA256 clone", "[mbedtls]")
|
||||
{
|
||||
mbedtls_sha256_context ctx;
|
||||
mbedtls_sha256_context clone;
|
||||
@ -276,6 +276,7 @@ static void tskFinaliseSha(void *v_param)
|
||||
vTaskDelete(NULL);
|
||||
}
|
||||
|
||||
// No concurrent SHA sessions in esp32s2, only has one engine
|
||||
TEST_CASE_ESP32("mbedtls SHA session passed between tasks" , "[mbedtls]")
|
||||
{
|
||||
finalise_sha_param_t param = { 0 };
|
||||
|
@ -11,7 +11,7 @@
|
||||
#include "test_utils.h"
|
||||
#include "sodium/utils.h"
|
||||
|
||||
TEST_CASE_ESP32("mbedtls SHA performance", "[aes]")
|
||||
TEST_CASE("mbedtls SHA performance", "[aes]")
|
||||
{
|
||||
const unsigned CALLS = 256;
|
||||
const unsigned CALL_SZ = 16*1024;
|
||||
@ -36,8 +36,8 @@ TEST_CASE_ESP32("mbedtls SHA performance", "[aes]")
|
||||
free(buf);
|
||||
mbedtls_sha256_free(&sha256_ctx);
|
||||
|
||||
/* Check the result. Reference value can be calculated using:
|
||||
* dd if=/dev/zero bs=$((16*1024)) count=256 | tr '\000' '\125' | sha256sum
|
||||
/* Check the result. Reference value can be calculated using:
|
||||
* dd if=/dev/zero bs=$((16*1024)) count=256 | tr '\000' '\125' | sha256sum
|
||||
*/
|
||||
const char* expected_hash = "c88df2638fb9699abaad05780fa5e0fdb6058f477069040eac8bed3231286275";
|
||||
char hash_str[sizeof(sha256) * 2 + 1];
|
||||
|
@ -1098,7 +1098,7 @@ static esp_err_t test_security0 (void)
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
TEST_CASE_ESP32("leak test", "[PROTOCOMM]")
|
||||
TEST_CASE("leak test", "[PROTOCOMM]")
|
||||
{
|
||||
#ifdef CONFIG_HEAP_TRACING
|
||||
heap_trace_init_standalone(trace_record, NUM_RECORDS);
|
||||
@ -1144,17 +1144,17 @@ TEST_CASE("security 0 basic test", "[PROTOCOMM]")
|
||||
TEST_ASSERT(test_security0() == ESP_OK);
|
||||
}
|
||||
|
||||
TEST_CASE_ESP32("security 1 basic test", "[PROTOCOMM]")
|
||||
TEST_CASE("security 1 basic test", "[PROTOCOMM]")
|
||||
{
|
||||
TEST_ASSERT(test_security1() == ESP_OK);
|
||||
}
|
||||
|
||||
TEST_CASE_ESP32("security 1 no encryption test", "[PROTOCOMM]")
|
||||
TEST_CASE("security 1 no encryption test", "[PROTOCOMM]")
|
||||
{
|
||||
TEST_ASSERT(test_security1_no_encryption() == ESP_OK);
|
||||
}
|
||||
|
||||
TEST_CASE_ESP32("security 1 session overflow test", "[PROTOCOMM]")
|
||||
TEST_CASE("security 1 session overflow test", "[PROTOCOMM]")
|
||||
{
|
||||
TEST_ASSERT(test_security1_session_overflow() == ESP_OK);
|
||||
}
|
||||
@ -1164,12 +1164,12 @@ TEST_CASE("security 1 wrong pop test", "[PROTOCOMM]")
|
||||
TEST_ASSERT(test_security1_wrong_pop() == ESP_OK);
|
||||
}
|
||||
|
||||
TEST_CASE_ESP32("security 1 insecure client test", "[PROTOCOMM]")
|
||||
TEST_CASE("security 1 insecure client test", "[PROTOCOMM]")
|
||||
{
|
||||
TEST_ASSERT(test_security1_insecure_client() == ESP_OK);
|
||||
}
|
||||
|
||||
TEST_CASE_ESP32("security 1 weak session test", "[PROTOCOMM]")
|
||||
TEST_CASE("security 1 weak session test", "[PROTOCOMM]")
|
||||
{
|
||||
TEST_ASSERT(test_security1_weak_session() == ESP_OK);
|
||||
}
|
||||
|
@ -23,7 +23,7 @@
|
||||
#include "mbedtls/ecp.h"
|
||||
typedef struct crypto_bignum crypto_bignum;
|
||||
|
||||
TEST_CASE_ESP32("Test crypto lib bignum apis", "[wpa_crypto]")
|
||||
TEST_CASE("Test crypto lib bignum apis", "[wpa_crypto]")
|
||||
{
|
||||
{
|
||||
|
||||
|
@ -453,7 +453,7 @@ UT_034:
|
||||
|
||||
UT_035:
|
||||
extends: .unit_test_template
|
||||
parallel: 19
|
||||
parallel: 20
|
||||
tags:
|
||||
- ESP32S2BETA_IDF
|
||||
- UT_T1_1
|
||||
|
@ -11,7 +11,6 @@ CONFIG_FREERTOS_WATCHPOINT_END_OF_STACK=y
|
||||
CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=3
|
||||
CONFIG_FREERTOS_USE_TRACE_FACILITY=y
|
||||
CONFIG_HEAP_POISONING_COMPREHENSIVE=y
|
||||
CONFIG_MBEDTLS_HARDWARE_SHA=y
|
||||
CONFIG_SPI_FLASH_ENABLE_COUNTERS=y
|
||||
CONFIG_ESP_TASK_WDT=n
|
||||
CONFIG_SPI_FLASH_DANGEROUS_WRITE_FAILS=y
|
||||
|
@ -1,5 +1,2 @@
|
||||
CONFIG_ESP32S2_DEFAULT_CPU_FREQ_240=y
|
||||
CONFIG_ESP32S2_ULP_COPROC_ENABLED=y
|
||||
|
||||
# Hardware MPI disabled, ref. IDF-757
|
||||
CONFIG_MBEDTLS_HARDWARE_MPI=n
|
||||
|
Loading…
Reference in New Issue
Block a user