Merge pull request #2099 from miyazakh/Espressif_port_Phase2C

RSA primitive hw acceleration support on esp32
This commit is contained in:
toddouska
2019-03-11 12:04:26 -07:00
committed by GitHub
19 changed files with 1337 additions and 144 deletions

View File

@ -31,6 +31,22 @@ Including the following examples:
## Build examples
1. See README in each example folder
## Benchmark
w/o atecc608a
```
ECC 256 key gen 4 ops took 1.092 sec, avg 273.000 ms, 3.663 ops/sec
ECDHE 256 agree 4 ops took 1.091 sec, avg 272.750 ms, 3.666 ops/sec
ECDSA 256 sign 4 ops took 1.102 sec, avg 275.500 ms, 3.630 ops/sec
ECDSA 256 verify 2 ops took 1.091 sec, avg 545.500 ms, 1.833 ops/sec
```
w/ atecc608a
```
ECC 256 key gen 11 ops took 1.074 sec, avg 97.636 ms, 10.242 ops/sec
ECDHE 256 agree 6 ops took 1.068 sec, avg 178.000 ms, 5.618 ops/sec
ECDSA 256 sign 8 ops took 1.009 sec, avg 126.125 ms, 7.929 ops/sec
ECDSA 256 verify 14 ops took 1.079 sec, avg 77.071 ms, 12.975 ops/sec
```
## Support
For question please email [support@wolfssl.com]

View File

@ -21,25 +21,18 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <wolfssl/wolfcrypt/settings.h>
#include <wolfcrypt/benchmark/benchmark.h>
#include "sdkconfig.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_log.h"
#include "nvs_flash.h"
#define WOLFSSL_BENCH_ARGV CONFIG_BENCH_ARGV
#define WOLFSSLBENCHMARK_TASK_NAME "wolfsslbenchmark_name"
#define WOLFSSLBENCHMARK_TASK_WORDS 10240
#define WOLFSSLBENCHMARK_TASK_PRIORITY 8
/* proto-type */
extern void wolf_benchmark_task();
static const char* const TAG = "wolfbenchmark";
char* __argv[22];
#if defined(WOLFSSL_ESPWROOM32SE) && defined(HAVE_PK_CALLBACKS) \
@ -57,8 +50,7 @@ static byte mSlotList[ATECC_MAX_SLOT];
void my_atmel_slotInit()
{
int i;
for(i=0;i<ATECC_MAX_SLOT; i++) {
for(i = 0;i < ATECC_MAX_SLOT;i++) {
mSlotList[i] = ATECC_INVALID_SLOT;
}
}
@ -68,8 +60,6 @@ int my_atmel_alloc(int slotType)
{
int i, slot = -1;
ESP_LOGI(TAG, "Enter my_atmel_alloc");
switch(slotType){
case ATMEL_SLOT_ENCKEY:
slot = 4;
@ -78,13 +68,13 @@ int my_atmel_alloc(int slotType)
slot = 0;
break;
case ATMEL_SLOT_ECDHE:
slot = 2;
slot = 0;
break;
case ATMEL_SLOT_ECDHE_ENC:
slot = 4;
break;
case ATMEL_SLOT_ANY:
for(i=0;i<ATECC_MAX_SLOT;i++){
for(i = 0;i < ATECC_MAX_SLOT;i++){
if(mSlotList[i] == ATECC_INVALID_SLOT){
slot = i;
break;
@ -92,22 +82,15 @@ int my_atmel_alloc(int slotType)
}
}
ESP_LOGI(TAG, "Leave my_atmel_alloc\n");
return slot;
}
/* free slot array */
void my_atmel_free(int slotId)
{
ESP_LOGI(TAG, "Enter my_atmel_alloc");
if(slotId >= 0 && slotId < ATECC_MAX_SLOT){
mSlotList[slotId] = ATECC_INVALID_SLOT;
}
ESP_LOGI(TAG, "Leave my_atmel_alloc");
}
#endif /* CUSTOM_SLOT_ALLOCATION */
@ -167,30 +150,22 @@ int construct_argv()
/* entry point */
void app_main(void)
{
ESP_LOGI(TAG, "Start app_main...");
ESP_ERROR_CHECK(nvs_flash_init());
#ifndef NO_CRYPT_BENCHMARK
/* when using atecc608a on esp32-wroom-32se */
/* when using atecc608a on esp32-wroom-32se */
#if defined(WOLFSSL_ESPWROOM32SE) && defined(HAVE_PK_CALLBACKS) \
&& defined(WOLFSSL_ATECC508A)
#if defined(CUSTOM_SLOT_ALLOCATION)
ESP_LOGI(TAG, "register callback for slot allocation");
my_atmel_slotInit();
/* to register the callback, it needs to be initialized. */
benchmark_init();
if ((wolfCrypt_Init()) != 0) {
ESP_LOGE(TAG, "wolfCrypt_Init failed");
return;
}
atmel_set_slot_allocator(my_atmel_alloc, my_atmel_free);
#endif
#endif
ESP_LOGI(TAG, "Start benchmark..");
wolf_benchmark_task();
#else
ESP_LOGI(TAG, "no crypt benchmark");
#endif /* NO_CRYPT_BENCHMARK */
}

View File

@ -1,5 +1,5 @@
CONFIG_BENCH_ARGV="-lng 0"
CONFIG_MAIN_TASK_STACK_SIZE=5000
CONFIG_MAIN_TASK_STACK_SIZE=7000
CONFIG_FREERTOS_HZ=1000
CONFIG_TASK_WDT_CHECK_IDLE_TASK_CPU0=
CONFIG_ESP32_DEFAULT_CPU_FREQ_240=y

View File

@ -10,11 +10,11 @@ The Example contains of wolfSSL tls client demo.
Target host ip address : the host that you want to connect to.(default is 127.0.0.1)
Note: the example program uses 11111 port. If you want to use different port
, you need to modifiy DEFAULT_PORT definition in the code.
, you need to modify DEFAULT_PORT definition in the code.
When you want to test the wolfSSL client
1. "make falsh monitor" to load the firmware and see the context
1. "make flash monitor" to load the firmware and see the context
2. You can use <wolfssl>/examples/server/server program for test.
e.g. Launch ./examples/server/server -v 4 -b -i

View File

@ -61,7 +61,7 @@ static void ShowCiphers(void)
#include "wolfssl/wolfcrypt/port/atmel/atmel.h"
/* when you want to use custome slot allocation */
/* when you want to use custom slot allocation */
/* enable the definition CUSTOM_SLOT_ALLOCATION.*/
#if defined(CUSTOM_SLOT_ALLOCATION)
@ -235,7 +235,7 @@ void tls_smp_client_task()
#if defined(WOLFSSL_ESPWROOM32SE) && defined(HAVE_PK_CALLBACKS) \
&& defined(WOLFSSL_ATECC508A)
atcatls_set_callbacks(ctx);
/* when using custome slot-allocation */
/* when using custom slot-allocation */
#if defined(CUSTOM_SLOT_ALLOCATION)
my_atmel_slotInit();
atmel_set_slot_allocator(my_atmel_alloc, my_atmel_free);

View File

@ -4,7 +4,7 @@ The Example contains of wolfSSL test program.
When you want to run the benchmark program
1. "make menuconfig" to configure the program,first
1. "make flash" to compile and load the firemware
2. "make monitor" to see the message
2. "make flash" to compile and load the firmware
3. "make monitor" to see the message
See the README.md file in the upper level 'examples' directory for more information about examples.

View File

@ -1,2 +1,2 @@
CONFIG_MAIN_TASK_STACK_SIZE=5000
CONFIG_MAIN_TASK_STACK_SIZE=9000
CONFIG_TASK_WDT_CHECK_IDLE_TASK_CPU0=

View File

@ -1,5 +1,5 @@
/*
* wolfssl sha tests
* wolfssl unit tests
*/
#include <stdio.h>
@ -12,6 +12,7 @@
#include "unity.h"
#include "sdkconfig.h"
#include "esp_log.h"
#include "esp_timer.h"
#include <wolfssl/wolfcrypt/settings.h>
#include <wolfssl/wolfcrypt/sha.h>
@ -20,10 +21,18 @@
#include <wolfssl/wolfcrypt/wc_port.h>
#include <wolfssl/wolfcrypt/logging.h>
#include <wolfssl/wolfcrypt/types.h>
#include <wolfssl/wolfcrypt/integer.h>
static const char* TAG = "wolfssl unit test";
#ifdef NO_INLINE
#include <wolfssl/wolfcrypt/misc.h>
#else
#define WOLFSSL_MISC_INCLUDED
#include <wolfcrypt/src/misc.c>
#endif
static const char* const TAG = "wolfssl unit test";
static xSemaphoreHandle exit_semaph;
static volatile bool exit_loop=false;
static uint64_t startTime = 0;
#define SHA_STACK_SIZE (20*1024)
#define TIMES_SHA 500
@ -42,12 +51,51 @@ int sha384_test(void);
int sha512_test(void);
#endif
static uint64_t rsa_elapsedTime = 0;
static void esp32TimerStart()
{
startTime = esp_timer_get_time();
}
static uint64_t esp32elapsedTime()
{
/* return elapsed time since wc_esp32AesTimeStart() is called in us */
return esp_timer_get_time() - startTime;
}
#ifndef NO_RSA
int rsa_test(void);
static void tskRsa_Test(void *pvParam)
{
int ret = 0;
ESP_LOGI(TAG, "enter tskRsa_Test");
while(exit_loop==false) {
if(rsa_elapsedTime == 0) esp32TimerStart();
ret = rsa_test();
if(rsa_elapsedTime == 0) rsa_elapsedTime = esp32elapsedTime()/1000;
if(ret != 0) {
printf("result was not good(rsa_test)(%d)\n",ret);
TEST_FAIL_MESSAGE("tskRsa_Test\n");
}
}
ESP_LOGI(TAG, "leave tskRsa_Test");
xSemaphoreGive(exit_semaph);
vTaskDelete(NULL);
}
#endif
#ifndef NO_AES
int aes_test(void);
static void tskAes_Test(void *pvParam)
{
ESP_LOGI(TAG, "enter tskAes_Test");
int ret = 0;
ESP_LOGI(TAG, "enter tskAes_Test");
while(exit_loop==false) {
ret = aes_test();
if(ret != 0) {
@ -56,17 +104,20 @@ static void tskAes_Test(void *pvParam)
}
}
ESP_LOGI(TAG, "leave tskAes_Test");
xSemaphoreGive(exit_semaph);
vTaskDelete(NULL);
ESP_LOGI(TAG, "leave tskAes_Test");
xSemaphoreGive(exit_semaph);
vTaskDelete(NULL);
}
int aesgcm_test(void);
static void tskAesGcm_Test(void *pvParam)
{
ESP_LOGI(TAG, "enter tskAesGcm_Test");
int ret = 0;
ESP_LOGI(TAG, "enter tskAesGcm_Test");
while(exit_loop==false) {
ret = aesgcm_test();
if(ret != 0) {
@ -83,8 +134,10 @@ static void tskAesGcm_Test(void *pvParam)
int aes192_test(void);
static void tskAes192_Test(void *pvParam)
{
ESP_LOGI(TAG, "enter tskAes192_Test");
int ret = 0;
ESP_LOGI(TAG, "enter tskAes192_Test");
while(exit_loop==false) {
ret = aes192_test();
if(ret != 0) {
@ -101,8 +154,10 @@ static void tskAes192_Test(void *pvParam)
int aes256_test(void);
static void tskAes256_Test(void *pvParam)
{
ESP_LOGI(TAG, "enter tskAes256_Test");
int ret = 0;
ESP_LOGI(TAG, "enter tskAes256_Test");
while(exit_loop==false) {
ret = aes256_test();
if(ret != 0) {
@ -116,6 +171,473 @@ static void tskAes256_Test(void *pvParam)
}
#endif
#if !defined(NO_RSA) || defined(HAVE_ECC)
int mp_performance_check(int mul, int mulmod, int exptmod)
{
int ret = 0;
int i,j,k;
word32 Xbits;
word32 Ybits;
word32 Pbits;
byte strX[256];
byte strY[256];
byte strP[256];
uint64_t elapsedTime1;
uint64_t elapsedTime2;
uint64_t elapsedTime3;
RNG rng;
mp_int z1, z2, z3, x, p, y;
/* sanity check */
if(!(mul||mulmod||exptmod)) return ret;
XMEMSET(strX, 0, sizeof(strX));
XMEMSET(strY, 0, sizeof(strY));
XMEMSET(strP, 0, sizeof(strP));
wc_InitRng(&rng);
ret = wc_RNG_GenerateBlock(&rng, strX, sizeof(strX));
if (ret != 0) {
return -1; //generating block failed!
}
ret = wc_RNG_GenerateBlock(&rng, strY, sizeof(strY));
if (ret != 0) {
return -1; //generating block failed!
}
ret = wc_RNG_GenerateBlock(&rng, strP, sizeof(strP));
if (ret != 0) {
return -1; //generating block failed!
}
if((strP[255]&1) == 0) {
strP[255] |= 1;
}
for(i = 0; i < 256; i+=16) {
for(j = 0; j < 256; j+=16) {
for(k = 0; k < 256; k+=16) {
/* set init mp_int */
if((ret = mp_init_multi(&z1, &x, &y, &p, &z2, NULL)) != MP_OKAY) {
TEST_FAIL_MESSAGE("mp_init failed.\n");
}
/* set big-numbers into mp_inits */
if(ret == 0 && mp_read_unsigned_bin(&x, (const byte*)&strX[i+1], i+1) != MP_OKAY) {
ESP_LOGE(TAG,"failed to set strX into mp_init");
return -1;
}
if(ret == 0 && mp_read_unsigned_bin(&y, (const byte*)&strY[j+1], j+1) != MP_OKAY) {
ESP_LOGE(TAG,"failed to set strY into mp_init");
return -1;
}
if(ret == 0 && mp_read_unsigned_bin(&p, (const byte*)&strP[k+1], k+1) != MP_OKAY) {
ESP_LOGE(TAG,"failed to set strY into mp_init");
return -1;
}
Xbits = mp_count_bits(&x);
Ybits = mp_count_bits(&y);
Pbits = mp_count_bits(&p);
if(mul) {
/* Z = X * Y */
esp32TimerStart();
if(ret == 0 && (ret = mp_mul(&x, &y, &z1)) != MP_OKAY) {
printf("(%d,%d) Xbits = %d, Ybits = %d Pbits = %d ret = %d\n",
i, j, Xbits, Ybits, Pbits, ret);
TEST_FAIL_MESSAGE("mp_mul() failed");
}
elapsedTime1 = esp32elapsedTime();
}
if(mulmod) {
/* Z = X^Y mod M */
esp32TimerStart();
if(ret == 0 && (ret = mp_mulmod(&x, &y, &p, &z2)) != MP_OKAY) {
printf("(%d,%d) Xbits = %d, Ybits = %d Pbits = %d ret = %d\n",
i , j, Xbits, Ybits, Pbits, ret);
printf("X = %s Y = %s P = %s\n", mp_isodd(&x)==MP_YES?"ODD":"EVEN",
mp_isodd(&y)==MP_YES?"ODD":"EVEN",
mp_isodd(&p)==MP_YES?"ODD":"EVEN");
TEST_FAIL_MESSAGE("mp_mulmod() failed");
}
elapsedTime2 = esp32elapsedTime();
}
if(exptmod) {
/* Z = X^Y mod M */
esp32TimerStart();
if(ret == 0 && (ret = mp_exptmod(&x, &y, &p, &z3)) != MP_OKAY) {
printf("(%d,%d) Xbits = %d, Ybits = %d Pbits = %d ret = %d\n",
i , j, Xbits, Ybits, Pbits, ret);
printf("X = %s Y = %s P = %s\n", mp_isodd(&x)==MP_YES?"ODD":"EVEN",
mp_isodd(&y)==MP_YES?"ODD":"EVEN",
mp_isodd(&p)==MP_YES?"ODD":"EVEN");
TEST_FAIL_MESSAGE("mp_exptmod() failed");
}
elapsedTime3 = esp32elapsedTime()/1000;
}
printf("(%d,%d) Xbits = %d, Ybits = %d Pbits = %d",
i , j, Xbits, Ybits, Pbits);
if(mul) {
printf(" mul = %llu (us)", elapsedTime1);
}
if(mulmod) {
printf(" mulmod = %llu (us)\n", elapsedTime2);
}
if(exptmod) {
printf(" exptmod = %llu (ms)\n", elapsedTime3);
}
}
}
}
mp_clear(&z1);
mp_clear(&z2);
mp_clear(&z3);
mp_clear(&x);
mp_clear(&p);
mp_clear(&y);
wc_FreeRng(&rng);
return ret;
}
/* Z = X * Y */
int mp_unitest_mul(const char* strZ, const char* strX, const char* strY, int verbose)
{
int ret = 0;
char* buf;
char* bufZ;
int radixX_size;
int radixZ_size;
int radixY_size;
mp_int z, x, y;
/* set init mp_int */
if((ret = mp_init_multi(&z, &x, &y, NULL, NULL, NULL)) != MP_OKAY) {
TEST_FAIL_MESSAGE("mp_init failed.\n");
}
/* set big-numbers into mp_inits */
if(ret == 0 && mp_read_radix(&x, strX, 16) != MP_OKAY) {
ESP_LOGE(TAG,"failed to set strX into mp_init");
return -1;
}
if(ret == 0 && mp_read_radix(&y, strY, 16) != MP_OKAY) {
ESP_LOGE(TAG,"failed to set strY into mp_init");
return -1;
}
/* Z = X * Y */
if(ret == 0 && (ret = mp_mul(&x, &y, &z)) != MP_OKAY) {
TEST_FAIL_MESSAGE("mp_mul() failed\n");
}
mp_radix_size(&z, 16, &radixZ_size);
bufZ = (char*)XMALLOC(radixZ_size + 1, NULL, DYNAMIC_TYPE_TMP_BUFFER);
if(bufZ != NULL) {
mp_toradix(&z, bufZ, 16);
bufZ[radixZ_size] ='\0';
}
if(verbose) {
mp_dump("x_value", &x, 1);
mp_dump("y_value", &y, 1);
mp_dump("z_value", &z, 1);
mp_radix_size(&x, 16, &radixX_size);
mp_radix_size(&y, 16, &radixY_size);
radixX_size = max(radixX_size, radixY_size);
buf = (char*)XMALLOC(radixX_size + 1, NULL, DYNAMIC_TYPE_TMP_BUFFER);
if(buf != NULL) {
mp_toradix(&x, buf, 16);
buf[radixX_size] ='\0';
printf("X : %s ", buf);
mp_toradix(&y, buf, 16);
buf[radixY_size] ='\0';
printf("Y : %s ", buf);
}
if(bufZ != NULL) {
printf("Z : %s \n", bufZ);
}
XFREE(buf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
}
TEST_ASSERT_EQUAL_STRING_MESSAGE(strZ, bufZ,
"mp_mulmod returns an unexpected result.");
XFREE(bufZ, NULL, DYNAMIC_TYPE_TMP_BUFFER);
return 0;
}
int mp_unitest_mulmod(const char* strZ, const char* strX, const char* strY,
const char* strM, int verbose)
{
int ret = 0;
char* buf;
char* bufZ;
int radixX_size;
int radixZ_size;
int radixY_size;
int radixM_size;
mp_int z, x, y, m;
/* set init mp_int */
if((ret = mp_init_multi(&z, &x, &y, &m, NULL, NULL)) != MP_OKAY) {
TEST_FAIL_MESSAGE("mp_init failed.\n");
}
/* set big-numbers into mp_inits */
if(ret == 0 && mp_read_radix(&x, strX, 16) != MP_OKAY) {
ESP_LOGE(TAG,"failed to set strX into mp_init");
return -1;
}
if(ret == 0 && mp_read_radix(&y, strY, 16) != MP_OKAY) {
ESP_LOGE(TAG,"failed to set strY into mp_init");
return -1;
}
if(ret == 0 && mp_read_radix(&m, strM, 16) != MP_OKAY) {
ESP_LOGE(TAG,"failed to set strM into mp_init");
return -1;
}
/* Z = X^Y mod M */
if(ret == 0 && (ret = mp_mulmod(&x, &y, &m, &z)) != MP_OKAY) {
TEST_FAIL_MESSAGE("mp_mulmod() failed\n");
}
mp_radix_size(&z, 16, &radixZ_size);
bufZ = (char*)XMALLOC(radixZ_size + 1, NULL, DYNAMIC_TYPE_TMP_BUFFER);
if(bufZ != NULL) {
mp_toradix(&z, bufZ, 16);
bufZ[radixZ_size] ='\0';
}
if(verbose) {
mp_dump("x_value", &x, 1);
mp_dump("y_value", &y, 1);
mp_dump("m_value", &m, 1);
mp_dump("z_value", &z, 1);
mp_radix_size(&x, 16, &radixX_size);
mp_radix_size(&y, 16, &radixY_size);
mp_radix_size(&m, 16, &radixM_size);
radixX_size = max(radixX_size, max(radixY_size, radixM_size));
buf = (char*)XMALLOC(radixX_size + 1, NULL, DYNAMIC_TYPE_TMP_BUFFER);
if(buf != NULL) {
mp_toradix(&x, buf, 16);
buf[radixX_size] ='\0';
printf("X : %s ", buf);
mp_toradix(&y, buf, 16);
buf[radixY_size] ='\0';
printf("Y : %s ", buf);
mp_toradix(&m, buf, 16);
buf[radixM_size] ='\0';
printf("M : %s ", buf);
}
if(bufZ != NULL) {
printf("Z : %s \n", bufZ);
}
XFREE(buf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
}
TEST_ASSERT_EQUAL_STRING_MESSAGE(strZ, bufZ,
"mp_mulmod returns an unexpected result.");
XFREE(bufZ, NULL, DYNAMIC_TYPE_TMP_BUFFER);
return 0;
}
int mp_unitest_exptmod(const char* strZ, const char* strX, const char* strY,
const char* strM, int verbose)
{
int ret = 0;
char* buf;
char* bufZ;
int radixX_size;
int radixZ_size;
int radixY_size;
int radixM_size;
mp_int z, x, y, m;
/* set init mp_int */
if((ret = mp_init_multi(&z, &x, &y, &m, NULL, NULL)) != MP_OKAY) {
TEST_FAIL_MESSAGE("mp_init failed.\n");
}
/* set big-numbers into mp_inits */
if(ret == 0 && mp_read_radix(&x, strX, 16) != MP_OKAY) {
ESP_LOGE(TAG,"failed to set strX into mp_init");
return -1;
}
if(ret == 0 && mp_read_radix(&y, strY, 16) != MP_OKAY) {
ESP_LOGE(TAG,"failed to set strY into mp_init");
return -1;
}
if(ret == 0 && mp_read_radix(&m, strM, 16) != MP_OKAY) {
ESP_LOGE(TAG,"failed to set strM into mp_init");
return -1;
}
/* Z = X^Y mod M */
if(ret == 0 && (ret = mp_exptmod(&x, &y, &m, &z)) != MP_OKAY) {
TEST_FAIL_MESSAGE("mp_exptmod() failed\n");
}
mp_radix_size(&z, 16, &radixZ_size);
bufZ = (char*)XMALLOC(radixZ_size + 1, NULL, DYNAMIC_TYPE_TMP_BUFFER);
if(bufZ != NULL) {
mp_toradix(&z, bufZ, 16);
bufZ[radixZ_size] ='\0';
}
if(verbose) {
mp_dump("x_value", &x, 1);
mp_dump("y_value", &y, 1);
mp_dump("m_value", &m, 1);
mp_dump("z_value", &z, 1);
mp_radix_size(&x, 16, &radixX_size);
mp_radix_size(&y, 16, &radixY_size);
mp_radix_size(&m, 16, &radixM_size);
radixX_size = max(radixX_size, max(radixY_size, radixM_size));
buf = (char*)XMALLOC(radixX_size + 1, NULL, DYNAMIC_TYPE_TMP_BUFFER);
if(buf != NULL) {
mp_toradix(&x, buf, 16);
buf[radixX_size] ='\0';
printf("X : %s ", buf);
mp_toradix(&y, buf, 16);
buf[radixY_size] ='\0';
printf("Y : %s ", buf);
mp_toradix(&m, buf, 16);
buf[radixM_size] ='\0';
printf("M : %s ", buf);
}
if(bufZ != NULL) {
printf("Z : %s \n", bufZ);
}
XFREE(buf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
}
TEST_ASSERT_EQUAL_STRING_MESSAGE(strZ, bufZ,
"mp_exptmod returns an unexpected result.");
XFREE(bufZ, NULL, DYNAMIC_TYPE_TMP_BUFFER);
return 0;
}
TEST_CASE("wolfssl mp exptmod test" , "[wolfssl]")
{
ESP_LOGI(TAG, "mp test");
int verbose = 0;
TEST_ASSERT_EQUAL(0, mp_unitest_exptmod("2", "5", "1", "3", verbose));
TEST_ASSERT_EQUAL(0, mp_unitest_exptmod("1", "-5", "1", "3", verbose));
TEST_ASSERT_EQUAL(0, mp_unitest_exptmod("CE331E6D30A77A57", "1234", "A",
"FFFFFFFFFFFFFFFF", verbose));
TEST_ASSERT_EQUAL(0, mp_unitest_exptmod("1000000", "1000", "2", "FFFFFFF", verbose));
TEST_ASSERT_EQUAL(0, mp_unitest_exptmod("1000000", "2", "128",
"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", verbose));
TEST_ASSERT_EQUAL(0, mp_unitest_exptmod("14B5A90", "1234", "2", "FFFFFFF", verbose));
TEST_ASSERT_EQUAL(0, mp_unitest_exptmod("1234321", "1111", "2", "FFFFFFFF", verbose));
TEST_ASSERT_EQUAL(0, mp_unitest_exptmod("2", "5", "1", "3", verbose));
TEST_ASSERT_EQUAL(0, mp_unitest_exptmod("22", "55", "1", "33", verbose));
TEST_ASSERT_EQUAL(0, mp_unitest_exptmod("222", "555", "1", "333", verbose));
TEST_ASSERT_EQUAL(0, mp_unitest_exptmod("2222", "5555", "1", "3333", verbose));
TEST_ASSERT_EQUAL(0, mp_unitest_exptmod("11", "5555", "1", "33", verbose));
TEST_ASSERT_EQUAL(0, mp_unitest_exptmod("55", "1111", "1", "77", verbose));
TEST_ASSERT_EQUAL(0, mp_unitest_exptmod("88", "1111", "2", "BB", verbose));
}
TEST_CASE("wolfssl mp mulmod test" , "[wolfssl]")
{
ESP_LOGI(TAG, "mp test");
int verbose = 0;
/* Z X Y M */
TEST_ASSERT_EQUAL(0, mp_unitest_mulmod("2", "5", "1", "3", verbose));
TEST_ASSERT_EQUAL(0, mp_unitest_mulmod("1", "-5", "1", "3", verbose));
TEST_ASSERT_EQUAL(0, mp_unitest_mulmod("2", "-64", "A", "3", verbose));
TEST_ASSERT_EQUAL(0, mp_unitest_mulmod("74C3AC", "123456", "55555", "AAAAA1", verbose));
TEST_ASSERT_EQUAL(0, mp_unitest_mulmod("73A068", "123456", "55555", "AAAAA3", verbose));
mp_unitest_mulmod(
"10C530243ADE5EA7C557E9A2FF5B4573195665A89CB921F573267B15CD2BCB6467E925235AA752CC2D08B07D31497B497744CA3685A46E76247439826628589DD814AC9EEE9EF8B4B44BEE2DB6065BE3C51B788E4ECFF39FB28C3D8EBE10FC9989D97CDC6624E32EBD222E222A2E93085FC2D05E4EB73375F7FC7B11E9B3024",
"A4F780E83C3FAC34878787D4876BA7582E48C7637A26C6E720974FC7416150A3865D44F6D08E3DA38EB4296928C564D9A0008D8A0D63E0B8EF54D14D54FBEAB540E43D2ED6BE54806D9150C1944437CC3D8B2486A1FB932A6691B529E0E2A46524CB0825BA4F4E1B9C24554DB1913169E5373173A3B7CBBF77C3403C8C7AE86A",
"6520379E44C1A2C359342010E1038F8C3644D9A47A9346A80C92B48A6986872D74C3BDDB49B2D93C554B588D4A4448614FADBC066CC10F3EB20A2422EA857B7DD0BF60C9CB7D733B12761BD785BCD122D97ECA0A8F1D0F705BC094B66EE5C96712AE3B14B5AA6AD9E50C6A3020BA01DA4FB94E3934527ADCDB3DE51C368B37C2",
"BE7070B80418E528FE66D89088E0F1B7C3D0D23EE64B9474B0FFB0F763A5AB7EAFB62BB738161A50BFF1CA873AD5B0DAF8437A15B97EEA2A80D251B035AF07F3F25D243A4B8756481B3C249ADA7080BD3C8B034A0C8371DEE30370A2B760091B5EC73DA06460E3A9068DD3FF42BB0A94272D57420DB02DE0BA182560921192F3",
verbose);
TEST_ASSERT_EQUAL(0, mp_unitest_mulmod(
"76DBEC4349F316F82C27F59CD87378C83234E28C6E99990A5F9CDCF5A627CD1B2F405FA31AA0EAF7CB433B01D3592E5EF11134E4F8C8126D4DF33F4022A9A2A5B2FA1E6D25B66C628A9BE974136C823CE564E39D1ED099B5B401B8805DE19EFA776C6263265D6E9928714EBD74FFFFD89179BD594DCDC74F5687E311C26B613E539311DC310D36D04D831704524820DE3FC70BC2E43B929F9B4FF40DF4367B241095577C80B6BEB7F2BDE84282EEC9F9FE2A289E4115DB788803392C96A8A86A2FCABCBC6545BABB80F65CE2821C07DA899CEA8D172681F398341FC449D21630DDD0F100E28D351CFF2F2C4E2341B5851632FC6597E00149E98752A5895CDC41",
"1678D8E98C4A0BA91E0F8318A15A453A562B36A4EC315B445617CF93CD5287B0284FEE83EF0A5DBEFCEC1801E402D860C050CE24F74D715B57A9E0BE2D8F91FF61F7124983270F06A2E6A00E33A32E26A1A358B1B178C969D37BCB544ED8B3A0AF3BFEA5AB970AE7613ACF0B5C7B5B4AB578C96911752528DA7B3B40189E75C67EC3F6CEA16D5B53C5742FF3C425EB7C3F20D5198CC5B8CCAD0A2D59AD58DD88FB203396341456CF9415CEB3BFB1FB7B2CFE9599E755AB8FD55C5A8B9AD044E6E2DE44FC996297C3C900F76D118572EDF860F507B3C1AC3590B9B47AD85F9D930CEDE1DA1F0AE0DCF69D6DE44304FE22704C51262B9230D00A988438555F7EAF",
"3D76E6173983A5E1F98C04CDD512274E7259E7C26355A5BA7F067B343699E01D6FDE6A27E3D73B1BBFE2F32FC4B412F8D16F1F538D09227BEECDC9BFF1D05DCF0D28112209D3077C2F9E88BBE62AA7E61948172142B793E6AA65D11AFFF182F0D758609B113C45EF43934233767F0C2337853750892E4E45413C87D02D051DC4BAD0782724672E9C8AC888A2EFDDC5C3AC24B0BD846F473070C815A784B4E6C1E16F2F4428379E80AC9226CDE94C5141B316EA3573E64487EB460E80E888FF270A9AB06CD17447FE082C3F7B2809EAA20227E9AE1924978793947E67CB664D938E061F1CE4B1F36795ED7166022D8B35F3C671ECB77EA7B0AA481E1E0D575887",
"E98A5D15A4D434B959A2DAAF74C8C9032638FA48FC4D306EEA7689CE4FF687DE323A466E38125837220D80AC2DAF2F123E627360666890B26F4717042BCAB726B710C213F97A620A933290420D162EFAD729D79F54E4FC6574F8F6436B4E9E347FCB6B1C1ADE8281BF085D3FC0B6B1A8A59C8170A74E3287151C780EF018FEEB4B372BE9E1F7FA51C658B9D80603EDC00318558B98FEB1F6D03DFA63C03819C700EF4D9960B4BACEE3CED96B2D7694FFFB77184AFE65F00A915C3B229485D02018592EA53303AC1B5F78321125EE7F9621A9D676978D667EB291D0362EA31DBFF185EDC03E60B85A9FAB80E0EA5D5F7556C74D518ED41F34A636F1301F51992F",
verbose));
TEST_ASSERT_EQUAL(0, mp_unitest_mulmod(
"DBEE64C8091CF78EC926AF5D51E06FD92FE0007DA3AF33317D9E131F3CDE711AFB30F8F61E6ACF99EAD21822E4DBC2B31B910D7E357230F255DA6C90EEA36A1E926A7F44CF34FBE544C1DC30B8DF4D5735495FEB1D0E10827222B6AF069BCD3F66120C4A19D8D533E4222FE65FCB323CF993A8DB07B896F0D10AAF94A996EB9B",
"1572A17625B1609DB02793AEC41541DB2C9B0301EEF6805804945BA77656B207BF46F90762DEBB3E0057A43A95D09C6C852267E602FD3851D925323F875CB1E743818CBE17814D2DB4921BAA7DA2F8E5EFBD6373FF0E2020206BC89870F0B734AD3E331EB010CC713F09683165EC5BF551B3B70A497178EB926C0726EDDB2E37",
"773FB6148DC513087EC9C4EAD4BA0DA49EB36EDE1A7AF88988EF363C11BC83E8306C817C47F34DCAEA560162552E4B89A9BD6F01F67402AAE38466069534A1E2CA65FEA32D4397956C6FD5B438F6F99530FAF89C252BB61451CC2EB35BD6DC1AEC2D095B3F3AD0B84E271FDC2AEEACA9595D076311830BD47480B67D6245BF56",
"FF3011C23C6BB4D69E6BC193D148CE802DBEAFF7BAB2D7C3C4536E1502AA61B9EA059B79670BCED9FB988C1D6BF45AA7A05E5418E931447CC752D86DA03ED6142D7B159D1E398796DDA833552A8E32C0C4E5B8CBCD328DAD7BE5C67E4D6FF3A4C5A640BE903A336A24B2808112ACE37B2663CF88B9FF74233752F0C4275D451F",
verbose));
TEST_ASSERT_EQUAL(0, mp_unitest_mulmod(
"7C65",
"10000000000",
"555555",
"12345", verbose));
}
TEST_CASE("wolfssl mp mul test" , "[wolfssl]")
{
ESP_LOGI(TAG, "mp test");
int verbose = 0;
TEST_ASSERT_EQUAL(0, mp_unitest_mul("A", "5", "2", verbose));
TEST_ASSERT_EQUAL(0, mp_unitest_mul("-A", "-5", "2", verbose));
TEST_ASSERT_EQUAL(0, mp_unitest_mul("A", "-5", "-2", verbose));
TEST_ASSERT_EQUAL(0, mp_unitest_mul("6260060", "1234", "5678", verbose));
TEST_ASSERT_EQUAL(0, mp_unitest_mul("38E83", "123", "321", verbose));
TEST_ASSERT_EQUAL(0, mp_unitest_mul("75CD7FCBBC", "123456", "6789A", verbose));
TEST_ASSERT_EQUAL(0, mp_unitest_mul(
"19C26D7DC91D2123426ECCDB5A0290A9F7D9D01456D266BA549E859373D9D4FE0B4EDAE8763FA94458E4BED29CB7DD6CEF5C52136D2F310D2EABA373C750760EEE3FAE6EA618C60E9A4A0F2C3F3AC87612A0F032866F1CA4DA95CCCC47D2C51F",
"77BDC7B4C5616B142B7762251075BA95FB475D570179E730D418A9143D18905F",
"371280CB239B46A1BB0C036755ADF3C4474E1696FB2E70AA200225322C50270D44AE8490F24AA22D0FD9AE89EEF9449285FCED5FBC8F424A4A5E82DFEB3B0341",
verbose));
TEST_ASSERT_EQUAL(0, mp_unitest_mul(
"33676FE7B625BF0759F7E8932B6B50D5F45E16E1C670AD20F1CDA5DFFA433685937CA8422A9CB916CC8",
"165196BA298CD54975DC483C4D21A51EA0A146783CFB41522E76E50C",
"24D9D5CA7D9CCC06F5E70F1963E6",
verbose));
TEST_ASSERT_EQUAL(0, mp_unitest_mul(
"65D67946D0D9AB634DD18E5308A1F963C3AAE65F949A81C16C91B5B9DACE18A170ED73E3FC1F01EC8FF7D78EDD29B71FA00D9F5D8FF9116AA93E6F8F09DB306A8C1EEA42DCE9C8C9345B4B84E58CEED1F24A93B14FF47E81A766DF842A25BB941F3F07310C749B47E27C85D544FFE9021AB31AD3484AF40F738A04E9BCC0EFB6B36E56ABE76D982AD7B4D2527526F29B9CFD2A0F6570532C286EA7937354F1A6903480B4D8554E7ED707A08E07CAD5EB713752125163626CF52178574011072D2E536D126C2FF096505515FCA91B5BCEC2D765FC0A1AE90CC8F3C2E18529CF6647E4F732B1D16685189FE24148C752B3AF23F1D8481507CFB89DC1DC70E87B06748D4F1E32B489E1288FC5B02466C8395A59E92862F83F985D021B9C4C42B768BFD3FC81C189F7B88755EB879CF781EFC97C41D0ABB428F7351FA9D62A12A316FE2D2C24D8ECF87132D8476A1B0611793E9EFEE2ADDE1AB7116F69D7744150C770555C54B6BE88ECDD5CF33DF321147061FCB42BEF3D69663695FFD74D42493A",
"13DADD9D122C5264497863C0BC2A893CD6C951E94198ABC0DAFF499BE89C6A425548B15F582E714D866563E4ACC81197D5B95BF87BD960D3647E51764F31977BFE2D0A7A7727C27BF7B3134148F126B5F1F0F00730C172C76D768874006C6C86E82F8698621773ED0B91CCA997FBC712D788D384E7831F51A6DD4FB4819D26026",
"5210C04ED4FDF80D630BA81DCA6BA05495156D7DDBE1DEE0E057825F7FADACE70EBE4D5F82E51E465514DDC86E5B46DD780C182865A6C9E29F7456E3090229247BFC18094E31B15B1BE3A962601202D5C65979FF96CA64FB93F29110A76500DEB1003B6CEA2BA79CBAD007FA35610C43DE59FD0A22E07CA0A9943F6B101B4C9663AF0CADD26014586933AC536A917F4A62A31BD5EE8BFD452F63E4ED4D656DDC22D2413B44D02029887F7DC31200FD793C83F1927F306D00535EB1E0E8BEDA6486A41C509E8DB4369BC4D0C36767AA0127EC3E8C6EF4B5C07F2AD9FB51910B771F112A10F21128E26428B74F69586C486B04EEB64E84A36D4BD03C315B90CE8F",
verbose));
}
TEST_CASE("wolfssl mp mul performance test" , "[wolfssl]")
{
int mul = 0, mulmod = 0, exptmod = 0;
TEST_ASSERT_EQUAL(0, mp_performance_check(mul, mulmod, exptmod));
}
#endif/* !NO_RSA || HAVE_ECC */
TEST_CASE("wolfssl aes test" , "[wolfssl]")
{
ESP_LOGI(TAG, "aes test");
@ -158,10 +680,10 @@ TEST_CASE("wolfssl sha crypt-test", "[wolfssl]")
#ifndef NO_SHA
static void tskSha_Test(void *pvParam)
{
ESP_LOGI(TAG, "enter tskSha_Test");
int ret = 0;
ESP_LOGI(TAG, "enter tskSha_Test");
while(exit_loop==false) {
ret = sha_test();
if(ret != 0) {
@ -171,6 +693,7 @@ static void tskSha_Test(void *pvParam)
}
ESP_LOGI(TAG, "leave tskSha_Test");
xSemaphoreGive(exit_semaph);
vTaskDelete(NULL);
}
@ -179,9 +702,10 @@ static void tskSha_Test(void *pvParam)
#ifndef NO_SHA256
static void tskSha256_Test(void *pvParam)
{
ESP_LOGI(TAG, "enter tskSha256_Test");
int ret;
ESP_LOGI(TAG, "enter tskSha256_Test");
while(exit_loop==false) {
ret = sha256_test();
if(ret != 0) {
@ -191,6 +715,7 @@ static void tskSha256_Test(void *pvParam)
}
ESP_LOGI(TAG, "leave tskSha256_Test");
xSemaphoreGive(exit_semaph);
vTaskDelete(NULL);
}
@ -199,9 +724,10 @@ static void tskSha256_Test(void *pvParam)
#ifdef WOLFSSL_SHA384
static void tskSha384_Test(void *pvParam)
{
ESP_LOGI(TAG, "enter tskSha384_Test");
int ret = 0;
ESP_LOGI(TAG, "enter tskSha384_Test");
while(exit_loop==false) {
ret = sha384_test();
if(ret != 0) {
@ -211,6 +737,7 @@ static void tskSha384_Test(void *pvParam)
}
ESP_LOGI(TAG, "leave tskSha384_Test");
xSemaphoreGive(exit_semaph);
vTaskDelete(NULL);
}
@ -219,10 +746,10 @@ static void tskSha384_Test(void *pvParam)
#ifdef WOLFSSL_SHA512
static void tskSha512_Test(void *pvParam)
{
ESP_LOGI(TAG, "enter tskSha512_Test");
int ret = 0;
ESP_LOGI(TAG, "enter tskSha512_Test");
while(exit_loop==false) {
ret = sha512_test();
if(ret != 0) {
@ -230,17 +757,18 @@ static void tskSha512_Test(void *pvParam)
TEST_FAIL_MESSAGE("tskSha512_Test() failed\n");
}
}
ESP_LOGI(TAG, "leave tskSha512_test()");
xSemaphoreGive(exit_semaph);
vTaskDelete(NULL);
}
#endif
TEST_CASE("wolfssl sha multi-thread test ", "[wolfssl]")
{
int num = 0;
int i;
#ifndef NO_SHA
num++;
#endif
@ -271,21 +799,24 @@ TEST_CASE("wolfssl sha multi-thread test ", "[wolfssl]")
xTaskCreate(tskSha512_Test, "sha512_test", SHA_STACK_SIZE, NULL, 3, NULL);
#endif
ESP_LOGI(TAG, "Waiting for 10s ...");
vTaskDelay(10000/portTICK_PERIOD_MS);
exit_loop = true;
ESP_LOGI(TAG, "Waiting for 10s ...");
vTaskDelay(10000/portTICK_PERIOD_MS);
exit_loop = true;
for(i = 0;i < num;i++) {
if(!xSemaphoreTake(exit_semaph, 2000/portTICK_PERIOD_MS)) {
TEST_FAIL_MESSAGE("exit semaphore not released by test task");
}
}
vSemaphoreDelete(exit_semaph);
for(int i=0;i<num;i++){
if(!xSemaphoreTake(exit_semaph, 2000/portTICK_PERIOD_MS)) {
TEST_FAIL_MESSAGE("exit semaphore not released by test task");
}
}
vSemaphoreDelete(exit_semaph);
}
TEST_CASE("wolfssl aes multi-thread test ", "[wolfssl]")
{
int num = 0;
int i;
#ifndef NO_AES
num++;
num++;
@ -311,21 +842,24 @@ TEST_CASE("wolfssl aes multi-thread test ", "[wolfssl]")
xTaskCreate(tskAes256_Test, "Aes256_test", SHA_STACK_SIZE, NULL, 3, NULL);
#endif
ESP_LOGI(TAG, "Waiting for 10s ...");
vTaskDelay(10000/portTICK_PERIOD_MS);
exit_loop = true;
ESP_LOGI(TAG, "Waiting for 10s ...");
vTaskDelay(10000/portTICK_PERIOD_MS);
exit_loop = true;
for(int i=0;i<num;i++){
if(!xSemaphoreTake(exit_semaph, 2000/portTICK_PERIOD_MS)) {
TEST_FAIL_MESSAGE("exit semaphore not released by test task");
for(i = 0;i < num;i++){
if(!xSemaphoreTake(exit_semaph, 2000/portTICK_PERIOD_MS)) {
TEST_FAIL_MESSAGE("exit semaphore not released by test task");
}
}
}
vSemaphoreDelete(exit_semaph);
vSemaphoreDelete(exit_semaph);
}
TEST_CASE("wolfssl aes sha sha256 multi-thread test ", "[wolfssl]")
{
int num = 0;
int i;
#ifndef NO_AES
num++;
@ -414,7 +948,7 @@ TEST_CASE("wolfssl aes sha sha256 multi-thread test ", "[wolfssl]")
vTaskDelay(15000/portTICK_PERIOD_MS);
exit_loop = true;
for(int i=0;i<num;i++){
for(i = 0;i < num;i++){
if(!xSemaphoreTake(exit_semaph, 2000/portTICK_PERIOD_MS)) {
TEST_FAIL_MESSAGE("exit semaphore not released by test task");
}
@ -425,6 +959,7 @@ TEST_CASE("wolfssl aes sha sha256 multi-thread test ", "[wolfssl]")
TEST_CASE("wolfssl aes sha384 sha512 multi-thread test ", "[wolfssl]")
{
int num = 0;
int i;
#ifndef NO_AES
num++;
@ -515,7 +1050,88 @@ TEST_CASE("wolfssl aes sha384 sha512 multi-thread test ", "[wolfssl]")
exit_loop = true;
for(int i=0;i<num;i++){
for(i = 0;i < num;i++){
if(!xSemaphoreTake(exit_semaph, 2000/portTICK_PERIOD_MS)) {
TEST_FAIL_MESSAGE("exit semaphore not released by test task");
}
}
vSemaphoreDelete(exit_semaph);
}
TEST_CASE("wolfssl aes sha256 rsa multi-thread test ", "[wolfssl]")
{
int num = 0;
int i;
#ifndef NO_AES
num++;
num++;
#endif
#ifndef NO_SHA256
num++;
#endif
#ifndef NO_RSA
num++;
#endif
exit_loop = false;
#ifndef CONFIG_FREERTOS_UNICORE
num *= 2;
printf("num=%d\n", num);
exit_semaph = xSemaphoreCreateCounting(num, 0);
#ifndef NO_AES
if(xTaskCreatePinnedToCore(tskAes_Test, "Aes_test", SHA_STACK_SIZE, NULL, 3, NULL, 0)!=pdPASS)
ESP_LOGE(TAG, "failed to create task -1 \n");
if(xTaskCreatePinnedToCore(tskAes_Test, "Aes_test", SHA_STACK_SIZE, NULL, 3, NULL, 1)!=pdPASS)
ESP_LOGE(TAG, "failed to create task -2 \n");
if(xTaskCreatePinnedToCore(tskAesGcm_Test, "AesGcm_test", SHA_STACK_SIZE, NULL, 3, NULL, 0)!=pdPASS)
ESP_LOGE(TAG, "failed to create task -3 \n");
if(xTaskCreatePinnedToCore(tskAesGcm_Test, "AesGcm_test", SHA_STACK_SIZE, NULL, 3, NULL, 1)!=pdPASS)
ESP_LOGE(TAG, "failed to create task -4 \n");
#endif
#ifndef NO_SHA256
if(xTaskCreatePinnedToCore(tskSha256_Test, "sha256_test", SHA_STACK_SIZE, NULL, 3, NULL, 0)!=pdPASS)
ESP_LOGE(TAG, "failed to create task -5 \n");
if(xTaskCreatePinnedToCore(tskSha256_Test, "sha256_test", SHA_STACK_SIZE, NULL, 3, NULL, 1)!=pdPASS)
ESP_LOGE(TAG, "failed to create task -6 \n");
#endif
#ifndef NO_RSA
if(xTaskCreatePinnedToCore(tskRsa_Test, "rsa_test", SHA_STACK_SIZE, NULL, 3, NULL, 0)!=pdPASS)
ESP_LOGE(TAG, "failed to create task -7 \n");
if(xTaskCreatePinnedToCore(tskRsa_Test, "rsa_test", SHA_STACK_SIZE, NULL, 3, NULL, 1)!=pdPASS)
ESP_LOGE(TAG, "failed to create task -8 \n");
#endif
#else
exit_semaph = xSemaphoreCreateCounting(num, 0);
#ifndef NO_AES
xTaskCreate(tskAes_Test, "Aes_test", SHA_STACK_SIZE, NULL, 3, NULL);
xTaskCreate(tskAesGcm_Test, "AesGcm_test", SHA_STACK_SIZE, NULL, 3, NULL);
#endif
#ifndef NO_SHA256
xTaskCreate(tskSha256_Test, "sha256_test", SHA_STACK_SIZE, NULL, 3, NULL);
#endif
#ifndef NO_RSA
xTaskCreate(tskRsa_Test, "rsa_test", SHA_STACK_SIZE, NULL, 3, NULL);
#endif
#endif /* CONFIG_FREERTOS_UNICORE */
ESP_LOGI(TAG, "Waiting for 15s ...");
vTaskDelay(15000/portTICK_PERIOD_MS);
exit_loop = true;
/* wait until rsa test finishes */
while(rsa_elapsedTime<=0){ vTaskDelay(1); }
ESP_LOGI(TAG, "Waiting another %llu s. rsa test would take more time to finish.",
(rsa_elapsedTime+3000)/portTICK_PERIOD_MS);
vTaskDelay((rsa_elapsedTime+3000)/portTICK_PERIOD_MS);
for(i = 0;i < num;i++){
if(!xSemaphoreTake(exit_semaph, 2000/portTICK_PERIOD_MS)) {
TEST_FAIL_MESSAGE("exit semaphore not released by test task");
}

View File

@ -54,6 +54,16 @@
/* #define CUSTOM_SLOT_ALLOCATION */
#endif
/* rsa primitive specific definition */
#if defined(WOLFSSL_ESPWROOM32) || defined(WOLFSSL_ESPWROOM32SE)
/* Define USE_FAST_MATH and SMALL_STACK */
#define ESP32_USE_RSA_PRIMITIVE
/* threshold for performance adjustment for hw primitive use */
/* X bits of G^X mod P greater than */
#define EPS_RSA_EXPT_XBTIS 36
/* X and Y of X * Y mod P greater than */
#define ESP_RSA_MULM_BITS 2000
#endif
/* debug options */
/* #define DEBUG_WOLFSSL */
@ -70,3 +80,4 @@
/* #define NO_ESP32WROOM32_CRYPT */
/* #define NO_WOLFSSL_ESP32WROOM32_CRYPT_HASH*/
/* #define NO_WOLFSSL_ESP32WROOM32_CRYPT_AES */
/* #define NO_WOLFSSL_ESP32WROOM32_CRYPT_RSA_PRI */

View File

@ -71,7 +71,9 @@ EXTRA_DIST += wolfcrypt/src/port/ti/ti-aes.c \
wolfcrypt/src/port/mynewt/mynewt_port.c \
wolfcrypt/src/port/Espressif/esp32_aes.c \
wolfcrypt/src/port/Espressif/esp32_sha.c \
wolfcrypt/src/port/Espressif/esp32_util.c
wolfcrypt/src/port/Espressif/esp32_util.c \
wolfcrypt/src/port/Espressif/esp32_mp.c \
wolfcrypt/src/port/Espressif/README.md
if BUILD_CRYPTOCB

View File

@ -1,8 +1,6 @@
# ESP32 Port
Support for the ESP32-WROOM-32 on-board crypto hardware acceleration for symmetric AES and SHA1/SHA256/SHA384/SHA512.
NOTE: RSA has not supported yet.
Support for the ESP32-WROOM-32 on-board crypto hardware acceleration for symmetric AES, SHA1/SHA256/SHA384/SHA512 and RSA primitive including mul, mulmod and exptmod.
## ESP32 Acceleration
@ -18,12 +16,14 @@ Uncomment out #define WOLFSSL_ESPWROOM32 in /path/to/wolfssl/wolfssl/wolfcrypt/s
To disable portions of the hardware acceleration you can optionally define:
```
/* Disabled SHA and AES acceleration */
/* Disabled SHA, AES and RSA acceleration */
#define NO_ESP32WROOM32_CRYPT
/* Disabled AES acceleration */
#define NO_WOLFSSL_ESP32WROOM32_CRYPT_AES
/* Disabed SHA acceleration */
/* Disabled SHA acceleration */
#define NO_WOLFSSL_ESP32WROOM32_CRYPT_HASH
/* Disabled RSA Primitive acceleration */
#define NO_WOLFSSL_ESP32WROOM32_CRYPT_RSA_PRI
```
### Coding
@ -33,8 +33,9 @@ In your application you must include <wolfssl/wolfcrypt/settings.h> before any o
### Benchmarks
Software only implementation :
w/ USE_FAST_MATH and WOLFSSL_SMALL_STACK options
Software only implementation :
```
AES-128-CBC-enc 1 MB took 1.001 seconds, 1.146 MB/s
@ -44,45 +45,57 @@ AES-192-CBC-dec 1 MB took 1.006 seconds, 1.019 MB/s
AES-256-CBC-enc 1000 KB took 1.000 seconds, 1000.000 KB/s
AES-256-CBC-dec 975 KB took 1.007 seconds, 968.222 KB/s
AES-128-GCM-enc 350 KB took 1.055 seconds, 331.754 KB/s
AES-128-GCM-dec 350 KB took 1.055 seconds, 331.754 KB/s
AES-128-GCM-dec 350 KB took 1.054 seconds, 332.068 KB/s
AES-192-GCM-enc 325 KB took 1.013 seconds, 320.829 KB/s
AES-192-GCM-dec 325 KB took 1.013 seconds, 320.829 KB/s
AES-256-GCM-enc 325 KB took 1.041 seconds, 312.200 KB/s
AES-256-GCM-dec 325 KB took 1.041 seconds, 312.200 KB/s
SHA 6 MB took 1.003 seconds, 5.720 MB/s
SHA-256 2 MB took 1.003 seconds, 2.483 MB/s
SHA-384 1 MB took 1.002 seconds, 1.218 MB/s
SHA-512 1 MB took 1.000 seconds, 1.221 MB/s
HMAC-SHA 6 MB took 1.000 seconds, 5.664 MB/s
HMAC-SHA256 2 MB took 1.002 seconds, 2.461 MB/s
HMAC-SHA384 1 MB took 1.017 seconds, 1.200 MB/s
HMAC-SHA512 1 MB took 1.017 seconds, 1.200 MB/s
SHA 6 MB took 1.004 seconds, 5.714 MB/s
SHA-256 2 MB took 1.006 seconds, 1.747 MB/s
SHA-384 1 MB took 1.011 seconds, 1.159 MB/s
SHA-512 1 MB took 1.009 seconds, 1.161 MB/s
HMAC-SHA 6 MB took 1.001 seconds, 5.634 MB/s
HMAC-SHA256 2 MB took 1.000 seconds, 1.733 MB/s
HMAC-SHA384 1 MB took 1.004 seconds, 1.046 MB/s
HMAC-SHA512 1 MB took 1.002 seconds, 1.048 MB/s
RSA 2048 public 16 ops took 1.056 sec, avg 66.000 ms, 15.152 ops/sec
RSA 2048 private 2 ops took 2.488 sec, avg 1244.000 ms, 0.804 ops/sec
ECC 256 key gen 4 ops took 1.101 sec, avg 275.250 ms, 3.633 ops/sec
ECDHE 256 agree 4 ops took 1.098 sec, avg 274.500 ms, 3.643 ops/sec
ECDSA 256 sign 4 ops took 1.111 sec, avg 277.750 ms, 3.600 ops/sec
ECDSA 256 verify 2 ops took 1.099 sec, avg 549.500 ms, 1.820 ops/sec
```
Hardware Acceleration :
```
AES-128-CBC-enc 6 MB took 1.002 seconds, 6.018 MB/s
AES-128-CBC-dec 5 MB took 1.002 seconds, 5.336 MB/s
AES-192-CBC-enc 6 MB took 1.003 seconds, 6.012 MB/s
AES-192-CBC-dec 5 MB took 1.004 seconds, 5.325 MB/s
AES-256-CBC-enc 6 MB took 1.003 seconds, 6.012 MB/s
AES-256-CBC-dec 5 MB took 1.004 seconds, 5.325 MB/s
AES-128-GCM-enc 350 KB took 1.001 seconds, 349.650 KB/s
AES-128-GCM-dec 350 KB took 1.001 seconds, 349.650 KB/s
AES-192-GCM-enc 350 KB took 1.015 seconds, 344.828 KB/s
AES-192-GCM-dec 350 KB took 1.015 seconds, 344.828 KB/s
AES-256-GCM-enc 350 KB took 1.022 seconds, 342.466 KB/s
AES-256-GCM-dec 350 KB took 1.022 seconds, 342.466 KB/s
SHA 14 MB took 1.001 seconds, 14.073 MB/s
SHA-256 15 MB took 1.000 seconds, 15.259 MB/s
SHA-384 18 MB took 1.000 seconds, 17.529 MB/s
SHA-512 18 MB took 1.000 seconds, 17.529 MB/s
HMAC-SHA 14 MB took 1.001 seconds, 13.805 MB/s
HMAC-SHA256 15 MB took 1.000 seconds, 14.966 MB/s
HMAC-SHA384 17 MB took 1.000 seconds, 16.968 MB/s
HMAC-SHA512 17 MB took 1.001 seconds, 16.951 MB/s
AES-128-CBC-enc 6 MB took 1.004 seconds, 5.958 MB/s
AES-128-CBC-dec 5 MB took 1.002 seconds, 5.287 MB/s
AES-192-CBC-enc 6 MB took 1.004 seconds, 5.958 MB/s
AES-192-CBC-dec 5 MB took 1.002 seconds, 5.287 MB/s
AES-256-CBC-enc 6 MB took 1.001 seconds, 5.951 MB/s
AES-256-CBC-dec 5 MB took 1.004 seconds, 5.277 MB/s
AES-128-GCM-enc 375 KB took 1.067 seconds, 351.453 KB/s
AES-128-GCM-dec 375 KB took 1.067 seconds, 351.453 KB/s
AES-192-GCM-enc 350 KB took 1.010 seconds, 346.535 KB/s
AES-192-GCM-dec 350 KB took 1.009 seconds, 346.878 KB/s
AES-256-GCM-enc 350 KB took 1.016 seconds, 344.488 KB/s
AES-256-GCM-dec 350 KB took 1.016 seconds, 344.488 KB/s
SHA 14 MB took 1.000 seconds, 14.062 MB/s
SHA-256 15 MB took 1.000 seconds, 15.234 MB/s
SHA-384 17 MB took 1.000 seconds, 17.383 MB/s
SHA-512 18 MB took 1.001 seconds, 17.512 MB/s
HMAC-SHA 14 MB took 1.000 seconds, 13.818 MB/s
HMAC-SHA256 15 MB took 1.001 seconds, 14.951 MB/s
HMAC-SHA384 17 MB took 1.001 seconds, 16.683 MB/s
HMAC-SHA512 17 MB took 1.000 seconds, 16.943 MB/s
RSA 2048 public 20 ops took 1.017 sec, avg 50.850 ms, 19.666 ops/sec
RSA 2048 private 4 ops took 1.059 sec, avg 264.750 ms, 3.777 ops/sec
ECC 256 key gen 4 ops took 1.092 sec, avg 273.000 ms, 3.663 ops/sec
ECDHE 256 agree 4 ops took 1.089 sec, avg 272.250 ms, 3.673 ops/sec
ECDSA 256 sign 4 ops took 1.101 sec, avg 275.250 ms, 3.633 ops/sec
ECDSA 256 verify 2 ops took 1.092 sec, avg 546.000 ms, 1.832 ops/sec
```
Condition :

View File

@ -47,7 +47,7 @@ static int espaes_CryptHwMutexInit = 0;
static int esp_aes_hw_InUse()
{
int ret = 0;
ESP_LOGV(TAG, "enter esp_aes_hw_InUse");
if(espaes_CryptHwMutexInit == 0) {
@ -94,7 +94,7 @@ static void esp_aes_hw_Set_KeyMode(Aes *ctx, ESP32_AESPROCESS mode)
{
int i;
word32 mode_ = 0;
ESP_LOGV(TAG, "enter esp_aes_hw_Set_KeyMode");
/* check mode */
@ -131,13 +131,13 @@ static void esp_aes_hw_Set_KeyMode(Aes *ctx, ESP32_AESPROCESS mode)
}
/*
* Porcess a one block of AES
* Process a one block of AES
*/
static void esp_aes_bk(const byte* in, byte* out)
{
const word32 *inwords = (const word32 *)in;
word32 *outwords = (word32 *)out;
ESP_LOGV(TAG, "enter esp_aes_bk");
/* copy text for encrypting/decrypting blocks */
@ -220,7 +220,7 @@ int wc_esp32AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
word32 blocks = (sz / AES_BLOCK_SIZE);
byte *iv;
byte temp_block[AES_BLOCK_SIZE];
ESP_LOGV(TAG, "enter wc_esp32AesCbcEncrypt");
iv = (byte*)aes->reg;
@ -268,7 +268,7 @@ int wc_esp32AesCbcDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
byte temp_block[AES_BLOCK_SIZE];
ESP_LOGV(TAG, "enter wc_esp32AesCbcDecrypt");
iv = (byte*)aes->reg;
esp_aes_hw_InUse();

View File

@ -0,0 +1,514 @@
/* esp32_mp.c
*
* Copyright (C) 2006-2019 wolfSSL Inc.
*
* This file is part of wolfSSL.
*
* wolfSSL is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* wolfSSL is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
*/
#include <string.h>
#include <stdio.h>
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <wolfssl/wolfcrypt/settings.h>
#include "wolfssl/wolfcrypt/logging.h"
#if !defined(NO_RSA) || defined(HAVE_ECC)
#if defined(WOLFSSL_ESP32WROOM32_CRYPT_RSA_PRI) && \
!defined(NO_WOLFSSL_ESP32WROOM32_CRYPT_RSA_PRI)
#ifdef NO_INLINE
#include <wolfssl/wolfcrypt/misc.h>
#else
#define WOLFSSL_MISC_INCLUDED
#include <wolfcrypt/src/misc.c>
#endif
#include <wolfssl/wolfcrypt/tfm.h>
static const char* const TAG = "wolfssl_mp";
#define ESP_HW_RSAMAX_BIT 4096
#define ESP_HW_MULTI_RSAMAX_BITS 2048
#define ESP_HW_RSAMIN_BIT 512
#define BYTE_TO_WORDS(s) (((s+3)>>2)) /* (s+(4-1))/ 4 */
#define BITS_TO_WORDS(s) (((s+31)>>3)>>2) /* (s+(32-1))/ 8/ 4*/
#define MP_NG -1
/* mutex */
static wolfSSL_Mutex mp_mutex;
static int espmp_CryptHwMutexInit = 0;
/*
* check if the hw is ready before accessing it
*/
static int esp_mp_hw_wait_clean()
{
int timeout = 0;
while(++timeout < ESP_RSA_TIMEOUT && DPORT_REG_READ(RSA_CLEAN_REG) != 1){}
if(timeout >= ESP_RSA_TIMEOUT) {
ESP_LOGE(TAG, "waiting hw ready is time-outed.");
return MP_NG;
}
return MP_OKAY;
}
/*
* lock hw engine.
* this should be called before using engine.
*/
static int esp_mp_hw_lock()
{
int ret = 0;
if(espmp_CryptHwMutexInit == 0) {
ret = esp_CryptHwMutexInit(&mp_mutex);
if(ret == 0){
espmp_CryptHwMutexInit = 1;
} else {
ESP_LOGE(TAG, "mp mutx initialization failed.");
return MP_NG;
}
}
/* lock hardware */
ret = esp_CryptHwMutexLock(&mp_mutex, portMAX_DELAY);
if(ret != 0) {
ESP_LOGE(TAG, "mp engine lock failed.");
return MP_NG;
}
/* Enable RSA hardware */
periph_module_enable(PERIPH_RSA_MODULE);
return ret;
}
/*
* Release hw engine
*/
static void esp_mp_hw_unlock( void )
{
/* Disable RSA hardware */
periph_module_disable(PERIPH_RSA_MODULE);
/* unlock */
esp_CryptHwMutexUnLock(&mp_mutex);
}
/* this is based on an article by Cetin Kaya Koc, A New Algorithm for Inversion*/
/* mod p^k, June 28 2017. */
static int esp_calc_Mdash(mp_int *M, word32 k, mp_digit* md)
{
int i;
int xi;
int b0 = 1;
int bi;
word32 N = 0;
word32 x;
N = M->dp[0];
bi = b0;
x = 0;
for(i = 0; i < k; i++) {
xi = bi % 2;
if(xi < 0){
xi *= -1;
}
bi = (bi - N * xi) / 2;
x |= (xi << i);
}
/* 2's complement */
*md = ~x + 1;
return MP_OKAY;
}
/* start hw process */
static void process_start(word32 reg)
{
/* clear interrupt */
DPORT_REG_WRITE(RSA_INTERRUPT_REG, 1);
/* start process */
DPORT_REG_WRITE(reg, 1);
}
/* wait until done */
static int wait_uitil_done(word32 reg)
{
int timeout = 0;
/* wait until done && not timeout */
while(1) {
if(++timeout < ESP_RSA_TIMEOUT && DPORT_REG_READ(reg) == 1){
break;
}
}
/* clear interrupt */
DPORT_REG_WRITE(RSA_INTERRUPT_REG, 1);
if(timeout >= ESP_RSA_TIMEOUT) {
ESP_LOGE(TAG, "rsa operation is time-outed.");
return MP_NG;
}
return MP_OKAY;
}
/* read data from memory into mp_init */
static void esp_memblock_to_mpint(word32 mem_address, mp_int* mp, word32 numwords)
{
esp_dport_access_read_buffer((uint32_t*)mp->dp, mem_address, numwords);
mp->used = numwords;
}
/* write mp_init into memory block */
static void esp_mpint_to_memblock(word32 mem_address, const mp_int* mp,
const word32 bits,
const word32 hwords)
{
word32 i;
word32 len = (bits / 8 + ((bits & 7) != 0 ? 1 : 0));
len = (len+sizeof(word32)-1)/sizeof(word32);
for(i=0;i < hwords; i++) {
if(i < len) {
DPORT_REG_WRITE(mem_address + (i * sizeof(word32)), mp->dp[i]);
} else {
DPORT_REG_WRITE(mem_address + (i * sizeof(word32)), 0);
}
}
}
/* return needed hw words. */
/* supported words length */
/* words : {16 , 32, 48, 64, 80, 96, 112, 128} */
/* bits : {512,1024, 1536, 2048, 2560, 3072, 3584, 4096} */
static word32 words2hwords(word32 wd)
{
const word32 shit_ = 4;
return (((wd + 0xf)>>shit_)<<shit_);
}
/* count the number of words is needed for bits */
static word32 bits2words(word32 bits)
{
/* 32 bits */
const word32 d = sizeof(word32) * WOLFSSL_BIT_SIZE;
return((bits + (d - 1))/d);
}
/* get rinv */
static int esp_get_rinv(mp_int *rinv, mp_int *M, word32 exp)
{
int ret = 0;
/* 2^(exp)*/
if((ret = mp_2expt(rinv, exp)) != MP_OKAY) {
ESP_LOGE(TAG, "failed to calculate mp_2expt()");
return ret;
}
/* r_inv = R^2 mod M(=P) */
if(ret == 0 && (ret = mp_mod(rinv, M, rinv)) != MP_OKAY){
ESP_LOGE(TAG, "failed to calculate mp_mod()");
return ret;
}
return ret;
}
/* Z = X * Y; */
int esp_mp_mul(fp_int* X, fp_int* Y, fp_int* Z)
{
int ret = 0;
int neg = (X->sign == Y->sign)? MP_ZPOS : MP_NEG;
word32 Xs;
word32 Ys;
word32 Zs;
word32 maxWords_sz;
word32 hwWords_sz;
/* ask bits number */
Xs = mp_count_bits(X);
Ys = mp_count_bits(Y);
Zs = Xs + Ys;
/* maximum bits and words for writing to hw */
maxWords_sz = bits2words(max(Xs, Ys));
hwWords_sz = words2hwords(maxWords_sz);
/* sanity check */
if((hwWords_sz<<5) > ESP_HW_MULTI_RSAMAX_BITS) {
ESP_LOGW(TAG, "exceeds max bit length(2048)");
return -2;
}
/*Steps to use hw in the following order:
* 1. wait until clean hw engine
* 2. Write(2*N/512bits - 1 + 8) to MULT_MODE_REG
* 3. Write X and Y to memory blocks
* need to write data to each memory block only according to the length
* of the number.
* 4. Write 1 to MUL_START_REG
* 5. Wait for the first operation to be done. Poll INTERRUPT_REG until it reads 1.
* (Or until the INTER interrupt is generated.)
* 6. Write 1 to RSA_INTERRUPT_REG to clear the interrupt.
* 7. Read the Z from RSA_Z_MEM
* 8. Write 1 to RSA_INTERUPT_REG to clear the interrupt.
* 9. Release the hw engine
*/
/* lock hw for use */
if((ret = esp_mp_hw_lock()) != MP_OKAY)
return ret;
if((ret = esp_mp_hw_wait_clean()) != MP_OKAY){
return ret;
}
/* step.1 (2*N/512) => N/256. 512 bits => 16 words */
DPORT_REG_WRITE(RSA_MULT_MODE_REG, (hwWords_sz >> 3) - 1 + 8);
/* step.2 write X, M and r_inv into memory */
esp_mpint_to_memblock(RSA_MEM_X_BLOCK_BASE, X, Xs, hwWords_sz);
/* Y(let-extend) */
esp_mpint_to_memblock(RSA_MEM_Z_BLOCK_BASE + (hwWords_sz<<2), Y, Ys, hwWords_sz);
/* step.3 start process */
process_start(RSA_MULT_START_REG);
/* step.4,5 wait until done */
wait_uitil_done(RSA_INTERRUPT_REG);
/* step.6 read the result form MEM_Z */
esp_memblock_to_mpint(RSA_MEM_Z_BLOCK_BASE, Z, BITS_TO_WORDS(Zs));
/* step.7 clear and release hw */
esp_mp_hw_unlock();
Z->sign = (Z->used > 0)? neg : MP_ZPOS;
return ret;
}
/* Z = X * Y (mod M) */
int esp_mp_mulmod(fp_int* X, fp_int* Y, fp_int* M, fp_int* Z)
{
int ret = 0;
int negcheck = 0;
word32 Xs;
word32 Ys;
word32 Ms;
word32 maxWords_sz;
word32 hwWords_sz;
word32 zwords;
mp_int r_inv;
mp_int tmpZ;
mp_digit mp;
/* neg check */
if(X->sign != Y->sign) {
/* X*Y becomes negative */
negcheck = 1;
}
/* ask bits number */
Xs = mp_count_bits(X);
Ys = mp_count_bits(Y);
Ms = mp_count_bits(M);
/* maximum bits and words for writing to hw */
maxWords_sz = bits2words(max(Xs, max(Ys, Ms)));
zwords = bits2words(min(Ms, Xs + Ys));
hwWords_sz = words2hwords(maxWords_sz);
if((hwWords_sz<<5) > ESP_HW_RSAMAX_BIT) {
ESP_LOGE(TAG, "exceeds hw maximum bits");
return -2;
}
/* calculate r_inv = R^2 mode M
* where: R = b^n, and b = 2^32
* accordinalry R^2 = 2^(n*32*2)
*/
ret = mp_init_multi(&tmpZ, &r_inv, NULL, NULL, NULL, NULL);
if(ret == 0 && (ret = esp_get_rinv(&r_inv, M, (hwWords_sz<<6))) != MP_OKAY) {
ESP_LOGE(TAG, "calcurate r_inv failed.");
mp_clear(&tmpZ);
mp_clear(&r_inv);
return ret;
}
/* lock hw for use */
if((ret = esp_mp_hw_lock()) != MP_OKAY){
mp_clear(&tmpZ);
mp_clear(&r_inv);
return ret;
}
/* Calculate M' */
if((ret = esp_calc_Mdash(M, 32/* bits */, &mp)) != MP_OKAY) {
ESP_LOGE(TAG, "failed to calculate M dash");
mp_clear(&tmpZ);
mp_clear(&r_inv);
return -1;
}
/*Steps to use hw in the following order:
* 1. wait until clean hw engine
* 2. Write(N/512bits - 1) to MULT_MODE_REG
* 3. Write X,M(=G, X, P) to memory blocks
* need to write data to each memory block only according to the length
* of the number.
* 4. Write M' to M_PRIME_REG
* 5. Write 1 to MODEXP_START_REG
* 6. Wait for the first operation to be done. Poll INTERRUPT_REG until it reads 1.
* (Or until the INTER interrupt is generated.)
* 7. Write 1 to RSA_INTERRUPT_REG to clear the interrupt.
* 8. Write Y to RSA_X_MEM
* 9. Write 1 to RSA_MULT_START_REG
* 10. Wait for the second operation to be completed. Poll INTERRUPT_REG until it reads 1.
* 11. Read the Z from RSA_Z_MEM
* 12. Write 1 to RSA_INTERUPT_REG to clear the interrupt.
* 13. Release the hw engine
*/
if((ret = esp_mp_hw_wait_clean()) != MP_OKAY){
return ret;
}
/* step.1 512 bits => 16 words */
DPORT_REG_WRITE(RSA_MULT_MODE_REG, (hwWords_sz >> 4) - 1);
/* step.2 write X, M and r_inv into memory */
esp_mpint_to_memblock(RSA_MEM_X_BLOCK_BASE, X, Xs, hwWords_sz);
esp_mpint_to_memblock(RSA_MEM_M_BLOCK_BASE, M, Ms, hwWords_sz);
esp_mpint_to_memblock(RSA_MEM_Z_BLOCK_BASE, &r_inv, mp_count_bits(&r_inv),
hwWords_sz);
/* step.3 write M' into memory */
DPORT_REG_WRITE(RSA_M_DASH_REG, mp);
/* step.4 start process */
process_start(RSA_MULT_START_REG);
/* step.5,6 wait until done */
wait_uitil_done(RSA_INTERRUPT_REG);
/* step.7 Y to MEM_X */
esp_mpint_to_memblock(RSA_MEM_X_BLOCK_BASE, Y, Ys, hwWords_sz);
/* step.8 start process */
process_start(RSA_MULT_START_REG);
/* step.9,11 wait until done */
wait_uitil_done(RSA_INTERRUPT_REG);
/* step.12 read the result from MEM_Z */
esp_memblock_to_mpint(RSA_MEM_Z_BLOCK_BASE, &tmpZ, zwords);
/* step.13 clear and release hw */
esp_mp_hw_unlock();
/* additional steps */
/* this needs for known issue when Z is greather than M */
if(mp_cmp(&tmpZ, M)==FP_GT) {
/* Z -= M */
mp_sub(&tmpZ, M, &tmpZ);
}
if(negcheck) {
mp_sub(M, &tmpZ, &tmpZ);
}
mp_copy(&tmpZ, Z);
mp_clear(&tmpZ);
mp_clear(&r_inv);
return ret;
}
/* Z = X^Y mod M */
int esp_mp_exptmod(fp_int* X, fp_int* Y, word32 Ys, fp_int* M, fp_int* Z)
{
int ret = 0;
word32 Xs;
word32 Ms;
word32 maxWords_sz;
word32 hwWords_sz;
mp_int r_inv;
mp_digit mp;
/* ask bits number */
Xs = mp_count_bits(X);
Ms = mp_count_bits(M);
/* maximum bits and words for writing to hw */
maxWords_sz = bits2words(max(Xs, max(Ys, Ms)));
hwWords_sz = words2hwords(maxWords_sz);
if((hwWords_sz<<5) > ESP_HW_RSAMAX_BIT) {
ESP_LOGE(TAG, "exceeds hw maximum bits");
return -2;
}
/* calculate r_inv = R^2 mode M
* where: R = b^n, and b = 2^32
* accordingly R^2 = 2^(n*32*2)
*/
ret = mp_init(&r_inv);
if(ret == 0 && (ret = esp_get_rinv(&r_inv, M, (hwWords_sz<<6))) != MP_OKAY) {
ESP_LOGE(TAG, "calculate r_inv failed.");
mp_clear(&r_inv);
return ret;
}
/* lock and init the hw */
if((ret = esp_mp_hw_lock()) != MP_OKAY) {
mp_clear(&r_inv);
return ret;
}
/* calc M' */
/* if Pm is odd, uses mp_montgomery_setup() */
if((ret = esp_calc_Mdash(M, 32/* bits */, &mp)) != MP_OKAY) {
ESP_LOGE(TAG, "failed to calculate M dash");
mp_clear(&r_inv);
return -1;
}
/*Steps to use hw in the following order:
* 1. Write(N/512bits - 1) to MODEXP_MODE_REG
* 2. Write X, Y, M and r_inv to memory blocks
* need to write data to each memory block only according to the length
* of the number.
* 3. Write M' to M_PRIME_REG
* 4. Write 1 to MODEXP_START_REG
* 5. Wait for the operation to be done. Poll INTERRUPT_REG until it reads 1.
* (Or until the INTER interrupt is generated.)
* 6. Read the result Z(=Y) from Z_MEM
* 7. Write 1 to INTERRUPT_REG to clear the interrupt.
*/
if((ret = esp_mp_hw_wait_clean()) != MP_OKAY){
return ret;
}
/* step.1 */
DPORT_REG_WRITE(RSA_MODEXP_MODE_REG, (hwWords_sz >> 4) - 1);
/* step.2 write G, X, P, r_inv and M' into memory */
esp_mpint_to_memblock(RSA_MEM_X_BLOCK_BASE, X, Xs, hwWords_sz);
esp_mpint_to_memblock(RSA_MEM_Y_BLOCK_BASE, Y, Ys, hwWords_sz);
esp_mpint_to_memblock(RSA_MEM_M_BLOCK_BASE, M, Ms, hwWords_sz);
esp_mpint_to_memblock(RSA_MEM_Z_BLOCK_BASE, &r_inv, mp_count_bits(&r_inv),
hwWords_sz);
/* step.3 write M' into memory */
DPORT_REG_WRITE(RSA_M_DASH_REG, mp);
/* step.4 start process */
process_start(RSA_START_MODEXP_REG);
/* step.5 wait until done */
wait_uitil_done(RSA_INTERRUPT_REG);
/* step.6 read a result form memory */
esp_memblock_to_mpint(RSA_MEM_Z_BLOCK_BASE, Z, BITS_TO_WORDS(Ms));
/* step.7 clear and release hw */
esp_mp_hw_unlock();
mp_clear(&r_inv);
return ret;
}
#endif /* !NO_RSA || HAVE_ECC */
#endif /* (WOLFSS_ESP32WROOM32_CRYPT) && (NO_WOLFSSL_ESP32WROOM32_CRYPT_RES_PRI)*/

View File

@ -118,7 +118,7 @@ int esp_sha_try_hw_lock(WC_ESP32SHA* ctx)
int ret = 0;
ESP_LOGV(TAG, "enter esp_sha_hw_lock");
/* Init mutex */
#if defined(SINGLE_THREADED)
if(ctx->mode == ESP32_SHA_INIT) {
@ -151,7 +151,7 @@ int esp_sha_try_hw_lock(WC_ESP32SHA* ctx)
ctx->mode = ESP32_SHA_HW;
} else {
ESP_LOGI(TAG, "someone used. hw is locked.....");
ESP_LOGI(TAG, "the rest of operaion will use sw implementation for this sha");
ESP_LOGI(TAG, "the rest of operation will use sw implementation for this sha");
ctx->mode = ESP32_SHA_SW;
return 0;
}
@ -209,7 +209,7 @@ static void esp_process_block(WC_ESP32SHA* ctx, word32 address,
const word32* data, word32 len)
{
int i;
ESP_LOGV(TAG, "enter esp_process_block");
/* check if there are any busy engine */
@ -224,7 +224,7 @@ static void esp_process_block(WC_ESP32SHA* ctx, word32 address,
ESP_LOGV(TAG, "leave esp_process_block");
}
/*
* retreive sha digest from memory
* retrieve sha digest from memory
*/
static void esp_digest_state(WC_ESP32SHA* ctx, byte* hash, enum SHA_TYPE sha_type)
{
@ -239,7 +239,7 @@ static void esp_digest_state(WC_ESP32SHA* ctx, byte* hash, enum SHA_TYPE sha_typ
ESP_LOGE(TAG, "unexpected error. sha_type is invalid.");
return;
}
SHA_LOAD_REG += (sha_type << 4);
SHA_BUSY_REG += (sha_type << 4);
@ -284,9 +284,9 @@ int esp_sha_process(struct wc_Sha* sha)
int ret = 0;
ESP_LOGV(TAG, "enter esp_sha_process");
word32 SHA_START_REG = SHA_1_START_REG;
esp_process_block(&sha->ctx, SHA_START_REG, sha->buffer,
WC_SHA_BLOCK_SIZE);
@ -299,7 +299,7 @@ int esp_sha_process(struct wc_Sha* sha)
int esp_sha_digest_process(struct wc_Sha* sha, byte blockproc)
{
int ret = 0;
ESP_LOGV(TAG, "enter esp_sha_digest_process");
if(blockproc) {
@ -326,9 +326,9 @@ int esp_sha256_process(struct wc_Sha256* sha)
{
int ret = 0;
word32 SHA_START_REG = SHA_1_START_REG;
ESP_LOGV(TAG, "enter esp_sha256_process");
/* start register offset */
SHA_START_REG += (SHA2_256 << 4);
@ -345,7 +345,7 @@ int esp_sha256_process(struct wc_Sha256* sha)
int esp_sha256_digest_process(struct wc_Sha256* sha, byte blockproc)
{
int ret = 0;
ESP_LOGV(TAG, "enter esp_sha256_digest_process");
if(blockproc) {
@ -398,21 +398,21 @@ void esp_sha512_block(struct wc_Sha512* sha, const word32* data, byte isfinal)
ESP_LOGV(TAG, "leave esp_sha512_block");
}
/*
* sha512 proess. this is used for sha384 too.
* sha512 process. this is used for sha384 too.
*/
int esp_sha512_process(struct wc_Sha512* sha)
{
word32 *data = (word32*)sha->buffer;
ESP_LOGV(TAG, "enter esp_sha512_process");
esp_sha512_block(sha, data, 0);
ESP_LOGV(TAG, "leave esp_sha512_process");
return 0;
}
/*
* retreive sha512 digest. this is used for sha384 too.
* retrieve sha512 digest. this is used for sha384 too.
*/
int esp_sha512_digest_process(struct wc_Sha512* sha, byte blockproc)
{

View File

@ -60,7 +60,7 @@ void wc_esp32TimerStart()
uint64_t wc_esp32elapsedTime()
{
/* retturn elapsed time since wc_esp32AesTimeStart() is called in us */
/* return elapsed time since wc_esp32AesTimeStart() is called in us */
return esp_timer_get_time() - startTime;
}

View File

@ -516,7 +516,6 @@ static int InitSha256(wc_Sha256* sha256)
}
int wc_InitSha256_ex(wc_Sha256* sha256, void* heap, int devId)
{
WOLFSSL_ENTER("wc_InitSha256_ex");
int ret = 0;
if (sha256 == NULL)
@ -529,7 +528,6 @@ static int InitSha256(wc_Sha256* sha256)
ret = InitSha256(sha256);
WOLFSSL_LEAVE("wc_InitSha256_ex", ret);
return ret;
}
#else

View File

@ -203,6 +203,12 @@ int fp_mul(fp_int *A, fp_int *B, fp_int *C)
int ret = 0;
int y, yy, oldused;
#if defined(WOLFSSL_ESP32WROOM32_CRYPT_RSA_PRI) && \
!defined(NO_WOLFSSL_ESP32WROOM32_CRYPT_RSA_PRI)
ret = esp_mp_mul(A, B, C);
if(ret != -2) return ret;
#endif
oldused = C->used;
y = MAX(A->used, B->used);
@ -1824,11 +1830,24 @@ static int _fp_exptmod(fp_int * G, fp_int * X, fp_int * P, fp_int * Y)
int fp_exptmod(fp_int * G, fp_int * X, fp_int * P, fp_int * Y)
{
#if defined(WOLFSSL_ESP32WROOM32_CRYPT_RSA_PRI) && \
!defined(NO_WOLFSSL_ESP32WROOM32_CRYPT_RSA_PRI)
int x = fp_count_bits (X);
#endif
/* prevent overflows */
if (P->used > (FP_SIZE/2)) {
return FP_VAL;
}
#if defined(WOLFSSL_ESP32WROOM32_CRYPT_RSA_PRI) && \
!defined(NO_WOLFSSL_ESP32WROOM32_CRYPT_RSA_PRI)
if(x > EPS_RSA_EXPT_XBTIS) {
return esp_mp_exptmod(G, X, x, P, Y);
}
#endif
if (X->sign == FP_NEG) {
#ifndef POSITIVE_EXP_ONLY /* reduce stack if assume no negatives */
int err;
@ -3001,7 +3020,16 @@ int wolfcrypt_mp_mulmod (mp_int * a, mp_int * b, mp_int * c, mp_int * d)
int mp_mulmod (mp_int * a, mp_int * b, mp_int * c, mp_int * d)
#endif
{
return fp_mulmod(a, b, c, d);
#if defined(WOLFSSL_ESP32WROOM32_CRYPT_RSA_PRI) && \
!defined(NO_WOLFSSL_ESP32WROOM32_CRYPT_RSA_PRI)
int A = fp_count_bits (a);
int B = fp_count_bits (b);
if( A >= ESP_RSA_MULM_BITS && B >= ESP_RSA_MULM_BITS)
return esp_mp_mulmod(a, b, c, d);
else
#endif
return fp_mulmod(a, b, c, d);
}
/* d = a - b (mod c) */

View File

@ -27,7 +27,7 @@
#ifdef WOLFSSL_ESP32WROOM32_CRYPT_DEBUG
#undef LOG_LOCAL_LEVEL
#define LOG_LOCAL_LEVEL ESP_LOG_VERBOSE
#define LOG_LOCAL_LEVEL ESP_LOG_DEBUG
#else
#undef LOG_LOCAL_LEVEL
#define LOG_LOCAL_LEVEL ESP_LOG_ERROR
@ -117,6 +117,22 @@ int esp_sha_process(struct wc_Sha* sha);
#endif
#endif /* NO_SHA && */
#if !defined(NO_RSA) || defined(HAVE_ECC)
#ifndef ESP_RSA_TIMEOUT
#define ESP_RSA_TIMEOUT 0xFFFFF
#endif
struct fp_int;
int esp_mp_mul(struct fp_int* X, struct fp_int* Y, struct fp_int* Z);
int esp_mp_exptmod(struct fp_int* G, struct fp_int* X, word32 Xbits, struct fp_int* P,
struct fp_int* Y);
int esp_mp_mulmod(struct fp_int* X, struct fp_int* Y, struct fp_int* M,
struct fp_int* Z);
#endif /* NO_RSA || HAVE_ECC*/
#ifdef __cplusplus
}
#endif

View File

@ -242,14 +242,18 @@
#define TFM_TIMING_RESISTANT
#define ECC_TIMING_RESISTANT
#define WC_RSA_BLINDING
#if defined(WOLFSSL_ESPWROOM32) || defined(WOLFSSL_ESPWROOM32SE)
#ifndef NO_ESP32WROOM32_CRYPT
#define WOLFSSL_ESP32WROOM32_CRYPT
#endif
#if defined(ESP32_USE_RSA_PRIMITIVE) && \
!defined(NO_WOLFSSL_ESP32WROOM32_CRYPT_RSA_PRI)
#define WOLFSSL_ESP32WROOM32_CRYPT_RSA_PRI
#define USE_FAST_MATH
#define WOLFSSL_SMALL_STACK
#endif
#endif
#endif
#if !defined(WOLFSSL_USER_SETTINGS)
#define HAVE_ECC
#endif /* !WOLFSSL_USER_SETTINGS */
#endif /* WOLFSSL_ESPIDF */
#if defined(HAVE_LWIP_NATIVE) /* using LwIP native TCP socket */