From 165cb443e7e79d65e3bfba2283e311929f3d567d Mon Sep 17 00:00:00 2001 From: Elms Date: Mon, 26 Oct 2020 09:30:11 -0700 Subject: [PATCH 01/20] Micrium v5.8 support * OS error type change from uc OS3 to v5 * detect if network or TCP is available * XMEMCMP change workaround --- wolfcrypt/src/wc_port.c | 25 +++++++++++++++++-------- wolfcrypt/test/test.c | 13 +++++++++---- wolfssl/wolfcrypt/settings.h | 28 ++++++++++++++++++++++------ 3 files changed, 48 insertions(+), 18 deletions(-) diff --git a/wolfcrypt/src/wc_port.c b/wolfcrypt/src/wc_port.c index 165bc4a70..2d5d6186b 100644 --- a/wolfcrypt/src/wc_port.c +++ b/wolfcrypt/src/wc_port.c @@ -1232,14 +1232,23 @@ int wolfSSL_CryptHwMutexUnLock(void) } #elif defined(MICRIUM) + #if (OS_VERSION < 50000) + #define MICRIUM_ERR_TYPE OS_ERR + #define MICRIUM_ERR_NONE OS_ERR_NONE + #define MICRIUM_ERR_CODE(err) err + #else + #define MICRIUM_ERR_TYPE RTOS_ERR + #define MICRIUM_ERR_NONE RTOS_ERR_NONE + #define MICRIUM_ERR_CODE(err) RTOS_ERR_CODE_GET(err) + #endif int wc_InitMutex(wolfSSL_Mutex* m) { - OS_ERR err; + MICRIUM_ERR_TYPE err; OSMutexCreate(m, "wolfSSL Mutex", &err); - if (err == OS_ERR_NONE) + if (MICRIUM_ERR_CODE(err) == MICRIUM_ERR_NONE) return 0; else return BAD_MUTEX_E; @@ -1248,11 +1257,11 @@ int wolfSSL_CryptHwMutexUnLock(void) int wc_FreeMutex(wolfSSL_Mutex* m) { #if (OS_CFG_MUTEX_DEL_EN == DEF_ENABLED) - OS_ERR err; + MICRIUM_ERR_TYPE err; OSMutexDel(m, OS_OPT_DEL_ALWAYS, &err); - if (err == OS_ERR_NONE) + if (MICRIUM_ERR_CODE(err) == MICRIUM_ERR_NONE) return 0; else return BAD_MUTEX_E; @@ -1263,11 +1272,11 @@ int wolfSSL_CryptHwMutexUnLock(void) int wc_LockMutex(wolfSSL_Mutex* m) { - OS_ERR err; + MICRIUM_ERR_TYPE err; OSMutexPend(m, 0, OS_OPT_PEND_BLOCKING, NULL, &err); - if (err == OS_ERR_NONE) + if (MICRIUM_ERR_CODE(err) == MICRIUM_ERR_NONE) return 0; else return BAD_MUTEX_E; @@ -1275,11 +1284,11 @@ int wolfSSL_CryptHwMutexUnLock(void) int wc_UnLockMutex(wolfSSL_Mutex* m) { - OS_ERR err; + MICRIUM_ERR_TYPE err; OSMutexPost(m, OS_OPT_POST_NONE, &err); - if (err == OS_ERR_NONE) + if (MICRIUM_ERR_CODE(err) == MICRIUM_ERR_NONE) return 0; else return BAD_MUTEX_E; diff --git a/wolfcrypt/test/test.c b/wolfcrypt/test/test.c index cd85a33a5..383e80c86 100644 --- a/wolfcrypt/test/test.c +++ b/wolfcrypt/test/test.c @@ -80,10 +80,15 @@ _Pragma("GCC diagnostic ignored \"-Wunused-function\""); #define printf printk #elif defined(MICRIUM) - #include - void BSP_Ser_Printf (CPU_CHAR* format, ...); - #undef printf - #define printf BSP_Ser_Printf + #include + #if (OS_VERSION < 50000) + #include + void BSP_Ser_Printf (CPU_CHAR* format, ...); + #undef printf + #define printf BSP_Ser_Printf + #else + #include + #endif #elif defined(WOLFSSL_PB) #include int wolfssl_pb_print(const char*, ...); diff --git a/wolfssl/wolfcrypt/settings.h b/wolfssl/wolfcrypt/settings.h index a4614f01b..6d24a643e 100644 --- a/wolfssl/wolfcrypt/settings.h +++ b/wolfssl/wolfcrypt/settings.h @@ -1391,11 +1391,14 @@ extern void uITRON4_free(void *p) ; #ifdef MICRIUM #include #include - #include - #include - #include + #if defined(RTOS_MODULE_NET_AVAIL) || (APP_CFG_TCPIP_EN == DEF_ENABLED) + #include + #include + #include + #endif #include #include + #include #define USE_FAST_MATH #define TFM_TIMING_RESISTANT @@ -1449,10 +1452,23 @@ extern void uITRON4_free(void *p) ; (CPU_SIZE_T)(size))) #define XMEMCPY(pdest, psrc, size) ((void)Mem_Copy((void *)(pdest), \ (void *)(psrc), (CPU_SIZE_T)(size))) - #define XMEMCMP(pmem_1, pmem_2, size) \ - (((CPU_BOOLEAN)Mem_Cmp((void *)(pmem_1), \ - (void *)(pmem_2), \ + + #if (OS_VERSION < 50000) + #define XMEMCMP(pmem_1, pmem_2, size) \ + (((CPU_BOOLEAN)Mem_Cmp((void *)(pmem_1), \ + (void *)(pmem_2), \ (CPU_SIZE_T)(size))) ? DEF_NO : DEF_YES) + #else + // Work aroud for Micrium OS version 5.8 change in behavior + // that returns DEF_NO for 0 size compare + #define XMEMCMP(pmem_1, pmem_2, size) \ + (( (size < 1 ) || \ + ((CPU_BOOLEAN)Mem_Cmp((void *)(pmem_1), \ + (void *)(pmem_2), \ + (CPU_SIZE_T)(size)) == DEF_YES)) \ + ? 0 : 1) + #endif + #define XMEMMOVE XMEMCPY #if (OS_CFG_MUTEX_EN == DEF_DISABLED) From 0cbf8c7f28674b3dda6836d919d5a1ca614e7e52 Mon Sep 17 00:00:00 2001 From: Elms Date: Mon, 26 Oct 2020 21:28:51 -0700 Subject: [PATCH 02/20] Micrium: readme url fix and add additional link to k70 example with TCP --- IDE/ECLIPSE/MICRIUM/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/IDE/ECLIPSE/MICRIUM/README.md b/IDE/ECLIPSE/MICRIUM/README.md index 73747edcb..7f5c81d4d 100644 --- a/IDE/ECLIPSE/MICRIUM/README.md +++ b/IDE/ECLIPSE/MICRIUM/README.md @@ -1,7 +1,7 @@ # Micrium μC/OS-III Port ## Overview -You can enable the wolfSSL support for Micrium μC/OS-III RTOS available [here](http://www.micriums.com/) using the define `MICRIUM`. +You can enable the wolfSSL support for Micrium μC/OS-III RTOS available [here](http://www.micrium.com/) using the define `MICRIUM`. ## Usage @@ -72,7 +72,7 @@ The test results below were collected from the NXP Kinetis K70 (Freescale TWR-K7 - IAR Embedded Workbench IDE - ARM 8.32.1 (IAR ELF Linker V8.32.1.169/W32 for ARM) -- The starting project is based on an IAR EWARM project from Micrium download center at [micrium_twr-k70f120m-os3/](https://www.micrium.com/download/micrium_twr-k70f120m-os3/) but the K70X_FLASH.icf linker script file was slightly modified to configure the stack and heap sizes to 16KB and 20KB. The test was run on a 1 MBytes of program flash and 128 KBytes of static RAM. +- The starting project is based on an IAR EWARM project from Micrium download center at [micrium_twr-k70f120m-os3/](https://www.micrium.com/download/micrium_twr-k70f120m-os3/) but the K70X_FLASH.icf linker script file was slightly modified to configure the stack and heap sizes to 16KB and 20KB. The test was run on a 1 MBytes of program flash and 128 KBytes of static RAM. ([Similar TCP version](https://www.micrium.com/download/twr-k70f120m_os3-tcpip-wifi-lib/)) - wolfssl [latest version](https://github.com/wolfSSL/wolfssl) From 6e21f547ff3f9045ab5c958fcc65356bf42e5ba6 Mon Sep 17 00:00:00 2001 From: Elms Date: Thu, 12 Nov 2020 11:21:48 -0800 Subject: [PATCH 03/20] Micrium: fix compiler warnings --- wolfcrypt/src/wc_port.c | 1 + wolfssl/wolfcrypt/settings.h | 1 + 2 files changed, 2 insertions(+) diff --git a/wolfcrypt/src/wc_port.c b/wolfcrypt/src/wc_port.c index 2d5d6186b..cc3d1e0fa 100644 --- a/wolfcrypt/src/wc_port.c +++ b/wolfcrypt/src/wc_port.c @@ -1266,6 +1266,7 @@ int wolfSSL_CryptHwMutexUnLock(void) else return BAD_MUTEX_E; #else + (void)m; return 0; #endif } diff --git a/wolfssl/wolfcrypt/settings.h b/wolfssl/wolfcrypt/settings.h index 6d24a643e..15b99fa2e 100644 --- a/wolfssl/wolfcrypt/settings.h +++ b/wolfssl/wolfcrypt/settings.h @@ -1398,6 +1398,7 @@ extern void uITRON4_free(void *p) ; #endif #include #include + #include #include #define USE_FAST_MATH From 1899a72d2790f482b6ed52f9db6679a70783b369 Mon Sep 17 00:00:00 2001 From: Elms Date: Tue, 17 Nov 2020 10:55:01 -0800 Subject: [PATCH 04/20] Micrium: benchmark fixes * Time update for v5.8 to avoid rollover issues * define `XSNPRINTF` * `printf` based on Micrium version --- wolfcrypt/benchmark/benchmark.c | 25 ++++++++++++++++++++----- wolfssl/wolfcrypt/settings.h | 2 ++ 2 files changed, 22 insertions(+), 5 deletions(-) diff --git a/wolfcrypt/benchmark/benchmark.c b/wolfcrypt/benchmark/benchmark.c index dee2727bd..bdcaa7222 100644 --- a/wolfcrypt/benchmark/benchmark.c +++ b/wolfcrypt/benchmark/benchmark.c @@ -64,10 +64,12 @@ #undef printf #define printf printx #elif defined(MICRIUM) - #include - void BSP_Ser_Printf (CPU_CHAR* format, ...); - #undef printf - #define printf BSP_Ser_Printf + #if (OS_VERSION < 50000) + #include + void BSP_Ser_Printf (CPU_CHAR* format, ...); + #undef printf + #define printf BSP_Ser_Printf + #endif #elif defined(WOLFSSL_ZEPHYR) #include #define BENCH_EMBEDDED @@ -6027,10 +6029,23 @@ exit_ed_verify: #elif defined(MICRIUM) double current_time(int reset) { - CPU_ERR err; +#if (OS_VERSION < 50000) + CPU_ERR err; (void)reset; return (double) CPU_TS_Get32()/CPU_TS_TmrFreqGet(&err); +#else + RTOS_ERR err; + double ret = 0; + OS_TICK tick = OSTimeGet(&err); + OS_RATE_HZ rate = OSTimeTickRateHzGet(&err); + (void)reset; + + if (RTOS_ERR_CODE_GET(err) == RTOS_ERR_NONE) { + ret = ((double)tick)/rate; + } + return ret; +#endif } #elif defined(WOLFSSL_ZEPHYR) diff --git a/wolfssl/wolfcrypt/settings.h b/wolfssl/wolfcrypt/settings.h index 15b99fa2e..06b1eb3aa 100644 --- a/wolfssl/wolfcrypt/settings.h +++ b/wolfssl/wolfcrypt/settings.h @@ -1399,6 +1399,7 @@ extern void uITRON4_free(void *p) ; #include #include #include + #include #include #define USE_FAST_MATH @@ -1468,6 +1469,7 @@ extern void uITRON4_free(void *p) ; (void *)(pmem_2), \ (CPU_SIZE_T)(size)) == DEF_YES)) \ ? 0 : 1) + #define XSNPRINTF snprintf #endif #define XMEMMOVE XMEMCPY From 79c31a5f2c809d110410e20f1733876056fcafeb Mon Sep 17 00:00:00 2001 From: Elms Date: Fri, 6 Nov 2020 12:20:03 -0800 Subject: [PATCH 05/20] SiLbs: SHA and AES-{GCM,CBC} hardware acceleration using se_manager --- wolfcrypt/src/aes.c | 21 ++ wolfcrypt/src/include.am | 3 + wolfcrypt/src/port/silabs/README.md | 52 ++++ wolfcrypt/src/port/silabs/silabs_aes.c | 164 +++++++++++ wolfcrypt/src/port/silabs/silabs_hash.c | 305 ++++++++++++++++++++ wolfcrypt/src/sha.c | 9 + wolfcrypt/src/sha256.c | 19 +- wolfcrypt/src/sha512.c | 20 +- wolfcrypt/test/test.c | 11 +- wolfssl/wolfcrypt/aes.h | 8 + wolfssl/wolfcrypt/include.am | 2 + wolfssl/wolfcrypt/port/silabs/silabs_aes.h | 54 ++++ wolfssl/wolfcrypt/port/silabs/silabs_hash.h | 66 +++++ wolfssl/wolfcrypt/sha.h | 5 + wolfssl/wolfcrypt/sha256.h | 5 + wolfssl/wolfcrypt/sha512.h | 8 + 16 files changed, 745 insertions(+), 7 deletions(-) create mode 100644 wolfcrypt/src/port/silabs/README.md create mode 100644 wolfcrypt/src/port/silabs/silabs_aes.c create mode 100644 wolfcrypt/src/port/silabs/silabs_hash.c create mode 100644 wolfssl/wolfcrypt/port/silabs/silabs_aes.h create mode 100644 wolfssl/wolfcrypt/port/silabs/silabs_hash.h diff --git a/wolfcrypt/src/aes.c b/wolfcrypt/src/aes.c index 6dedc68a9..2a773a0ec 100644 --- a/wolfcrypt/src/aes.c +++ b/wolfcrypt/src/aes.c @@ -2598,6 +2598,9 @@ static void wc_AesDecrypt(Aes* aes, const byte* inBlock, byte* outBlock) #elif defined(WOLFSSL_DEVCRYPTO_AES) /* implemented in wolfcrypt/src/port/devcrypto/devcrypto_aes.c */ +#elif defined(WOLFSSL_SILABS_SE_ACCEL) + /* implemented in wolfcrypt/src/port/silabs/silabs_hash.c */ + #else /* Software AES - SetKey */ @@ -3530,6 +3533,9 @@ int wc_AesSetIV(Aes* aes, const byte* iv) #elif defined(WOLFSSL_DEVCRYPTO_CBC) /* implemented in wolfcrypt/src/port/devcrypt/devcrypto_aes.c */ +#elif defined(WOLFSSL_SILABS_SE_ACCEL) + /* implemented in wolfcrypt/src/port/silabs/silabs_hash.c */ + #else /* Software AES - CBC Encrypt */ @@ -6307,6 +6313,14 @@ int wc_AesGcmEncrypt(Aes* aes, byte* out, const byte* in, word32 sz, } #endif /* WOLFSSL_ASYNC_CRYPT */ +#ifdef WOLFSSL_SILABS_SE_ACCEL + return wc_AesGcmEncrypt_silabs( + aes, out, in, sz, + iv, ivSz, + authTag, authTagSz, + authIn, authInSz); +#endif + #ifdef STM32_CRYPTO_AES_GCM return wc_AesGcmEncrypt_STM32( aes, out, in, sz, iv, ivSz, @@ -6780,6 +6794,13 @@ int wc_AesGcmDecrypt(Aes* aes, byte* out, const byte* in, word32 sz, } #endif /* WOLFSSL_ASYNC_CRYPT */ +#ifdef WOLFSSL_SILABS_SE_ACCEL + return wc_AesGcmDecrypt_silabs( + aes, out, in, sz, iv, ivSz, + authTag, authTagSz, authIn, authInSz); + +#endif + #ifdef STM32_CRYPTO_AES_GCM /* The STM standard peripheral library API's doesn't support partial blocks */ return wc_AesGcmDecrypt_STM32( diff --git a/wolfcrypt/src/include.am b/wolfcrypt/src/include.am index 5eb41df96..faaae81ae 100644 --- a/wolfcrypt/src/include.am +++ b/wolfcrypt/src/include.am @@ -67,6 +67,9 @@ EXTRA_DIST += wolfcrypt/src/port/ti/ti-aes.c \ wolfcrypt/src/port/caam/caam_init.c \ wolfcrypt/src/port/caam/caam_sha.c \ wolfcrypt/src/port/caam/caam_doc.pdf \ + wolfcrypt/src/port/silabs/silabs_aes.c \ + wolfcrypt/src/port/silabs/silabs_hash.c \ + wolfcrypt/src/port/silabs/README.md \ wolfcrypt/src/port/st/stm32.c \ wolfcrypt/src/port/st/stsafe.c \ wolfcrypt/src/port/st/README.md \ diff --git a/wolfcrypt/src/port/silabs/README.md b/wolfcrypt/src/port/silabs/README.md new file mode 100644 index 000000000..ddd5f7baf --- /dev/null +++ b/wolfcrypt/src/port/silabs/README.md @@ -0,0 +1,52 @@ +# Silicon Labs (sliabs) Port + +Support for the ERF32 Gecko + * Series 2 device config 1 (Secure Element) + https://docs.silabs.com/mcu/latest/efr32mg21/group-SE + https://docs.silabs.com/mcu/latest/efr32bg21/group-SE + https://docs.silabs.com/mcu/5.9/efr32bg21/group-SE + https://docs.silabs.com/mcu/5.9/efr32mg21/group-SE + + +For details see our [](https://www.wolfssl.com/docs/) + + +### Building + +To enable support define one of the following: + +``` +#define WOLFSSL_SILABS_SE_ACCEL +``` + +### Coding + +In your application you must include +before any other wolfSSL headers. If building the sources directly we +recommend defining `WOLFSSL_USER_SETTINGS` and adding your own +`user_settings.h` file. You can find a good reference for this in +`IDE/GCC-ARM/Header/user_settings.h`. + + +### Benchmarks + +See our [benchmarks](https://www.wolfssl.com/docs/benchmarks/) on the wolfSSL website. + +### Benchmarks and Memory Use + +Software only implementation (ERF32, Fast Math): + +``` +``` + +Memory Use: + +``` +Peak Stack: +Peak Heap: +Total: +``` + +## Support + +Email us at [support@wolfssl.com](mailto:support@wolfssl.com). diff --git a/wolfcrypt/src/port/silabs/silabs_aes.c b/wolfcrypt/src/port/silabs/silabs_aes.c new file mode 100644 index 000000000..bca443b59 --- /dev/null +++ b/wolfcrypt/src/port/silabs/silabs_aes.c @@ -0,0 +1,164 @@ +/* silabs_aes.c + * + * Copyright (C) 2006-2020 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 + */ + +/* Generic SILABS Series2 AES support Function */ + +#ifdef HAVE_CONFIG_H + #include +#endif + + +#include + +#if defined(WOLFSSL_SILABS_SE_ACCEL) + + +#include +#include +#include + + +int wc_AesSetKey(Aes* aes, const byte* userKey, word32 keylen, + const byte* iv, int dir) +{ + sl_se_command_context_t cc = SL_SE_COMMAND_CONTEXT_INIT; + int ret = 0; + (void)dir; + + ret = sl_se_init(); + if (ret != SL_STATUS_OK) { + return BUFFER_E; + } + + XMEMSET(aes, 0, sizeof(aes)); + + if (keylen > sizeof(aes->key)) { + return BAD_FUNC_ARG; + } + + ret = wc_AesSetIV(aes, iv); + aes->rounds = keylen/4 + 6; + aes->ctx.cmd_ctx = cc; + + XMEMSET(&(aes->ctx.key), 0, sizeof(sl_se_key_descriptor_t)); + + aes->ctx.key.storage.method = SL_SE_KEY_STORAGE_EXTERNAL_PLAINTEXT; + switch(keylen) { + case 128/8: + aes->ctx.key.type = SL_SE_KEY_TYPE_AES_128; + break; +#ifdef WOLFSSL_AES_192 + case 192/8: + aes->ctx.key.type = SL_SE_KEY_TYPE_AES_192; + break; +#endif +#ifdef WOLFSSL_AES_256 + case 256/8: + aes->ctx.key.type = SL_SE_KEY_TYPE_AES_256; + break; +#endif + default: + ret = BAD_FUNC_ARG; + break; + } + + + XMEMCPY(aes->key, userKey, keylen); + aes->ctx.key.storage.location.buffer.pointer = (void*)aes->key; + aes->ctx.key.storage.location.buffer.size = keylen; + aes->ctx.key.size = keylen; + + return ret; +} + +int wc_AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz) +{ + sl_status_t status = sl_se_aes_crypt_cbc( + &(aes->ctx.cmd_ctx), + &(aes->ctx.key), + SL_SE_ENCRYPT, + sz, + (uint8_t*)aes->reg, + in, + out); + return (status != SL_STATUS_OK); +} + +int wc_AesCbcDecrypt(Aes* aes, byte* out, const byte* in, word32 sz) +{ + sl_status_t status = sl_se_aes_crypt_cbc( + &(aes->ctx.cmd_ctx), + &(aes->ctx.key), + SL_SE_DECRYPT, + sz, + (uint8_t*)aes->reg, + in, + out); + return (status != SL_STATUS_OK); +} + +#ifdef HAVE_AESGCM +int wc_AesGcmEncrypt_silabs (Aes* aes, byte* out, const byte* in, word32 sz, + const byte* iv, word32 ivSz, + byte* authTag, word32 authTagSz, + const byte* authIn, word32 authInSz) +{ + sl_status_t status = sl_se_gcm_crypt_and_tag( + &(aes->ctx.cmd_ctx), + &(aes->ctx.key), + SL_SE_ENCRYPT, + sz, + iv, + ivSz, + authIn, + authInSz, + in, + out, + authTagSz, + authTag); + + return (status != SL_STATUS_OK) ? AES_GCM_AUTH_E : 0; +} + +int wc_AesGcmDecrypt_silabs (Aes* aes, byte* out, const byte* in, word32 sz, + const byte* iv, word32 ivSz, + const byte* authTag, word32 authTagSz, + const byte* authIn, word32 authInSz) +{ + sl_status_t status = sl_se_gcm_auth_decrypt( + &(aes->ctx.cmd_ctx), + &(aes->ctx.key), + sz, + iv, + ivSz, + authIn, + authInSz, + in, + out, + authTagSz, + (byte*)authTag); + + return (status != SL_STATUS_OK) ? AES_GCM_AUTH_E : 0; +} + +#endif /* HAVE_AESGCM */ + +#endif /* WOLFSSL_SILABS_SE_ACCEL */ diff --git a/wolfcrypt/src/port/silabs/silabs_hash.c b/wolfcrypt/src/port/silabs/silabs_hash.c new file mode 100644 index 000000000..b1214e431 --- /dev/null +++ b/wolfcrypt/src/port/silabs/silabs_hash.c @@ -0,0 +1,305 @@ +/* silabs_se_hash.c + * + * Copyright (C) 2006-2020 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 + */ + +/* Silicon Labs Secure Element Manager Hashing Function */ + +#ifdef HAVE_CONFIG_H + #include +#endif + + +#include + +#if defined(WOLFSSL_SILABS_SE_ACCEL) + +#include +#include + +#include + +int wc_silabs_se_hash_init (wc_silabs_sha_t* sha, enum wc_HashType type) +{ + int ret = 0; + sl_status_t rr; + + // set sizes and state + XMEMSET(sha, 0, sizeof(wc_silabs_sha_t)); + + // set init state + switch(type) { + case WC_HASH_TYPE_SHA: + rr = sl_se_hash_starts(&sha->hash_ctx, + &sha->cmd_ctx, + SL_SE_HASH_SHA1, + &sha->hash_type_ctx); + break; + case WC_HASH_TYPE_SHA224: + rr = sl_se_hash_starts(&sha->hash_ctx, + &sha->cmd_ctx, + SL_SE_HASH_SHA224, + &sha->hash_type_ctx); + break; + case WC_HASH_TYPE_SHA256: + rr = sl_se_hash_starts(&sha->hash_ctx, + &sha->cmd_ctx, + SL_SE_HASH_SHA256, + &sha->hash_type_ctx); + break; + +#ifdef WOLFSSL_SILABS_SHA384 + case WC_HASH_TYPE_SHA384: + rr = sl_se_hash_starts(&sha->hash_ctx, + &sha->cmd_ctx, + SL_SE_HASH_SHA384, + &sha->hash_type_ctx); + break; +#endif + +#ifdef WOLFSSL_SILABS_SHA512 + case WC_HASH_TYPE_SHA512: + rr = sl_se_hash_starts(&sha->hash_ctx, + &sha->cmd_ctx, + SL_SE_HASH_SHA512, + &sha->hash_type_ctx); + break; +#endif + + default: + ret = BAD_FUNC_ARG; + break; + } + + if (rr == SL_STATUS_OK) { + // init handles if it is already initialized + ret = sl_se_init(); + } else { + ret = BUFFER_E; + } + + return ret; +} + +int wc_silabs_se_hash_update (wc_silabs_sha_t* sha, const byte* data, word32 len) +{ + int ret = 0; + + sl_status_t status = sl_se_hash_update(&sha->hash_ctx, data, len); + if (status != SL_STATUS_OK) { + ret = BUFFER_E; + } + + return ret; +} + +int wc_silabs_se_hash_final (wc_silabs_sha_t* sha, byte* hash) +{ + int ret = 0; + + sl_status_t status = sl_se_hash_finish(&sha->hash_ctx, hash, sha->hash_ctx.size); + if (status != SL_STATUS_OK) { + ret = BUFFER_E; + } + + return ret; +} + + +int wc_HashUpdate_ex (wc_silabs_sha_t* sha, const byte* data, word32 len) +{ + int ret = 0; + + if (sha == NULL || (data == NULL && len > 0)) { + return BAD_FUNC_ARG; + } + + ret = wolfSSL_CryptHwMutexLock(); + if (ret == 0) { + ret = wc_silabs_se_hash_update(sha, data, len); + + wolfSSL_CryptHwMutexUnLock(); + } + return ret; +} + +int wc_HashFinal_ex(wc_silabs_sha_t* sha, byte* hash) +{ + int ret = 0; + + if (sha == NULL || hash == NULL) { + return BAD_FUNC_ARG; + } + + ret = wolfSSL_CryptHwMutexLock(); + if (ret == 0) { + ret = wc_silabs_se_hash_final(sha, hash); + wolfSSL_CryptHwMutexUnLock(); + } + + return ret; +} + +#ifndef NO_SHA + +int wc_InitSha_ex(wc_Sha* sha, void* heap, int devId) +{ + if (sha == NULL) { + return BAD_FUNC_ARG; + } + + (void)devId; + (void)heap; + + return wc_silabs_se_hash_init(&(sha->silabsCtx), WC_HASH_TYPE_SHA); +} + +int wc_ShaUpdate(wc_Sha* sha, const byte* data, word32 len) +{ + return wc_HashUpdate_ex(&(sha->silabsCtx), data, len); +} + +int wc_ShaFinal(wc_Sha* sha, byte* hash) +{ + int ret = wc_HashFinal_ex(&(sha->silabsCtx), hash); + + (void)wc_InitSha(sha); /* reset state */ + + return ret; +} + +#endif /* ! NO_SHA */ + +#ifndef NO_SHA256 +int wc_InitSha256_ex(wc_Sha256* sha, void* heap, int devId) +{ + if (sha == NULL) { + return BAD_FUNC_ARG; + } + + (void)devId; + (void)heap; + + return wc_silabs_se_hash_init(&(sha->silabsCtx), WC_HASH_TYPE_SHA256); +} + + +int wc_Sha256Update(wc_Sha256* sha, const byte* data, word32 len) +{ + return wc_HashUpdate_ex(&(sha->silabsCtx), data, len); +} + +int wc_Sha256Final(wc_Sha256* sha, byte* hash) +{ + int ret = wc_HashFinal_ex(&(sha->silabsCtx), hash); + + (void)wc_InitSha256(sha); /* reset state */ + + return ret; +} +#endif /* ! NO_SHA256 */ + +#ifndef NO_SHA224 +int wc_InitSha224_ex(wc_Sha224* sha, void* heap, int devId) +{ + if (sha == NULL) { + return BAD_FUNC_ARG; + } + + (void)devId; + (void)heap; + + return wc_silabs_se_hash_init(&(sha->silabsCtx), WC_HASH_TYPE_SHA224); +} + + +int wc_Sha224Update(wc_Sha224* sha, const byte* data, word32 len) +{ + return wc_HashUpdate_ex(&(sha->silabsCtx), data, len); +} + +int wc_Sha224Final(wc_Sha224* sha, byte* hash) +{ + int ret = wc_HashFinal_ex(&(sha->silabsCtx), hash); + + (void)wc_InitSha224(sha); /* reset state */ + + return ret; +} +#endif /* ! NO_SHA224 */ + +#ifdef WOLFSSL_SILABS_SHA384 +int wc_InitSha384_ex(wc_Sha384* sha, void* heap, int devId) +{ + if (sha == NULL) { + return BAD_FUNC_ARG; + } + + (void)devId; + (void)heap; + + return wc_silabs_se_hash_init(&(sha->silabsCtx), WC_HASH_TYPE_SHA384); +} + + +int wc_Sha384Update(wc_Sha384* sha, const byte* data, word32 len) +{ + return wc_HashUpdate_ex(&(sha->silabsCtx), data, len); +} + +int wc_Sha384Final(wc_Sha384* sha, byte* hash) +{ + int ret = wc_HashFinal_ex(&(sha->silabsCtx), hash); + + (void)wc_InitSha384(sha); /* reset state */ + + return ret; +} +#endif /* WOLFSSL_SILABS_SHA384 */ + +#ifdef WOLFSSL_SILABS_SHA512 +int wc_InitSha512_ex(wc_Sha512* sha, void* heap, int devId) +{ + if (sha == NULL) { + return BAD_FUNC_ARG; + } + + (void)devId; + (void)heap; + + return wc_silabs_se_hash_init(&(sha->silabsCtx), WC_HASH_TYPE_SHA512); +} + + +int wc_Sha512Update(wc_Sha512* sha, const byte* data, word32 len) +{ + return wc_HashUpdate_ex(&(sha->silabsCtx), data, len); +} + +int wc_Sha512Final(wc_Sha512* sha, byte* hash) +{ + int ret = wc_HashFinal_ex(&(sha->silabsCtx), hash); + + (void)wc_InitSha512(sha); /* reset state */ + + return ret; +} +#endif /* WOLFSSL_SILABS_SHA512 */ + +#endif /* defined(WOLFSSL_SILABS_SE_ACCEL) */ diff --git a/wolfcrypt/src/sha.c b/wolfcrypt/src/sha.c index bd442bc39..39d573304 100644 --- a/wolfcrypt/src/sha.c +++ b/wolfcrypt/src/sha.c @@ -331,6 +331,10 @@ #elif defined(WOLFSSL_IMXRT_DCP) /* implemented in wolfcrypt/src/port/nxp/dcp_port.c */ +#elif defined(WOLFSSL_SILABS_SE_ACCEL) + + /* implemented in wolfcrypt/src/port/silabs/silabs_hash.c */ + #else /* Software implementation */ #define USE_SHA_SOFTWARE_IMPL @@ -846,6 +850,11 @@ int wc_ShaCopy(wc_Sha* src, wc_Sha* dst) XMEMCPY(dst, src, sizeof(wc_Sha)); +#ifdef WOLFSSL_SILABS_SE_ACCEL + dst->silabsCtx.hash_ctx.cmd_ctx = &(dst->silabsCtx.cmd_ctx); + dst->silabsCtx.hash_ctx.hash_type_ctx = &(dst->silabsCtx.hash_type_ctx); +#endif + #ifdef WOLFSSL_ASYNC_CRYPT ret = wolfAsync_DevCopy(&src->asyncDev, &dst->asyncDev); #endif diff --git a/wolfcrypt/src/sha256.c b/wolfcrypt/src/sha256.c index 7009d65a8..285076f92 100644 --- a/wolfcrypt/src/sha256.c +++ b/wolfcrypt/src/sha256.c @@ -181,7 +181,8 @@ where 0 <= L < 2^64. !defined(WOLFSSL_AFALG_HASH) && !defined(WOLFSSL_DEVCRYPTO_HASH) && \ (!defined(WOLFSSL_ESP32WROOM32_CRYPT) || defined(NO_WOLFSSL_ESP32WROOM32_CRYPT_HASH)) && \ (!defined(WOLFSSL_RENESAS_TSIP_CRYPT) || defined(NO_WOLFSSL_RENESAS_TSIP_HASH)) && \ - !defined(WOLFSSL_PSOC6_CRYPTO) && !defined(WOLFSSL_IMXRT_DCP) + !defined(WOLFSSL_PSOC6_CRYPTO) && !defined(WOLFSSL_IMXRT_DCP) && !defined(WOLFSSL_SILABS_SE_ACCEL) + static int InitSha256(wc_Sha256* sha256) { @@ -718,6 +719,9 @@ static int InitSha256(wc_Sha256* sha256) #include /* implemented in wolfcrypt/src/port/nxp/dcp_port.c */ +#elif defined(WOLFSSL_SILABS_SE_ACCEL) + /* implemented in wolfcrypt/src/port/silabs/silabs_hash.c */ + #else #define NEED_SOFT_SHA256 @@ -1358,6 +1362,9 @@ static int InitSha256(wc_Sha256* sha256) #elif defined(WOLFSSL_DEVCRYPTO_HASH) /* implemented in wolfcrypt/src/port/devcrypto/devcrypt_hash.c */ +#elif defined(WOLFSSL_SILABS_SE_ACCEL) + /* implemented in wolfcrypt/src/port/silabs/silabs_hash.c */ + #else #define NEED_SOFT_SHA224 @@ -1587,6 +1594,11 @@ void wc_Sha256Free(wc_Sha256* sha256) dst->W = NULL; #endif + #ifdef WOLFSSL_SILABS_SE_ACCEL + dst->silabsCtx.hash_ctx.cmd_ctx = &(dst->silabsCtx.cmd_ctx); + dst->silabsCtx.hash_ctx.hash_type_ctx = &(dst->silabsCtx.hash_type_ctx); + #endif + #ifdef WOLFSSL_ASYNC_CRYPT ret = wolfAsync_DevCopy(&src->asyncDev, &dst->asyncDev); #endif @@ -1674,6 +1686,11 @@ int wc_Sha256Copy(wc_Sha256* src, wc_Sha256* dst) dst->W = NULL; #endif +#ifdef WOLFSSL_SILABS_SE_ACCEL + dst->silabsCtx.hash_ctx.cmd_ctx = &(dst->silabsCtx.cmd_ctx); + dst->silabsCtx.hash_ctx.hash_type_ctx = &(dst->silabsCtx.hash_type_ctx); +#endif + #ifdef WOLFSSL_ASYNC_CRYPT ret = wolfAsync_DevCopy(&src->asyncDev, &dst->asyncDev); #endif diff --git a/wolfcrypt/src/sha512.c b/wolfcrypt/src/sha512.c index 75f356894..1a4483278 100644 --- a/wolfcrypt/src/sha512.c +++ b/wolfcrypt/src/sha512.c @@ -188,6 +188,9 @@ #if defined(WOLFSSL_IMX6_CAAM) && !defined(NO_IMX6_CAAM_HASH) /* functions defined in wolfcrypt/src/port/caam/caam_sha.c */ +#elif defined(WOLFSSL_SILABS_SHA384) + /* functions defined in wolfcrypt/src/port/silabs/silabs_hash.c */ + #else #ifdef WOLFSSL_SHA512 @@ -743,7 +746,7 @@ int wc_Sha512Update(wc_Sha512* sha512, const byte* data, word32 len) #endif /* WOLFSSL_SHA512 */ -#endif /* WOLFSSL_IMX6_CAAM */ +#endif /* WOLFSSL_IMX6_CAAM || WOLFSSL_SILABS_SHA384 */ static WC_INLINE int Sha512Final(wc_Sha512* sha512) { @@ -924,6 +927,9 @@ void wc_Sha512Free(wc_Sha512* sha512) #if defined(WOLFSSL_IMX6_CAAM) && !defined(NO_IMX6_CAAM_HASH) /* functions defined in wolfcrypt/src/port/caam/caam_sha.c */ +#elif defined(WOLFSSL_SILABS_SHA512) + /* functions defined in wolfcrypt/src/port/silabs/silabs_hash.c */ + #else static int InitSha384(wc_Sha384* sha384) @@ -1063,7 +1069,7 @@ int wc_InitSha384_ex(wc_Sha384* sha384, void* heap, int devId) return ret; } -#endif /* WOLFSSL_IMX6_CAAM */ +#endif /* WOLFSSL_IMX6_CAAM || WOLFSSL_SILABS_SHA512 */ int wc_InitSha384(wc_Sha384* sha384) { @@ -1134,6 +1140,11 @@ int wc_Sha512Copy(wc_Sha512* src, wc_Sha512* dst) dst->W = NULL; #endif +#ifdef WOLFSSL_SILABS_SHA512 + dst->silabsCtx.hash_ctx.cmd_ctx = &(dst->silabsCtx.cmd_ctx); + dst->silabsCtx.hash_ctx.hash_type_ctx = &(dst->silabsCtx.hash_type_ctx); +#endif + #ifdef WOLFSSL_ASYNC_CRYPT ret = wolfAsync_DevCopy(&src->asyncDev, &dst->asyncDev); #endif @@ -1210,6 +1221,11 @@ int wc_Sha384Copy(wc_Sha384* src, wc_Sha384* dst) dst->W = NULL; #endif +#ifdef WOLFSSL_SILABS_SHA384 + dst->silabsCtx.hash_ctx.cmd_ctx = &(dst->silabsCtx.cmd_ctx); + dst->silabsCtx.hash_ctx.hash_type_ctx = &(dst->silabsCtx.hash_type_ctx); +#endif + #ifdef WOLFSSL_ASYNC_CRYPT ret = wolfAsync_DevCopy(&src->asyncDev, &dst->asyncDev); #endif diff --git a/wolfcrypt/test/test.c b/wolfcrypt/test/test.c index 383e80c86..a2d7b76f6 100644 --- a/wolfcrypt/test/test.c +++ b/wolfcrypt/test/test.c @@ -8943,6 +8943,7 @@ static int aesgcm_test(void) !defined(WOLFSSL_PIC32MZ_CRYPT) && \ !defined(FREESCALE_LTC) && !defined(FREESCALE_MMCAU) && \ !defined(WOLFSSL_XILINX_CRYPT) && !defined(WOLFSSL_AFALG_XILINX_AES) && \ + !defined(WOLFSSL_SILABS_SE_ACCEL) && \ !(defined(WOLF_CRYPTO_CB) && \ (defined(HAVE_INTEL_QA_SYNC) || defined(HAVE_CAVIUM_OCTEON_SYNC))) @@ -9444,8 +9445,9 @@ static int gmac_test(void) 0xaa, 0x10, 0xf1, 0x6d, 0x22, 0x7d, 0xc4, 0x1b }; -#if !defined(HAVE_FIPS) || \ - (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 2)) +#if (!defined(HAVE_FIPS) || \ + (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 2))) + /* FIPS builds only allow 16-byte auth tags. */ /* This sample uses a 15-byte auth tag. */ static const byte k2[] = @@ -9480,8 +9482,9 @@ static int gmac_test(void) if (XMEMCMP(t1, tag, sizeof(t1)) != 0) return -6400; -#if !defined(HAVE_FIPS) || \ - (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 2)) +#if (!defined(HAVE_FIPS) || \ + (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 2)) ) + XMEMSET(tag, 0, sizeof(tag)); wc_GmacSetKey(&gmac, k2, sizeof(k2)); wc_GmacUpdate(&gmac, iv2, sizeof(iv2), a2, sizeof(a2), tag, sizeof(t2)); diff --git a/wolfssl/wolfcrypt/aes.h b/wolfssl/wolfcrypt/aes.h index bd704375e..0ac1b6c24 100644 --- a/wolfssl/wolfcrypt/aes.h +++ b/wolfssl/wolfcrypt/aes.h @@ -79,6 +79,11 @@ block cipher mechanism that uses n-bit binary string parameter key with 128-bits #include #endif +#ifdef WOLFSSL_SILABS_SE_ACCEL + #include +#endif + + #if defined(HAVE_AESGCM) && !defined(WC_NO_RNG) #include #endif @@ -231,6 +236,9 @@ struct Aes { #endif #if defined(WOLFSSL_IMXRT_DCP) dcp_handle_t handle; +#endif +#if defined(WOLFSSL_SILABS_SE_ACCEL) + silabs_aes_t ctx; #endif void* heap; /* memory hint to use */ }; diff --git a/wolfssl/wolfcrypt/include.am b/wolfssl/wolfcrypt/include.am index 8041a8bbc..655704646 100644 --- a/wolfssl/wolfcrypt/include.am +++ b/wolfssl/wolfcrypt/include.am @@ -80,6 +80,8 @@ noinst_HEADERS+= \ wolfssl/wolfcrypt/port/caam/caam_driver.h \ wolfssl/wolfcrypt/port/caam/wolfcaam.h \ wolfssl/wolfcrypt/port/caam/wolfcaam_sha.h \ + wolfssl/wolfcrypt/port/silabs/silabs_aes.h \ + wolfssl/wolfcrypt/port/silabs/silabs_hash.h \ wolfssl/wolfcrypt/port/st/stm32.h \ wolfssl/wolfcrypt/port/st/stsafe.h \ wolfssl/wolfcrypt/port/Espressif/esp32-crypt.h \ diff --git a/wolfssl/wolfcrypt/port/silabs/silabs_aes.h b/wolfssl/wolfcrypt/port/silabs/silabs_aes.h new file mode 100644 index 000000000..6263264e2 --- /dev/null +++ b/wolfssl/wolfcrypt/port/silabs/silabs_aes.h @@ -0,0 +1,54 @@ +/* silabs_aes.h + * + * Copyright (C) 2006-2020 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 + */ + +#ifndef _SILABS_AES_H_ +#define _SILABS_AES_H_ + +#include + +#if defined(WOLFSSL_SILABS_SE_ACCEL) + +#include + +#include +#include + +typedef struct { + sl_se_command_context_t cmd_ctx; + sl_se_key_descriptor_t key; +} silabs_aes_t; + +#ifdef HAVE_AESGCM +typedef struct Aes Aes; +int wc_AesGcmEncrypt_silabs (Aes* aes, byte* out, const byte* in, word32 sz, + const byte* iv, word32 ivSz, + byte* authTag, word32 authTagSz, + const byte* authIn, word32 authInSz); +int wc_AesGcmDecrypt_silabs (Aes* aes, byte* out, const byte* in, word32 sz, + const byte* iv, word32 ivSz, + const byte* authTag, word32 authTagSz, + const byte* authIn, word32 authInSz); + +#endif /* HAVE_AESGCM */ + +#endif /* defined(WOLFSSL_SILABS_SE_ACCEL) */ + +#endif /* _SILABS_AES_H_ */ diff --git a/wolfssl/wolfcrypt/port/silabs/silabs_hash.h b/wolfssl/wolfcrypt/port/silabs/silabs_hash.h new file mode 100644 index 000000000..c0e5887e5 --- /dev/null +++ b/wolfssl/wolfcrypt/port/silabs/silabs_hash.h @@ -0,0 +1,66 @@ +/* silabs_hash.h + * + * Copyright (C) 2006-2020 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 + */ + +#ifndef _SILABS_HASH_H_ +#define _SILABS_HASH_H_ + +#include + +#if defined(WOLFSSL_SILABS_SE_ACCEL) + +#include + +#include +#include + +#if defined(SL_SE_HASH_SHA384) && !defined(NO_SHA384) +#define WOLFSSL_SILABS_SHA384 +#endif + +#if defined(SL_SE_HASH_SHA512) && !defined(NO_SHA384) +#define WOLFSSL_SILABS_SHA512 +#endif + +typedef struct { + sl_se_hash_streaming_context_t hash_ctx; + sl_se_command_context_t cmd_ctx; + union hash_type_ctx_u { + sl_se_sha1_streaming_context_t sha1_ctx; + sl_se_sha224_streaming_context_t sha224_ctx; + sl_se_sha256_streaming_context_t sha256_ctx; +#ifdef WOLFSSL_SILABS_SHA384 + sl_se_sha384_streaming_context_t sha384_ctx; +#endif +#ifdef WOLFSSL_SILABS_SHA512 + sl_se_sha512_streaming_context_t sha512_ctx; +#endif + } hash_type_ctx; +} wc_silabs_sha_t; + +int wc_silabs_se_hash_init (wc_silabs_sha_t* sha, enum wc_HashType type); +int wc_silabs_se_hash_update (wc_silabs_sha_t* sha, const byte* data, word32 len); +int wc_silabs_se_hash_final (wc_silabs_sha_t* sha, byte* hash); + + + +#endif /* defined(WOLFSSL_SILABS_SE_ACCEL) */ + +#endif /* _SILABS_HASH_H_ */ diff --git a/wolfssl/wolfcrypt/sha.h b/wolfssl/wolfcrypt/sha.h index 5cfcb7cea..6203d648d 100644 --- a/wolfssl/wolfcrypt/sha.h +++ b/wolfssl/wolfcrypt/sha.h @@ -75,6 +75,9 @@ #ifdef WOLFSSL_IMXRT_DCP #include #endif +#if defined(WOLFSSL_SILABS_SE_ACCEL) + #include +#endif #if !defined(NO_OLD_SHA_NAMES) #define SHA WC_SHA @@ -114,6 +117,8 @@ struct wc_Sha { ltc_hash_ctx_t ctx; #elif defined(STM32_HASH) STM32_HASH_Context stmCtx; +#elif defined(WOLFSSL_SILABS_SE_ACCEL) + wc_silabs_sha_t silabsCtx; #else word32 buffLen; /* in bytes */ word32 loLen; /* length in bytes */ diff --git a/wolfssl/wolfcrypt/sha256.h b/wolfssl/wolfcrypt/sha256.h index 026157f16..9538fed7b 100644 --- a/wolfssl/wolfcrypt/sha256.h +++ b/wolfssl/wolfcrypt/sha256.h @@ -88,6 +88,9 @@ #if defined(WOLFSSL_CRYPTOCELL) #include #endif +#if defined(WOLFSSL_SILABS_SE_ACCEL) + #include +#endif #if defined(_MSC_VER) #define SHA256_NOINLINE __declspec(noinline) @@ -138,6 +141,8 @@ struct wc_Sha256 { ltc_hash_ctx_t ctx; #elif defined(STM32_HASH_SHA2) STM32_HASH_Context stmCtx; +#elif defined(WOLFSSL_SILABS_SE_ACCEL) + wc_silabs_sha_t silabsCtx; #else /* alignment on digest and buffer speeds up ARMv8 crypto operations */ ALIGN16 word32 digest[WC_SHA256_DIGEST_SIZE / sizeof(word32)]; diff --git a/wolfssl/wolfcrypt/sha512.h b/wolfssl/wolfcrypt/sha512.h index 5aaf8e3f0..f3e79a263 100644 --- a/wolfssl/wolfcrypt/sha512.h +++ b/wolfssl/wolfcrypt/sha512.h @@ -76,6 +76,10 @@ #ifdef WOLFSSL_ESP32WROOM32_CRYPT #include #endif +#if defined(WOLFSSL_SILABS_SE_ACCEL) + #include +#endif + #if defined(_MSC_VER) #define SHA512_NOINLINE __declspec(noinline) #elif defined(__IAR_SYSTEMS_ICC__) || defined(__GNUC__) @@ -136,6 +140,10 @@ struct wc_Sha512 { !defined(NO_WOLFSSL_ESP32WROOM32_CRYPT_HASH) WC_ESP32SHA ctx; #endif +#if defined(WOLFSSL_SILABS_SE_ACCEL) + wc_silabs_sha_t silabsCtx; +#endif + #if defined(WOLFSSL_HASH_FLAGS) || defined(WOLF_CRYPTO_CB) word32 flags; /* enum wc_HashFlags in hash.h */ #endif From e5013460479b7aedfb1a48e650857fcce184af98 Mon Sep 17 00:00:00 2001 From: Elms Date: Tue, 17 Nov 2020 14:40:33 -0800 Subject: [PATCH 06/20] SiLabs: add AES-CCM hardware acceleration support --- wolfcrypt/src/aes.c | 27 +++++++++++++ wolfcrypt/src/port/silabs/README.md | 4 ++ wolfcrypt/src/port/silabs/silabs_aes.c | 47 ++++++++++++++++++++++ wolfssl/wolfcrypt/port/silabs/silabs_aes.h | 15 ++++++- 4 files changed, 92 insertions(+), 1 deletion(-) diff --git a/wolfcrypt/src/aes.c b/wolfcrypt/src/aes.c index 2a773a0ec..1be8b2a98 100644 --- a/wolfcrypt/src/aes.c +++ b/wolfcrypt/src/aes.c @@ -7079,6 +7079,33 @@ int wc_AesCcmCheckTagSize(int sz) #elif defined(WOLFSSL_IMX6_CAAM) && !defined(NO_IMX6_CAAM_AES) /* implemented in wolfcrypt/src/port/caam_aes.c */ +#elif defined(WOLFSSL_SILABS_SE_ACCEL) + /* implemented in wolfcrypt/src/port/silabs/silabs_hash.c */ +int wc_AesCcmEncrypt(Aes* aes, byte* out, const byte* in, word32 inSz, + const byte* nonce, word32 nonceSz, + byte* authTag, word32 authTagSz, + const byte* authIn, word32 authInSz) +{ + return wc_AesCcmEncrypt_silabs( + aes, out, in, inSz, + nonce, nonceSz, + authTag, authTagSz, + authIn, authInSz); +} + +#ifdef HAVE_AES_DECRYPT +int wc_AesCcmDecrypt(Aes* aes, byte* out, const byte* in, word32 inSz, + const byte* nonce, word32 nonceSz, + const byte* authTag, word32 authTagSz, + const byte* authIn, word32 authInSz) +{ + return wc_AesCcmDecrypt_silabs( + aes, out, in, inSz, + nonce, nonceSz, + authTag, authTagSz, + authIn, authInSz); +} +#endif #elif defined(FREESCALE_LTC) /* return 0 on success */ diff --git a/wolfcrypt/src/port/silabs/README.md b/wolfcrypt/src/port/silabs/README.md index ddd5f7baf..1a628d7ed 100644 --- a/wolfcrypt/src/port/silabs/README.md +++ b/wolfcrypt/src/port/silabs/README.md @@ -27,6 +27,10 @@ recommend defining `WOLFSSL_USER_SETTINGS` and adding your own `user_settings.h` file. You can find a good reference for this in `IDE/GCC-ARM/Header/user_settings.h`. +### Caveats + + * AES GCM tags of some lengths do not pass tests. + ### Benchmarks diff --git a/wolfcrypt/src/port/silabs/silabs_aes.c b/wolfcrypt/src/port/silabs/silabs_aes.c index bca443b59..2bcaf2258 100644 --- a/wolfcrypt/src/port/silabs/silabs_aes.c +++ b/wolfcrypt/src/port/silabs/silabs_aes.c @@ -161,4 +161,51 @@ int wc_AesGcmDecrypt_silabs (Aes* aes, byte* out, const byte* in, word32 sz, #endif /* HAVE_AESGCM */ + +#ifdef HAVE_AESCCM +int wc_AesCcmEncrypt_silabs (Aes* aes, byte* out, const byte* in, word32 sz, + const byte* iv, word32 ivSz, + byte* authTag, word32 authTagSz, + const byte* authIn, word32 authInSz) +{ + sl_status_t status = sl_se_ccm_encrypt_and_tag( + &(aes->ctx.cmd_ctx), + &(aes->ctx.key), + sz, + iv, + ivSz, + authIn, + authInSz, + in, + out, + authTag, + authTagSz + ); + + return (status != SL_STATUS_OK) ? AES_GCM_AUTH_E : 0; +} + +int wc_AesCcmDecrypt_silabs (Aes* aes, byte* out, const byte* in, word32 sz, + const byte* iv, word32 ivSz, + const byte* authTag, word32 authTagSz, + const byte* authIn, word32 authInSz) +{ + sl_status_t status = sl_se_ccm_auth_decrypt( + &(aes->ctx.cmd_ctx), + &(aes->ctx.key), + sz, + iv, + ivSz, + authIn, + authInSz, + in, + out, + (byte*)authTag, + authTagSz); + + return (status != SL_STATUS_OK) ? AES_GCM_AUTH_E : 0; +} + +#endif /* HAVE_AESGCM */ + #endif /* WOLFSSL_SILABS_SE_ACCEL */ diff --git a/wolfssl/wolfcrypt/port/silabs/silabs_aes.h b/wolfssl/wolfcrypt/port/silabs/silabs_aes.h index 6263264e2..3b9d4f140 100644 --- a/wolfssl/wolfcrypt/port/silabs/silabs_aes.h +++ b/wolfssl/wolfcrypt/port/silabs/silabs_aes.h @@ -36,8 +36,9 @@ typedef struct { sl_se_key_descriptor_t key; } silabs_aes_t; -#ifdef HAVE_AESGCM typedef struct Aes Aes; + +#ifdef HAVE_AESGCM int wc_AesGcmEncrypt_silabs (Aes* aes, byte* out, const byte* in, word32 sz, const byte* iv, word32 ivSz, byte* authTag, word32 authTagSz, @@ -49,6 +50,18 @@ int wc_AesGcmDecrypt_silabs (Aes* aes, byte* out, const byte* in, word32 sz, #endif /* HAVE_AESGCM */ +#ifdef HAVE_AESCCM +int wc_AesCcmEncrypt_silabs (Aes* aes, byte* out, const byte* in, word32 sz, + const byte* iv, word32 ivSz, + byte* authTag, word32 authTagSz, + const byte* authIn, word32 authInSz); +int wc_AesCcmDecrypt_silabs (Aes* aes, byte* out, const byte* in, word32 sz, + const byte* iv, word32 ivSz, + const byte* authTag, word32 authTagSz, + const byte* authIn, word32 authInSz); + +#endif /* HAVE_AESCCM */ + #endif /* defined(WOLFSSL_SILABS_SE_ACCEL) */ #endif /* _SILABS_AES_H_ */ From a9f8b6e5b71e461d46f7b39856d1c4d3328b086b Mon Sep 17 00:00:00 2001 From: Elms Date: Wed, 18 Nov 2020 15:27:43 -0800 Subject: [PATCH 07/20] SiLabs: TRNG hardware acceleration --- wolfcrypt/src/port/silabs/README.md | 8 +++- wolfcrypt/src/port/silabs/silabs_random.c | 48 +++++++++++++++++++ wolfcrypt/src/random.c | 11 +++++ wolfssl/wolfcrypt/port/silabs/silabs_random.h | 35 ++++++++++++++ wolfssl/wolfcrypt/settings.h | 2 +- 5 files changed, 101 insertions(+), 3 deletions(-) create mode 100644 wolfcrypt/src/port/silabs/silabs_random.c create mode 100644 wolfssl/wolfcrypt/port/silabs/silabs_random.h diff --git a/wolfcrypt/src/port/silabs/README.md b/wolfcrypt/src/port/silabs/README.md index 1a628d7ed..610066046 100644 --- a/wolfcrypt/src/port/silabs/README.md +++ b/wolfcrypt/src/port/silabs/README.md @@ -29,8 +29,12 @@ recommend defining `WOLFSSL_USER_SETTINGS` and adding your own ### Caveats - * AES GCM tags of some lengths do not pass tests. - + * AES GCM tags length >= 16 bytes + * By default random generator is seeded by the TRNG, but not used to + generate all random data. `WOLFSSL_SILABS_TRNG` can be set to + generate all random data with hardware TRNG, but requesting too + much data or too quickly may result in system reset and setting + `SESYSREQ`. ### Benchmarks diff --git a/wolfcrypt/src/port/silabs/silabs_random.c b/wolfcrypt/src/port/silabs/silabs_random.c new file mode 100644 index 000000000..6da2f0136 --- /dev/null +++ b/wolfcrypt/src/port/silabs/silabs_random.c @@ -0,0 +1,48 @@ +/* silabs_random.c + * + * Copyright (C) 2006-2020 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 + */ + +/* Generic SILABS Entropy random */ + +#ifdef HAVE_CONFIG_H + #include +#endif + +#include + +#if defined(WOLFSSL_SILABS_SE_ACCEL) + +#include +#include + +#include + +int silabs_GenerateRand(byte* output, word32 sz) +{ + sl_se_command_context_t cmd_ctx = SL_SE_COMMAND_CONTEXT_INIT; + sl_status_t status = sl_se_init(); + + if (status == SL_STATUS_OK) + status = sl_se_get_random(&cmd_ctx, output, sz); + + return (status != SL_STATUS_OK); +} + +#endif /* WOLFSSL_SILABS_SE_ACCEL */ diff --git a/wolfcrypt/src/random.c b/wolfcrypt/src/random.c index 7208694fc..66319e4dc 100644 --- a/wolfcrypt/src/random.c +++ b/wolfcrypt/src/random.c @@ -927,6 +927,10 @@ int wc_RNG_GenerateBlock(WC_RNG* rng, byte* output, word32 sz) return wc_GenerateRand_IntelRD(NULL, output, sz); #endif +#if defined(WOLFSSL_SILABS_SE_ACCEL) && defined(WOLFSSL_SILABS_TRNG) + return silabs_GenerateRand(output, sz); +#endif + #if defined(WOLFSSL_ASYNC_CRYPT) if (rng->asyncDev.marker == WOLFSSL_ASYNC_MARKER_RNG) { /* these are blocking */ @@ -1908,6 +1912,13 @@ int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz) #define USE_TEST_GENSEED #endif /* FREESCALE_K70_RNGA */ +#elif defined(WOLFSSL_SILABS_SE_ACCEL) + int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz) + { + (void)os; + return silabs_GenerateRand(output, sz); + } + #elif defined(STM32_RNG) /* Generate a RNG seed using the hardware random number generator * on the STM32F2/F4/F7/L4. */ diff --git a/wolfssl/wolfcrypt/port/silabs/silabs_random.h b/wolfssl/wolfcrypt/port/silabs/silabs_random.h new file mode 100644 index 000000000..3267c4d9e --- /dev/null +++ b/wolfssl/wolfcrypt/port/silabs/silabs_random.h @@ -0,0 +1,35 @@ +/* silabs_random.h + * + * Copyright (C) 2006-2020 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 + */ + + +#ifndef _SILABS_RANDOM_H_ +#define _SILABS_RANDOM_H_ + + +#if defined(WOLFSSL_SILABS_SE_ACCEL) + +#include + +int silabs_GenerateRand(byte* output, word32 sz); + +#endif /* WOLFSSL_SILABS_SE_ACCEL */ + +#endif /* _SILABS_RANDOM_H_ */ diff --git a/wolfssl/wolfcrypt/settings.h b/wolfssl/wolfcrypt/settings.h index 06b1eb3aa..2dbcef1c5 100644 --- a/wolfssl/wolfcrypt/settings.h +++ b/wolfssl/wolfcrypt/settings.h @@ -1424,7 +1424,7 @@ extern void uITRON4_free(void *p) ; #define NO_WOLFSSL_DIR #define NO_WRITEV - #ifndef CUSTOM_RAND_GENERATE + #if ! defined(WOLFSSL_SILABS_SE_ACCEL) && !defined(CUSTOM_RAND_GENERATE) #define CUSTOM_RAND_TYPE RAND_NBR #define CUSTOM_RAND_GENERATE Math_Rand #endif From 9f7ef0b3e65c4c7d6d489e04eb2a8e35f588c22c Mon Sep 17 00:00:00 2001 From: Elms Date: Wed, 18 Nov 2020 16:06:32 -0800 Subject: [PATCH 08/20] SiLabs: Add ECC hardware acceleration support --- wolfcrypt/benchmark/benchmark.c | 2 +- wolfcrypt/src/ecc.c | 75 ++++- wolfcrypt/src/port/silabs/silabs_ecc.c | 312 +++++++++++++++++++++ wolfcrypt/src/port/silabs/silabs_random.c | 2 +- wolfcrypt/test/test.c | 4 +- wolfssl/wolfcrypt/ecc.h | 15 +- wolfssl/wolfcrypt/port/silabs/silabs_ecc.h | 64 +++++ wolfssl/wolfcrypt/settings.h | 2 +- 8 files changed, 463 insertions(+), 13 deletions(-) create mode 100644 wolfcrypt/src/port/silabs/silabs_ecc.c create mode 100644 wolfssl/wolfcrypt/port/silabs/silabs_ecc.h diff --git a/wolfcrypt/benchmark/benchmark.c b/wolfcrypt/benchmark/benchmark.c index bdcaa7222..0806c9c39 100644 --- a/wolfcrypt/benchmark/benchmark.c +++ b/wolfcrypt/benchmark/benchmark.c @@ -5314,7 +5314,7 @@ void bench_ecc(int doAsync) const char**desc = bench_desc_words[lng_index]; #ifdef HAVE_ECC_DHE - DECLARE_ARRAY(shared, byte, BENCH_MAX_PENDING, BENCH_MAX_ECC_SIZE, HEAP_HINT); + DECLARE_ARRAY(shared, byte, BENCH_MAX_PENDING, 2*BENCH_MAX_ECC_SIZE, HEAP_HINT); #endif #if !defined(NO_ASN) && defined(HAVE_ECC_SIGN) DECLARE_ARRAY(sig, byte, BENCH_MAX_PENDING, ECC_MAX_SIG_SIZE, HEAP_HINT); diff --git a/wolfcrypt/src/ecc.c b/wolfcrypt/src/ecc.c index 115b76c27..792548811 100644 --- a/wolfcrypt/src/ecc.c +++ b/wolfcrypt/src/ecc.c @@ -3766,7 +3766,8 @@ int wc_ecc_shared_secret(ecc_key* private_key, ecc_key* public_key, byte* out, WOLFSSL_MSG("CRYS_ECDH_SVDP_DH for secret failed"); return err; } - +#elif defined(WOLFSSL_SILABS_SE_ACCEL) + err = silabs_ecc_shared_secret(private_key, public_key, out, outlen); #else err = wc_ecc_shared_secret_ex(private_key, &public_key->pubkey, out, outlen); #endif /* WOLFSSL_ATECC508A */ @@ -4497,6 +4498,8 @@ int wc_ecc_make_key_ex2(WC_RNG* rng, int keysize, ecc_key* key, int curve_id, err = mp_read_unsigned_bin(&key->k, ucompressed_key, raw_size); } +#elif defined(WOLFSSL_SILABS_SE_ACCEL) + return silabs_ecc_make_key(key, keysize); #else #ifdef WOLFSSL_HAVE_SP_ECC @@ -4733,6 +4736,10 @@ int wc_ecc_init_ex(ecc_key* key, void* heap, int devId) key->heap = heap; #endif +#ifdef WOLFSSL_SILABS_SE_ACCEL + //TODO: anything? +#endif + #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC) /* handle as async */ ret = wolfAsync_DevCtxInit(&key->asyncDev, WOLFSSL_ASYNC_MARKER_ECC, @@ -4806,8 +4813,10 @@ static int wc_ecc_get_curve_order_bit_count(const ecc_set_type* dp) #ifndef NO_ASN -#if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A) || \ - defined(PLUTON_CRYPTO_ECC) || defined(WOLFSSL_CRYPTOCELL) + +#if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A) || \ + defined(PLUTON_CRYPTO_ECC) || defined(WOLFSSL_CRYPTOCELL) || \ + defined(WOLFSSL_SILABS_SE_ACCEL) static int wc_ecc_sign_hash_hw(const byte* in, word32 inlen, mp_int* r, mp_int* s, byte* out, word32 *outlen, WC_RNG* rng, ecc_key* key) @@ -4854,6 +4863,11 @@ static int wc_ecc_sign_hash_hw(const byte* in, word32 inlen, return BAD_COND_E; } } + #elif defined(WOLFSSL_SILABS_SE_ACCEL) + err = silabs_ecc_sign_hash(in, inlen, out, outlen, key); + if (err != 0) { + return BAD_COND_E; + } #elif defined(WOLFSSL_CRYPTOCELL) hash_mode = cc310_hashModeECC(msgLenInBytes); @@ -5051,7 +5065,8 @@ int wc_ecc_sign_hash(const byte* in, word32 inlen, byte* out, word32 *outlen, /* hardware crypto */ #if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A) || \ - defined(PLUTON_CRYPTO_ECC) || defined(WOLFSSL_CRYPTOCELL) + defined(PLUTON_CRYPTO_ECC) || defined(WOLFSSL_CRYPTOCELL) || \ + defined(WOLFSSL_SILABS_SE_ACCEL) err = wc_ecc_sign_hash_hw(in, inlen, r, s, out, outlen, rng, key); #else err = wc_ecc_sign_hash_ex(in, inlen, rng, key, r, s); @@ -5602,6 +5617,10 @@ int wc_ecc_free(ecc_key* key) } #endif +#ifdef WOLFSSL_SILABS_SE_ACCEL + // TODO: +#endif + #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC) #ifdef WC_ASYNC_ENABLE_ECC wolfAsync_DevCtxFree(&key->asyncDev, WOLFSSL_ASYNC_MARKER_ECC); @@ -6217,6 +6236,9 @@ int wc_ecc_verify_hash_ex(mp_int *r, mp_int *s, const byte* hash, CRYS_ECDSA_VerifyUserContext_t sigCtxTemp; word32 msgLenInBytes = hashlen; CRYS_ECPKI_HASH_OpMode_t hash_mode; +#elif defined(WOLFSSL_SILABS_SE_ACCEL) + // TODO: + byte sigRS[64*2]; #elif !defined(WOLFSSL_SP_MATH) || defined(FREESCALE_LTC_ECC) int did_init = 0; ecc_point *mG = NULL, *mQ = NULL; @@ -6324,6 +6346,22 @@ int wc_ecc_verify_hash_ex(mp_int *r, mp_int *s, const byte* hash, } /* valid signature if we get to this point */ *res = 1; +#elif defined(WOLFSSL_SILABS_SE_ACCEL) + /* Extract R and S */ + + err = mp_to_unsigned_bin(r, &sigRS[0]); + if (err != MP_OKAY) { + return err; + } + err = mp_to_unsigned_bin(s, &sigRS[keySz]); + if (err != MP_OKAY) { + return err; + } + + silabs_ecc_verify_hash(&sigRS[0], keySz*2, + hash, hashlen, + res, key); + #else /* checking if private key with no public part */ if (key->type == ECC_PRIVATEKEY_ONLY) { @@ -7321,7 +7359,10 @@ static int ecc_check_privkey_gen_helper(ecc_key* key) #if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A) /* Hardware based private key, so this operation is not supported */ err = MP_OKAY; /* just report success */ +#elif defined(WOLFSSL_SILABS_SE_ACCEL) + // TODO: + err = MP_OKAY; /* just report success */ #else ALLOC_CURVE_SPECS(2); @@ -7443,7 +7484,7 @@ int wc_ecc_check_key(ecc_key* key) return BAD_FUNC_ARG; #if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A) || \ - defined(WOLFSSL_CRYPTOCELL) + defined(WOLFSSL_CRYPTOCELL) || defined(WOLFSSL_SILABS_SE_ACCEL) err = 0; /* consider key check success on ATECC508/608A */ @@ -7746,6 +7787,10 @@ int wc_ecc_import_x963_ex(const byte* in, word32 inLen, ecc_key* key, if (err == MP_OKAY) err = mp_set(key->pubkey.z, 1); +#ifdef WOLFSSL_SILABS_SE_ACCEL + err = silabs_ecc_import(key, keysize); +#endif + #ifdef WOLFSSL_VALIDATE_ECC_IMPORT if (err == MP_OKAY) err = wc_ecc_check_key(key); @@ -7936,7 +7981,10 @@ int wc_ecc_import_private_key_ex(const byte* priv, word32 privSz, ret = mp_read_unsigned_bin(&key->k, priv, privSz); } - +#elif defined(WOLFSSL_SILABS_SE_ACCEL) + if (ret == MP_OKAY) { + ret = silabs_ecc_import_private(key, privSz); + } #else ret = mp_read_unsigned_bin(&key->k, priv, privSz); @@ -8084,6 +8132,10 @@ static int wc_ecc_import_raw_private(ecc_key* key, const char* qx, const CRYS_ECPKI_Domain_t* pDomain; CRYS_ECPKI_BUILD_TempData_t tempBuff; byte key_raw[ECC_MAX_CRYPTO_HW_SIZE*2 + 1]; +#endif + +#if defined(WOLFSSL_CRYPTOCELL) || defined(WOLFSSL_ATECC508A) || \ + !defined(WOLFSSL_ATECC608A) || defined(WOLFSSL_SILABS_SE_ACCEL) word32 keySz = 0; #endif @@ -8151,13 +8203,18 @@ static int wc_ecc_import_raw_private(ecc_key* key, const char* qx, #if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A) /* For SECP256R1 only save raw public key for hardware */ if (err == MP_OKAY && curve_id == ECC_SECP256R1) { - word32 keySz = key->dp->size; + keySz = key->dp->size; err = wc_export_int(key->pubkey.x, key->pubkey_raw, &keySz, keySz, WC_TYPE_UNSIGNED_BIN); if (err == MP_OKAY) err = wc_export_int(key->pubkey.y, &key->pubkey_raw[keySz], &keySz, keySz, WC_TYPE_UNSIGNED_BIN); } +#elif defined(WOLFSSL_SILABS_SE_ACCEL) + keySz = key->dp->size; + if (err == MP_OKAY) { + err = silabs_ecc_sig_to_rs(key, keySz); + } #elif defined(WOLFSSL_CRYPTOCELL) if (err == MP_OKAY) { key_raw[0] = ECC_POINT_UNCOMP; @@ -8195,8 +8252,10 @@ static int wc_ecc_import_raw_private(ecc_key* key, const char* qx, /* Hardware doesn't support loading private key */ err = NOT_COMPILED_IN; - #elif defined(WOLFSSL_CRYPTOCELL) + #elif defined(WOLFSSL_SILABS_SE_ACCEL) + err = silabs_ecc_import_private_raw(key, keySz, d, encType); + #elif defined(WOLFSSL_CRYPTOCELL) key->type = ECC_PRIVATEKEY; if (encType == WC_TYPE_HEX_STR) diff --git a/wolfcrypt/src/port/silabs/silabs_ecc.c b/wolfcrypt/src/port/silabs/silabs_ecc.c new file mode 100644 index 000000000..b1263b0c4 --- /dev/null +++ b/wolfcrypt/src/port/silabs/silabs_ecc.c @@ -0,0 +1,312 @@ +/* silabs_ecc.c + * + * Copyright (C) 2006-2020 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 + */ + +#ifdef HAVE_CONFIG_H + #include +#endif + + +#include + +#if defined(WOLFSSL_SILABS_SE_ACCEL) + +#include +#include +#include + + + +sl_se_key_type_t silabs_map_key_type (ecc_curve_id curve_id) +{ + sl_se_key_type_t res = 0; + + switch(curve_id) { + case ECC_SECP192R1: + res = SL_SE_KEY_TYPE_ECC_P192; + break; + case ECC_SECP256R1: + res = SL_SE_KEY_TYPE_ECC_P256; + break; + +#ifdef SL_SE_KEY_TYPE_ECC_P384 + case ECC_SECP384R1: + res = SL_SE_KEY_TYPE_ECC_P384; + break; +#endif + +#ifdef SL_SE_KEY_TYPE_ECC_P521 + case ECC_SECP521R1: + res = SL_SE_KEY_TYPE_ECC_P521; + break; +#endif + +#if defined(HAVE_CURVE25519) && defined(SL_SE_KEY_TYPE_ECC_X25519) + case ECC_X25519: + res = SL_SE_KEY_TYPE_ECC_X25519; + break; +#endif + +#if defined(HAVE_CURVE448) && defined(SL_SE_KEY_TYPE_ECC_X448) + case ECC_X448: + res = SL_SE_KEY_TYPE_ECC_X448; + break; +#endif + + default: + // TODO: log error + res = 0; + break; + } + + return res; +} + +int silabs_ecc_sign_hash(const byte* in, word32 inlen, byte* out, word32 *outlen, ecc_key* key) +{ + sl_status_t status = sl_se_init_command_context(&(key->cmd_ctx)); + word32 siglen = *outlen; + + status = sl_se_validate_key(&(key->key)); + + if (key->dp->size * 2 <= siglen) { + siglen = key->dp->size * 2; + } + + status = sl_se_ecc_sign( + &(key->cmd_ctx), + &(key->key), + 0, + 1, + in, + inlen, + out, + siglen + ); + + return (status == SL_STATUS_OK) ? 0 : -1; +} + +#ifdef HAVE_ECC_VERIFY + +int silabs_ecc_verify_hash(const byte* sig, word32 siglen, + const byte* hash, word32 hashlen, + int* stat, ecc_key* key) +{ + sl_status_t status = sl_se_init_command_context(&(key->cmd_ctx)); + + status = sl_se_ecc_verify( + &(key->cmd_ctx), + &(key->key), + 0, + 1, + hash, + hashlen, + sig, + siglen); + + if (status == SL_STATUS_OK) { + *stat = 1; + } else if (status == SL_STATUS_INVALID_SIGNATURE) { + *stat = 0; + } else { + // TODO: proper return code + return -1; + } + + return 0; +} +#endif + +int silabs_ecc_make_key(ecc_key* key, int keysize) +{ + sl_status_t sl_stat; + + key->key.type = silabs_map_key_type(key->dp->id); + key->key.size = keysize; + key->key.storage.method = SL_SE_KEY_STORAGE_EXTERNAL_PLAINTEXT; + key->key.flags = SL_SE_KEY_FLAG_ASYMMETRIC_BUFFER_HAS_PRIVATE_KEY + | SL_SE_KEY_FLAG_ASYMMETRIC_BUFFER_HAS_PUBLIC_KEY + | SL_SE_KEY_FLAG_ASYMMMETRIC_SIGNING_ONLY + ; + + sl_stat = sl_se_get_storage_size(&key->key, &key->key.storage.location.buffer.size); + key->key.storage.location.buffer.pointer = key->key_raw; + + sl_stat = sl_se_generate_key(&(key->cmd_ctx), + &(key->key)); + + key->type = ECC_PRIVATEKEY; + + /* copy key to mp components */ + mp_read_unsigned_bin (key->pubkey.x, + key->key.storage.location.buffer.pointer, + keysize); + mp_read_unsigned_bin (key->pubkey.y, + key->key.storage.location.buffer.pointer + keysize, + keysize); + mp_read_unsigned_bin (&key->k, + key->key.storage.location.buffer.pointer + 2 * keysize, + keysize); + + return (sl_stat == SL_STATUS_OK) ? 0 : -1; +} + +int silabs_ecc_import(ecc_key* key, word32 keysize) +{ + sl_status_t sl_stat; + int err = MP_OKAY; + word32 used = keysize; + + key->key.type = silabs_map_key_type(key->dp->id); + key->key.size = keysize; + key->key.storage.method = SL_SE_KEY_STORAGE_EXTERNAL_PLAINTEXT; + key->key.flags = SL_SE_KEY_FLAG_ASYMMETRIC_BUFFER_HAS_PRIVATE_KEY + | SL_SE_KEY_FLAG_ASYMMETRIC_BUFFER_HAS_PUBLIC_KEY + | SL_SE_KEY_FLAG_ASYMMMETRIC_SIGNING_ONLY + ; + + sl_stat = sl_se_get_storage_size(&key->key, &key->key.storage.location.buffer.size); + key->key.storage.location.buffer.pointer = key->key_raw; + + key->type = ECC_PRIVATEKEY; + + /* copy key from mp components */ + if (err == MP_OKAY) + err = wc_export_int(key->pubkey.x, key->key.storage.location.buffer.pointer, + &used, keysize, + WC_TYPE_UNSIGNED_BIN); + if (err == MP_OKAY) + err = wc_export_int(key->pubkey.y, key->key.storage.location.buffer.pointer + keysize, + &used, keysize, + WC_TYPE_UNSIGNED_BIN); + if (err == MP_OKAY) + err = wc_export_int(&key->k, key->key.storage.location.buffer.pointer + 2 * keysize, + &used, keysize, + WC_TYPE_UNSIGNED_BIN); + + return err; +} + +int silabs_ecc_import_private(ecc_key* key, word32 keysize) +{ + sl_status_t sl_stat; + word32 keySz = key->dp->size; + key->key.type = silabs_map_key_type(key->dp->id); + key->key.size = key->dp->size; + key->key.storage.method = SL_SE_KEY_STORAGE_EXTERNAL_PLAINTEXT; + key->key.flags = SL_SE_KEY_FLAG_ASYMMETRIC_BUFFER_HAS_PRIVATE_KEY + | SL_SE_KEY_FLAG_ASYMMMETRIC_SIGNING_ONLY + ; + + sl_stat = sl_se_get_storage_size(&key->key, &key->key.storage.location.buffer.size); + key->key.storage.location.buffer.pointer = key->key_raw; + + return wc_export_int(&key->k, key->key.storage.location.buffer.pointer, + &keySz, keySz, + WC_TYPE_UNSIGNED_BIN); +} + +int silabs_ecc_sig_to_rs(ecc_key* key, word32 keySz) +{ + sl_status_t sl_stat; + int err = MP_OKAY; + + key->key.type = silabs_map_key_type(key->dp->id); + key->key.size = keySz; + key->key.storage.method = SL_SE_KEY_STORAGE_EXTERNAL_PLAINTEXT; + key->key.flags = SL_SE_KEY_FLAG_ASYMMETRIC_BUFFER_HAS_PUBLIC_KEY + | SL_SE_KEY_FLAG_ASYMMMETRIC_SIGNING_ONLY + ; + + sl_stat = sl_se_get_storage_size(&key->key, &key->key.storage.location.buffer.size); + key->key.storage.location.buffer.pointer = key->key_raw; + + if (err == MP_OKAY) { + keySz = key->dp->size; + err = wc_export_int(key->pubkey.x, + key->key.storage.location.buffer.pointer, + &keySz, keySz, WC_TYPE_UNSIGNED_BIN); + if (err == MP_OKAY) + err = wc_export_int(key->pubkey.y, + key->key.storage.location.buffer.pointer + keySz, + &keySz, keySz, WC_TYPE_UNSIGNED_BIN); + } + + return err; +} + +int silabs_ecc_import_private_raw(ecc_key* key, word32 keySz, byte* d, int encType) +{ + sl_status_t sl_stat; + int err = MP_OKAY; + key->type = ECC_PRIVATEKEY; + key->key.flags |= SL_SE_KEY_FLAG_ASYMMETRIC_BUFFER_HAS_PRIVATE_KEY; + + sl_stat = sl_se_get_storage_size(&key->key, &key->key.storage.location.buffer.size); + + if (encType == WC_TYPE_HEX_STR) + err = mp_read_radix(&key->k, d, MP_RADIX_HEX); + else + err = mp_read_unsigned_bin(&key->k, (const byte*)d, + key->dp->size); + if (err == MP_OKAY) { + err = wc_export_int(&key->k, key->key.storage.location.buffer.pointer + (2 * keySz), + &keySz, keySz, + WC_TYPE_UNSIGNED_BIN); + } + + return err; +} + +int silabs_ecc_shared_secret(ecc_key* private_key, ecc_key* public_key, + byte* out, word32* outlen) +{ + sl_se_command_context_t cmd; + sl_se_key_descriptor_t key_out; + sl_se_key_descriptor_t pub_key; + + uint32_t pub_sz = 0; + sl_status_t sl_stat; + + pub_key = public_key->key; + pub_key.flags = 0x2000; + + *outlen = pub_key.size * 2; + pub_sz = pub_key.size * 2; + + + XMEMSET(&key_out, 0, sizeof(key_out)); + key_out.type = SL_SE_KEY_TYPE_SYMMETRIC; + key_out.storage.method = SL_SE_KEY_STORAGE_EXTERNAL_PLAINTEXT; + key_out.storage.location.buffer.pointer = out; + key_out.size = pub_sz; + key_out.storage.location.buffer.size = pub_sz; + + sl_stat = sl_se_ecdh_compute_shared_secret( + &cmd, + &(private_key->key), + &pub_key, + &key_out); + + return (sl_stat == SL_STATUS_OK) ? 0 : -1; +} + +#endif /* WOLFSSL_SILABS_SE_ACCEL */ diff --git a/wolfcrypt/src/port/silabs/silabs_random.c b/wolfcrypt/src/port/silabs/silabs_random.c index 6da2f0136..582f400a8 100644 --- a/wolfcrypt/src/port/silabs/silabs_random.c +++ b/wolfcrypt/src/port/silabs/silabs_random.c @@ -41,7 +41,7 @@ int silabs_GenerateRand(byte* output, word32 sz) if (status == SL_STATUS_OK) status = sl_se_get_random(&cmd_ctx, output, sz); - + return (status != SL_STATUS_OK); } diff --git a/wolfcrypt/test/test.c b/wolfcrypt/test/test.c index a2d7b76f6..734a59bce 100644 --- a/wolfcrypt/test/test.c +++ b/wolfcrypt/test/test.c @@ -20796,6 +20796,7 @@ static int ecc_ssh_test(ecc_key* key, WC_RNG* rng) (void)rng; #endif +#if !defined(WOLFSSL_SILABS_SE_ACCEL) /* Use API. */ ret = 0; do { @@ -20809,6 +20810,7 @@ static int ecc_ssh_test(ecc_key* key, WC_RNG* rng) return -10085; TEST_SLEEP(); return 0; +#endif } #endif /* HAVE_ECC_DHE */ #endif @@ -21996,7 +21998,7 @@ static int ecc_test(void) } #endif #if !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_ATECC608A) && \ - !defined(WOLFSSL_STM32_PKA) + !defined(WOLFSSL_STM32_PKA) && !defined(WOLFSSL_SILABS_SE_ACCEL) ret = ecc_test_make_pub(&rng); if (ret != 0) { printf("ecc_test_make_pub failed!: %d\n", ret); diff --git a/wolfssl/wolfcrypt/ecc.h b/wolfssl/wolfcrypt/ecc.h index 08b7148b1..fec3bdd82 100644 --- a/wolfssl/wolfcrypt/ecc.h +++ b/wolfssl/wolfcrypt/ecc.h @@ -58,6 +58,10 @@ #include #endif +#ifdef WOLFSSL_SILABS_SE_ACCEL + #include +#endif + #ifdef WOLFSSL_HAVE_SP_ECC #include #endif @@ -137,6 +141,8 @@ enum { ECC_MAX_CRYPTO_HW_PUBKEY_SIZE = (ATECC_KEY_SIZE*2), #elif defined(PLUTON_CRYPTO_ECC) ECC_MAX_CRYPTO_HW_SIZE = 32, +#elif defined(WOLFSSL_SILABS_SE_ACCEL) + ECC_MAX_CRYPTO_HW_SIZE = 32, #elif defined(WOLFSSL_CRYPTOCELL) #ifndef CRYPTOCELL_KEY_SIZE CRYPTOCELL_KEY_SIZE = ECC_MAXSIZE, @@ -395,6 +401,12 @@ struct ecc_key { #if defined(PLUTON_CRYPTO_ECC) || defined(WOLF_CRYPTO_CB) int devId; #endif +#ifdef WOLFSSL_SILABS_SE_ACCEL + sl_se_command_context_t cmd_ctx; + sl_se_key_descriptor_t key; + byte key_raw[3 * ECC_MAX_CRYPTO_HW_SIZE]; +#endif + #ifdef WOLFSSL_ASYNC_CRYPT mp_int* r; /* sign/verify temps */ mp_int* s; @@ -510,7 +522,8 @@ int wc_ecc_shared_secret_ex(ecc_key* private_key, ecc_point* point, byte* out, word32 *outlen); #if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A) || \ - defined(PLUTON_CRYPTO_ECC) || defined(WOLFSSL_CRYPTOCELL) + defined(PLUTON_CRYPTO_ECC) || defined(WOLFSSL_CRYPTOCELL) || \ + defined(WOLFSSL_SILABS_SE_ACCEL) #define wc_ecc_shared_secret_ssh wc_ecc_shared_secret #else #define wc_ecc_shared_secret_ssh wc_ecc_shared_secret_ex /* For backwards compat */ diff --git a/wolfssl/wolfcrypt/port/silabs/silabs_ecc.h b/wolfssl/wolfcrypt/port/silabs/silabs_ecc.h new file mode 100644 index 000000000..b2bb761ad --- /dev/null +++ b/wolfssl/wolfcrypt/port/silabs/silabs_ecc.h @@ -0,0 +1,64 @@ +/* silabs_ecc.h + * + * Copyright (C) 2006-2020 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 + */ + + +#ifndef _SILABS_ECC_H_ +#define _SILABS_ECC_H_ + + +#if defined(WOLFSSL_SILABS_SE_ACCEL) + +#include + +#include +#include +#include +#include + +typedef enum ecc_curve_id ecc_curve_id; +typedef struct ecc_key ecc_key; + +sl_se_key_type_t silabs_map_key_type (ecc_curve_id curve_id); +int silabs_ecc_sign_hash (const byte* in, word32 inlen, + byte* out, word32 *outlen, + ecc_key* key); +int silabs_ecc_verify_hash (const byte* sig, word32 siglen, + const byte* hash, word32 hashlen, + int* stat, ecc_key* key); + + + +int silabs_ecc_make_key(ecc_key* key, int keysize); + +int silabs_ecc_import(ecc_key* key, word32 keysize); + +int silabs_ecc_import_private(ecc_key* key, word32 keysize); + +int silabs_ecc_sig_to_rs(ecc_key* key, word32 keySz); + +int silabs_ecc_import_private_raw(ecc_key* key, word32 keySz, byte* d, int encType); + +int silabs_ecc_shared_secret(ecc_key* private_key, ecc_key* public_key, + byte* out, word32* outlen); + +#endif /* WOLFSSL_SILABS_SE_ACCEL */ + +#endif /* _SILABS_ECC_H_ */ diff --git a/wolfssl/wolfcrypt/settings.h b/wolfssl/wolfcrypt/settings.h index 2dbcef1c5..3a9a202ca 100644 --- a/wolfssl/wolfcrypt/settings.h +++ b/wolfssl/wolfcrypt/settings.h @@ -1394,7 +1394,7 @@ extern void uITRON4_free(void *p) ; #if defined(RTOS_MODULE_NET_AVAIL) || (APP_CFG_TCPIP_EN == DEF_ENABLED) #include #include - #include + //#include #endif #include #include From e1e8ca48c38b2cb78daa11a54925b11d182ad00b Mon Sep 17 00:00:00 2001 From: Elms Date: Mon, 30 Nov 2020 16:04:27 -0800 Subject: [PATCH 09/20] SiLabs: README and include updates --- wolfcrypt/src/include.am | 2 + wolfcrypt/src/port/silabs/README.md | 69 +++++++++++++++++++---------- wolfssl/wolfcrypt/include.am | 2 + 3 files changed, 49 insertions(+), 24 deletions(-) diff --git a/wolfcrypt/src/include.am b/wolfcrypt/src/include.am index faaae81ae..196feb42b 100644 --- a/wolfcrypt/src/include.am +++ b/wolfcrypt/src/include.am @@ -68,7 +68,9 @@ EXTRA_DIST += wolfcrypt/src/port/ti/ti-aes.c \ wolfcrypt/src/port/caam/caam_sha.c \ wolfcrypt/src/port/caam/caam_doc.pdf \ wolfcrypt/src/port/silabs/silabs_aes.c \ + wolfcrypt/src/port/silabs/silabs_ecc.c \ wolfcrypt/src/port/silabs/silabs_hash.c \ + wolfcrypt/src/port/silabs/silabs_random.c \ wolfcrypt/src/port/silabs/README.md \ wolfcrypt/src/port/st/stm32.c \ wolfcrypt/src/port/st/stsafe.c \ diff --git a/wolfcrypt/src/port/silabs/README.md b/wolfcrypt/src/port/silabs/README.md index 610066046..101d77025 100644 --- a/wolfcrypt/src/port/silabs/README.md +++ b/wolfcrypt/src/port/silabs/README.md @@ -1,48 +1,69 @@ -# Silicon Labs (sliabs) Port +# Silicon Labs (silabs) Port -Support for the ERF32 Gecko - * Series 2 device config 1 (Secure Element) - https://docs.silabs.com/mcu/latest/efr32mg21/group-SE - https://docs.silabs.com/mcu/latest/efr32bg21/group-SE - https://docs.silabs.com/mcu/5.9/efr32bg21/group-SE - https://docs.silabs.com/mcu/5.9/efr32mg21/group-SE +Support for the Silicon Labs hardware acceleration +Tested on ERF32 Gecko Series 2 device config 1 (Secure Element) -For details see our [](https://www.wolfssl.com/docs/) +* https://docs.silabs.com/mcu/latest/efr32mg21/group-SE +* https://docs.silabs.com/gecko-platform/latest/service/api/group-sl-se-manager +## Building -### Building - -To enable support define one of the following: +To enable support define the following: ``` #define WOLFSSL_SILABS_SE_ACCEL ``` -### Coding +## Caveats -In your application you must include -before any other wolfSSL headers. If building the sources directly we -recommend defining `WOLFSSL_USER_SETTINGS` and adding your own -`user_settings.h` file. You can find a good reference for this in -`IDE/GCC-ARM/Header/user_settings.h`. +:warning: **Be sure to update the SE firmware** Testing and results were done using SE firmware `1.2.6` -### Caveats +Update was preformed under Simplicity Studio directory: + `./developer/adapter_packs/commander/commander flash ./offline/efr32/firmware/series2config1/se_firmware_package/s2c1_se_fw_upgrade_app_1v2p6.hex` * AES GCM tags length >= 16 bytes * By default random generator is seeded by the TRNG, but not used to generate all random data. `WOLFSSL_SILABS_TRNG` can be set to - generate all random data with hardware TRNG, but requesting too - much data or too quickly may result in system reset and setting - `SESYSREQ`. + generate all random data with hardware TRNG. On early SE firmware + versions requesting too much data or too quickly may result in + system reset and setting `SESYSREQ`. -### Benchmarks +## Benchmarks See our [benchmarks](https://www.wolfssl.com/docs/benchmarks/) on the wolfSSL website. +``` +RNG 2 MB took 1.004 seconds, 1.897 MB/s +AES-128-CBC-enc 5 MB took 1.001 seconds, 4.902 MB/s +AES-128-CBC-dec 5 MB took 1.004 seconds, 4.912 MB/s +AES-192-CBC-enc 5 MB took 1.002 seconds, 4.800 MB/s +AES-192-CBC-dec 5 MB took 1.000 seconds, 4.810 MB/s +AES-256-CBC-enc 5 MB took 1.001 seconds, 4.707 MB/s +AES-256-CBC-dec 5 MB took 1.005 seconds, 4.713 MB/s +AES-128-GCM-enc 4 MB took 1.000 seconds, 4.468 MB/s +AES-128-GCM-dec 4 MB took 1.005 seconds, 4.324 MB/s +AES-192-GCM-enc 4 MB took 1.003 seconds, 4.381 MB/s +AES-192-GCM-dec 4 MB took 1.001 seconds, 4.244 MB/s +AES-256-GCM-enc 4 MB took 1.005 seconds, 4.300 MB/s +AES-256-GCM-dec 4 MB took 1.002 seconds, 4.166 MB/s +AES-CCM-Enc 4 MB took 1.005 seconds, 4.203 MB/s +AES-CCM-Dec 4 MB took 1.005 seconds, 4.057 MB/s +SHA 7 MB took 1.000 seconds, 7.202 MB/s +SHA-224 7 MB took 1.001 seconds, 7.341 MB/s +SHA-256 7 MB took 1.000 seconds, 7.349 MB/s +HMAC-SHA 6 MB took 1.001 seconds, 6.390 MB/s +HMAC-SHA224 6 MB took 1.003 seconds, 6.475 MB/s +HMAC-SHA256 6 MB took 1.000 seconds, 6.470 MB/s +ECC 256 key gen 169 ops took 1.003 sec, avg 5.935 ms, 168.495 ops/sec +ECDHE 256 agree 184 ops took 1.003 sec, avg 5.451 ms, 183.450 ops/sec +ECDSA 256 sign 158 ops took 1.010 sec, avg 6.392 ms, 156.436 ops/sec +ECDSA 256 verify 148 ops took 1.001 sec, avg 6.764 ms, 147.852 ops/sec +``` + ### Benchmarks and Memory Use -Software only implementation (ERF32, Fast Math): +Software only implementation (SILABS_SE_ACCEL, Fast Math): ``` ``` @@ -55,6 +76,6 @@ Peak Heap: Total: ``` -## Support +# Support Email us at [support@wolfssl.com](mailto:support@wolfssl.com). diff --git a/wolfssl/wolfcrypt/include.am b/wolfssl/wolfcrypt/include.am index 655704646..647714956 100644 --- a/wolfssl/wolfcrypt/include.am +++ b/wolfssl/wolfcrypt/include.am @@ -81,7 +81,9 @@ noinst_HEADERS+= \ wolfssl/wolfcrypt/port/caam/wolfcaam.h \ wolfssl/wolfcrypt/port/caam/wolfcaam_sha.h \ wolfssl/wolfcrypt/port/silabs/silabs_aes.h \ + wolfssl/wolfcrypt/port/silabs/silabs_ecc.h \ wolfssl/wolfcrypt/port/silabs/silabs_hash.h \ + wolfssl/wolfcrypt/port/silabs/silabs_random.h \ wolfssl/wolfcrypt/port/st/stm32.h \ wolfssl/wolfcrypt/port/st/stsafe.h \ wolfssl/wolfcrypt/port/Espressif/esp32-crypt.h \ From 099ed25da824be3144144fdcf12e2468c2721a65 Mon Sep 17 00:00:00 2001 From: Elms Date: Mon, 30 Nov 2020 16:29:58 -0800 Subject: [PATCH 10/20] SiLabs: fixing compiler warnings and better error checking --- wolfcrypt/src/port/silabs/silabs_ecc.c | 37 +++++++++++++--------- wolfcrypt/src/random.c | 4 +++ wolfcrypt/test/test.c | 3 +- wolfssl/wolfcrypt/port/silabs/silabs_ecc.h | 2 +- 4 files changed, 29 insertions(+), 17 deletions(-) diff --git a/wolfcrypt/src/port/silabs/silabs_ecc.c b/wolfcrypt/src/port/silabs/silabs_ecc.c index b1263b0c4..506883986 100644 --- a/wolfcrypt/src/port/silabs/silabs_ecc.c +++ b/wolfcrypt/src/port/silabs/silabs_ecc.c @@ -81,16 +81,16 @@ sl_se_key_type_t silabs_map_key_type (ecc_curve_id curve_id) int silabs_ecc_sign_hash(const byte* in, word32 inlen, byte* out, word32 *outlen, ecc_key* key) { - sl_status_t status = sl_se_init_command_context(&(key->cmd_ctx)); + sl_status_t sl_stat = sl_se_init_command_context(&(key->cmd_ctx)); word32 siglen = *outlen; - status = sl_se_validate_key(&(key->key)); + sl_stat = sl_se_validate_key(&(key->key)); - if (key->dp->size * 2 <= siglen) { + if (key->dp->size * 2 <= (int)siglen) { siglen = key->dp->size * 2; } - status = sl_se_ecc_sign( + sl_stat = sl_se_ecc_sign( &(key->cmd_ctx), &(key->key), 0, @@ -101,7 +101,7 @@ int silabs_ecc_sign_hash(const byte* in, word32 inlen, byte* out, word32 *outlen siglen ); - return (status == SL_STATUS_OK) ? 0 : -1; + return (sl_stat == SL_STATUS_OK) ? 0 : WC_HW_E; } #ifdef HAVE_ECC_VERIFY @@ -110,9 +110,9 @@ int silabs_ecc_verify_hash(const byte* sig, word32 siglen, const byte* hash, word32 hashlen, int* stat, ecc_key* key) { - sl_status_t status = sl_se_init_command_context(&(key->cmd_ctx)); + sl_status_t sl_stat = sl_se_init_command_context(&(key->cmd_ctx)); - status = sl_se_ecc_verify( + sl_stat = sl_se_ecc_verify( &(key->cmd_ctx), &(key->key), 0, @@ -122,13 +122,12 @@ int silabs_ecc_verify_hash(const byte* sig, word32 siglen, sig, siglen); - if (status == SL_STATUS_OK) { + if (sl_stat == SL_STATUS_OK) { *stat = 1; - } else if (status == SL_STATUS_INVALID_SIGNATURE) { + } else if (sl_stat == SL_STATUS_INVALID_SIGNATURE) { *stat = 0; } else { - // TODO: proper return code - return -1; + return WC_HW_E; } return 0; @@ -166,7 +165,7 @@ int silabs_ecc_make_key(ecc_key* key, int keysize) key->key.storage.location.buffer.pointer + 2 * keysize, keysize); - return (sl_stat == SL_STATUS_OK) ? 0 : -1; + return (sl_stat == SL_STATUS_OK) ? 0 : WC_HW_E; } int silabs_ecc_import(ecc_key* key, word32 keysize) @@ -185,6 +184,8 @@ int silabs_ecc_import(ecc_key* key, word32 keysize) sl_stat = sl_se_get_storage_size(&key->key, &key->key.storage.location.buffer.size); key->key.storage.location.buffer.pointer = key->key_raw; + if (sl_stat != SL_STATUS_OK) + return WC_HW_E; key->type = ECC_PRIVATEKEY; @@ -208,7 +209,7 @@ int silabs_ecc_import(ecc_key* key, word32 keysize) int silabs_ecc_import_private(ecc_key* key, word32 keysize) { sl_status_t sl_stat; - word32 keySz = key->dp->size; + word32 keySz = keysize; key->key.type = silabs_map_key_type(key->dp->id); key->key.size = key->dp->size; key->key.storage.method = SL_SE_KEY_STORAGE_EXTERNAL_PLAINTEXT; @@ -218,6 +219,8 @@ int silabs_ecc_import_private(ecc_key* key, word32 keysize) sl_stat = sl_se_get_storage_size(&key->key, &key->key.storage.location.buffer.size); key->key.storage.location.buffer.pointer = key->key_raw; + if (sl_stat != SL_STATUS_OK) + return WC_HW_E; return wc_export_int(&key->k, key->key.storage.location.buffer.pointer, &keySz, keySz, @@ -238,6 +241,8 @@ int silabs_ecc_sig_to_rs(ecc_key* key, word32 keySz) sl_stat = sl_se_get_storage_size(&key->key, &key->key.storage.location.buffer.size); key->key.storage.location.buffer.pointer = key->key_raw; + if (sl_stat != SL_STATUS_OK) + return WC_HW_E; if (err == MP_OKAY) { keySz = key->dp->size; @@ -253,7 +258,7 @@ int silabs_ecc_sig_to_rs(ecc_key* key, word32 keySz) return err; } -int silabs_ecc_import_private_raw(ecc_key* key, word32 keySz, byte* d, int encType) +int silabs_ecc_import_private_raw(ecc_key* key, word32 keySz, const char* d, int encType) { sl_status_t sl_stat; int err = MP_OKAY; @@ -261,6 +266,8 @@ int silabs_ecc_import_private_raw(ecc_key* key, word32 keySz, byte* d, int encTy key->key.flags |= SL_SE_KEY_FLAG_ASYMMETRIC_BUFFER_HAS_PRIVATE_KEY; sl_stat = sl_se_get_storage_size(&key->key, &key->key.storage.location.buffer.size); + if (sl_stat != SL_STATUS_OK) + return WC_HW_E; if (encType == WC_TYPE_HEX_STR) err = mp_read_radix(&key->k, d, MP_RADIX_HEX); @@ -306,7 +313,7 @@ int silabs_ecc_shared_secret(ecc_key* private_key, ecc_key* public_key, &pub_key, &key_out); - return (sl_stat == SL_STATUS_OK) ? 0 : -1; + return (sl_stat == SL_STATUS_OK) ? 0 : WC_HW_E; } #endif /* WOLFSSL_SILABS_SE_ACCEL */ diff --git a/wolfcrypt/src/random.c b/wolfcrypt/src/random.c index 66319e4dc..e8070a355 100644 --- a/wolfcrypt/src/random.c +++ b/wolfcrypt/src/random.c @@ -169,6 +169,10 @@ int wc_RNG_GenerateByte(WC_RNG* rng, byte* b) #endif #endif +#if defined(WOLFSSL_SILABS_SE_ACCEL) +#include +#endif + #if defined(HAVE_INTEL_RDRAND) || defined(HAVE_INTEL_RDSEED) static word32 intel_flags = 0; diff --git a/wolfcrypt/test/test.c b/wolfcrypt/test/test.c index 734a59bce..6e6a15e8d 100644 --- a/wolfcrypt/test/test.c +++ b/wolfcrypt/test/test.c @@ -20808,9 +20808,10 @@ static int ecc_ssh_test(ecc_key* key, WC_RNG* rng) } while (ret == WC_PENDING_E); if (ret != 0) return -10085; +#endif + TEST_SLEEP(); return 0; -#endif } #endif /* HAVE_ECC_DHE */ #endif diff --git a/wolfssl/wolfcrypt/port/silabs/silabs_ecc.h b/wolfssl/wolfcrypt/port/silabs/silabs_ecc.h index b2bb761ad..3f6cef898 100644 --- a/wolfssl/wolfcrypt/port/silabs/silabs_ecc.h +++ b/wolfssl/wolfcrypt/port/silabs/silabs_ecc.h @@ -54,7 +54,7 @@ int silabs_ecc_import_private(ecc_key* key, word32 keysize); int silabs_ecc_sig_to_rs(ecc_key* key, word32 keySz); -int silabs_ecc_import_private_raw(ecc_key* key, word32 keySz, byte* d, int encType); +int silabs_ecc_import_private_raw(ecc_key* key, word32 keySz, const char* d, int encType); int silabs_ecc_shared_secret(ecc_key* private_key, ecc_key* public_key, byte* out, word32* outlen); From dbcb42e5099dfc3b04e7929010f57083a2aefe19 Mon Sep 17 00:00:00 2001 From: Elms Date: Tue, 1 Dec 2020 08:56:01 -0800 Subject: [PATCH 11/20] SiLabs: fix unused variable #if --- wolfcrypt/src/ecc.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/wolfcrypt/src/ecc.c b/wolfcrypt/src/ecc.c index 792548811..bf1d6b7cb 100644 --- a/wolfcrypt/src/ecc.c +++ b/wolfcrypt/src/ecc.c @@ -8134,8 +8134,9 @@ static int wc_ecc_import_raw_private(ecc_key* key, const char* qx, byte key_raw[ECC_MAX_CRYPTO_HW_SIZE*2 + 1]; #endif -#if defined(WOLFSSL_CRYPTOCELL) || defined(WOLFSSL_ATECC508A) || \ - !defined(WOLFSSL_ATECC608A) || defined(WOLFSSL_SILABS_SE_ACCEL) +#if (defined(WOLFSSL_CRYPTOCELL) && !defined(WOLFSSL_ATECC508A) && \ + !defined(WOLFSSL_ATECC608A)) || \ + defined(WOLFSSL_SILABS_SE_ACCEL) word32 keySz = 0; #endif From 44243278a59fdb6e12daa3f75d5c4c18064f4089 Mon Sep 17 00:00:00 2001 From: Elms Date: Mon, 7 Dec 2020 13:41:35 -0800 Subject: [PATCH 12/20] SiLabs: renable ecc_ssh_test and disable AES non-12Byte IV --- wolfcrypt/src/ecc.c | 8 +++++--- wolfcrypt/src/port/silabs/README.md | 11 ----------- wolfcrypt/test/test.c | 2 -- wolfssl/wolfcrypt/ecc.h | 3 +-- 4 files changed, 6 insertions(+), 18 deletions(-) diff --git a/wolfcrypt/src/ecc.c b/wolfcrypt/src/ecc.c index bf1d6b7cb..81314c85d 100644 --- a/wolfcrypt/src/ecc.c +++ b/wolfcrypt/src/ecc.c @@ -4184,7 +4184,8 @@ static int ecc_make_pub_ex(ecc_key* key, ecc_curve_spec* curveIn, ecc_point* pubOut, WC_RNG* rng) { int err = MP_OKAY; -#if !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_ATECC608A) +#if !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_ATECC608A) \ + && !defined(WOLFSSL_SILABS_SE_ACCEL) #if !defined(WOLFSSL_SP_MATH) ecc_point* base = NULL; #endif @@ -4198,7 +4199,8 @@ static int ecc_make_pub_ex(ecc_key* key, ecc_curve_spec* curveIn, return BAD_FUNC_ARG; } -#if !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_ATECC608A) +#if !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_ATECC608A) \ + && !defined(WOLFSSL_SILABS_SE_ACCEL) /* if ecc_point passed in then use it as output for public key point */ if (pubOut != NULL) { @@ -4321,7 +4323,7 @@ static int ecc_make_pub_ex(ecc_key* key, ecc_curve_spec* curveIn, #else (void)curveIn; err = NOT_COMPILED_IN; -#endif /* WOLFSSL_ATECC508A */ +#endif /* WOLFSSL_ATECC508A || WOLFSSL_SILABS_SE_ACCEL */ /* change key state if public part is cached */ if (key->type == ECC_PRIVATEKEY_ONLY && pubOut == NULL) { diff --git a/wolfcrypt/src/port/silabs/README.md b/wolfcrypt/src/port/silabs/README.md index 101d77025..bd952ba37 100644 --- a/wolfcrypt/src/port/silabs/README.md +++ b/wolfcrypt/src/port/silabs/README.md @@ -63,18 +63,7 @@ ECDSA 256 verify 148 ops took 1.001 sec, avg 6.764 ms, 147.852 ops/sec ### Benchmarks and Memory Use -Software only implementation (SILABS_SE_ACCEL, Fast Math): -``` -``` - -Memory Use: - -``` -Peak Stack: -Peak Heap: -Total: -``` # Support diff --git a/wolfcrypt/test/test.c b/wolfcrypt/test/test.c index 6e6a15e8d..00f5ce35b 100644 --- a/wolfcrypt/test/test.c +++ b/wolfcrypt/test/test.c @@ -20796,7 +20796,6 @@ static int ecc_ssh_test(ecc_key* key, WC_RNG* rng) (void)rng; #endif -#if !defined(WOLFSSL_SILABS_SE_ACCEL) /* Use API. */ ret = 0; do { @@ -20808,7 +20807,6 @@ static int ecc_ssh_test(ecc_key* key, WC_RNG* rng) } while (ret == WC_PENDING_E); if (ret != 0) return -10085; -#endif TEST_SLEEP(); return 0; diff --git a/wolfssl/wolfcrypt/ecc.h b/wolfssl/wolfcrypt/ecc.h index fec3bdd82..97b070ea2 100644 --- a/wolfssl/wolfcrypt/ecc.h +++ b/wolfssl/wolfcrypt/ecc.h @@ -522,8 +522,7 @@ int wc_ecc_shared_secret_ex(ecc_key* private_key, ecc_point* point, byte* out, word32 *outlen); #if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A) || \ - defined(PLUTON_CRYPTO_ECC) || defined(WOLFSSL_CRYPTOCELL) || \ - defined(WOLFSSL_SILABS_SE_ACCEL) + defined(PLUTON_CRYPTO_ECC) || defined(WOLFSSL_CRYPTOCELL) #define wc_ecc_shared_secret_ssh wc_ecc_shared_secret #else #define wc_ecc_shared_secret_ssh wc_ecc_shared_secret_ex /* For backwards compat */ From 3abc4719ae268f5235035549e48785143f7d482f Mon Sep 17 00:00:00 2001 From: Elms Date: Mon, 7 Dec 2020 15:32:44 -0800 Subject: [PATCH 13/20] SiLabs: cleanup TODOs --- wolfcrypt/src/ecc.c | 12 +----------- wolfcrypt/src/port/silabs/silabs_ecc.c | 2 +- 2 files changed, 2 insertions(+), 12 deletions(-) diff --git a/wolfcrypt/src/ecc.c b/wolfcrypt/src/ecc.c index 81314c85d..365e510b6 100644 --- a/wolfcrypt/src/ecc.c +++ b/wolfcrypt/src/ecc.c @@ -4738,10 +4738,6 @@ int wc_ecc_init_ex(ecc_key* key, void* heap, int devId) key->heap = heap; #endif -#ifdef WOLFSSL_SILABS_SE_ACCEL - //TODO: anything? -#endif - #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC) /* handle as async */ ret = wolfAsync_DevCtxInit(&key->asyncDev, WOLFSSL_ASYNC_MARKER_ECC, @@ -5619,10 +5615,6 @@ int wc_ecc_free(ecc_key* key) } #endif -#ifdef WOLFSSL_SILABS_SE_ACCEL - // TODO: -#endif - #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC) #ifdef WC_ASYNC_ENABLE_ECC wolfAsync_DevCtxFree(&key->asyncDev, WOLFSSL_ASYNC_MARKER_ECC); @@ -6239,7 +6231,6 @@ int wc_ecc_verify_hash_ex(mp_int *r, mp_int *s, const byte* hash, word32 msgLenInBytes = hashlen; CRYS_ECPKI_HASH_OpMode_t hash_mode; #elif defined(WOLFSSL_SILABS_SE_ACCEL) - // TODO: byte sigRS[64*2]; #elif !defined(WOLFSSL_SP_MATH) || defined(FREESCALE_LTC_ECC) int did_init = 0; @@ -7362,8 +7353,7 @@ static int ecc_check_privkey_gen_helper(ecc_key* key) /* Hardware based private key, so this operation is not supported */ err = MP_OKAY; /* just report success */ #elif defined(WOLFSSL_SILABS_SE_ACCEL) - - // TODO: + /* Hardware based private key, so this operation is not supported */ err = MP_OKAY; /* just report success */ #else ALLOC_CURVE_SPECS(2); diff --git a/wolfcrypt/src/port/silabs/silabs_ecc.c b/wolfcrypt/src/port/silabs/silabs_ecc.c index 506883986..793913e01 100644 --- a/wolfcrypt/src/port/silabs/silabs_ecc.c +++ b/wolfcrypt/src/port/silabs/silabs_ecc.c @@ -71,7 +71,7 @@ sl_se_key_type_t silabs_map_key_type (ecc_curve_id curve_id) #endif default: - // TODO: log error + WOLFSSL_MSG("silabs_map_key_type() ECC curve unsupported by hardware"); res = 0; break; } From 919c2a2dfbe2d40a5fcecb86f4dd4fc1bbd040fc Mon Sep 17 00:00:00 2001 From: Elms Date: Mon, 7 Dec 2020 15:52:55 -0800 Subject: [PATCH 14/20] SiLabs: address PR comments to cleanup --- wolfcrypt/src/ecc.c | 10 +++---- wolfcrypt/src/port/silabs/README.md | 4 +-- wolfcrypt/src/port/silabs/silabs_ecc.c | 31 ++++++++++++++-------- wolfcrypt/src/port/silabs/silabs_hash.c | 6 ++--- wolfssl/wolfcrypt/port/silabs/silabs_ecc.h | 1 - wolfssl/wolfcrypt/settings.h | 4 ++- 6 files changed, 32 insertions(+), 24 deletions(-) diff --git a/wolfcrypt/src/ecc.c b/wolfcrypt/src/ecc.c index 365e510b6..d3180fafd 100644 --- a/wolfcrypt/src/ecc.c +++ b/wolfcrypt/src/ecc.c @@ -4864,7 +4864,7 @@ static int wc_ecc_sign_hash_hw(const byte* in, word32 inlen, #elif defined(WOLFSSL_SILABS_SE_ACCEL) err = silabs_ecc_sign_hash(in, inlen, out, outlen, key); if (err != 0) { - return BAD_COND_E; + return WC_HW_E; } #elif defined(WOLFSSL_CRYPTOCELL) @@ -6231,7 +6231,7 @@ int wc_ecc_verify_hash_ex(mp_int *r, mp_int *s, const byte* hash, word32 msgLenInBytes = hashlen; CRYS_ECPKI_HASH_OpMode_t hash_mode; #elif defined(WOLFSSL_SILABS_SE_ACCEL) - byte sigRS[64*2]; + byte sigRS[ECC_MAX_CRYPTO_HW_SIZE * 2]; #elif !defined(WOLFSSL_SP_MATH) || defined(FREESCALE_LTC_ECC) int did_init = 0; ecc_point *mG = NULL, *mQ = NULL; @@ -6351,9 +6351,9 @@ int wc_ecc_verify_hash_ex(mp_int *r, mp_int *s, const byte* hash, return err; } - silabs_ecc_verify_hash(&sigRS[0], keySz*2, - hash, hashlen, - res, key); + err = silabs_ecc_verify_hash(&sigRS[0], keySz*2, + hash, hashlen, + res, key); #else /* checking if private key with no public part */ diff --git a/wolfcrypt/src/port/silabs/README.md b/wolfcrypt/src/port/silabs/README.md index bd952ba37..7c92067ad 100644 --- a/wolfcrypt/src/port/silabs/README.md +++ b/wolfcrypt/src/port/silabs/README.md @@ -29,6 +29,7 @@ Update was preformed under Simplicity Studio directory: versions requesting too much data or too quickly may result in system reset and setting `SESYSREQ`. + ## Benchmarks See our [benchmarks](https://www.wolfssl.com/docs/benchmarks/) on the wolfSSL website. @@ -61,9 +62,6 @@ ECDSA 256 sign 158 ops took 1.010 sec, avg 6.392 ms, 156.436 ops/sec ECDSA 256 verify 148 ops took 1.001 sec, avg 6.764 ms, 147.852 ops/sec ``` -### Benchmarks and Memory Use - - # Support diff --git a/wolfcrypt/src/port/silabs/silabs_ecc.c b/wolfcrypt/src/port/silabs/silabs_ecc.c index 793913e01..76e86d361 100644 --- a/wolfcrypt/src/port/silabs/silabs_ecc.c +++ b/wolfcrypt/src/port/silabs/silabs_ecc.c @@ -33,10 +33,11 @@ #include +#define SILABS_UNSUPPORTED_KEY_TYPE 0xFFFFFFFF -sl_se_key_type_t silabs_map_key_type (ecc_curve_id curve_id) +static sl_se_key_type_t silabs_map_key_type (ecc_curve_id curve_id) { - sl_se_key_type_t res = 0; + sl_se_key_type_t res = SILABS_UNSUPPORTED_KEY_TYPE; switch(curve_id) { case ECC_SECP192R1: @@ -71,8 +72,7 @@ sl_se_key_type_t silabs_map_key_type (ecc_curve_id curve_id) #endif default: - WOLFSSL_MSG("silabs_map_key_type() ECC curve unsupported by hardware"); - res = 0; + res = SILABS_UNSUPPORTED_KEY_TYPE; break; } @@ -139,12 +139,14 @@ int silabs_ecc_make_key(ecc_key* key, int keysize) sl_status_t sl_stat; key->key.type = silabs_map_key_type(key->dp->id); + if (SILABS_UNSUPPORTED_KEY_TYPE == key->key.type) + return WC_HW_E; + key->key.size = keysize; key->key.storage.method = SL_SE_KEY_STORAGE_EXTERNAL_PLAINTEXT; key->key.flags = SL_SE_KEY_FLAG_ASYMMETRIC_BUFFER_HAS_PRIVATE_KEY | SL_SE_KEY_FLAG_ASYMMETRIC_BUFFER_HAS_PUBLIC_KEY - | SL_SE_KEY_FLAG_ASYMMMETRIC_SIGNING_ONLY - ; + | SL_SE_KEY_FLAG_ASYMMMETRIC_SIGNING_ONLY; sl_stat = sl_se_get_storage_size(&key->key, &key->key.storage.location.buffer.size); key->key.storage.location.buffer.pointer = key->key_raw; @@ -175,12 +177,14 @@ int silabs_ecc_import(ecc_key* key, word32 keysize) word32 used = keysize; key->key.type = silabs_map_key_type(key->dp->id); + if (SILABS_UNSUPPORTED_KEY_TYPE == key->key.type) + return WC_HW_E; + key->key.size = keysize; key->key.storage.method = SL_SE_KEY_STORAGE_EXTERNAL_PLAINTEXT; key->key.flags = SL_SE_KEY_FLAG_ASYMMETRIC_BUFFER_HAS_PRIVATE_KEY | SL_SE_KEY_FLAG_ASYMMETRIC_BUFFER_HAS_PUBLIC_KEY - | SL_SE_KEY_FLAG_ASYMMMETRIC_SIGNING_ONLY - ; + | SL_SE_KEY_FLAG_ASYMMMETRIC_SIGNING_ONLY; sl_stat = sl_se_get_storage_size(&key->key, &key->key.storage.location.buffer.size); key->key.storage.location.buffer.pointer = key->key_raw; @@ -211,11 +215,13 @@ int silabs_ecc_import_private(ecc_key* key, word32 keysize) sl_status_t sl_stat; word32 keySz = keysize; key->key.type = silabs_map_key_type(key->dp->id); + if (SILABS_UNSUPPORTED_KEY_TYPE == key->key.type) + return WC_HW_E; + key->key.size = key->dp->size; key->key.storage.method = SL_SE_KEY_STORAGE_EXTERNAL_PLAINTEXT; key->key.flags = SL_SE_KEY_FLAG_ASYMMETRIC_BUFFER_HAS_PRIVATE_KEY - | SL_SE_KEY_FLAG_ASYMMMETRIC_SIGNING_ONLY - ; + | SL_SE_KEY_FLAG_ASYMMMETRIC_SIGNING_ONLY; sl_stat = sl_se_get_storage_size(&key->key, &key->key.storage.location.buffer.size); key->key.storage.location.buffer.pointer = key->key_raw; @@ -233,6 +239,9 @@ int silabs_ecc_sig_to_rs(ecc_key* key, word32 keySz) int err = MP_OKAY; key->key.type = silabs_map_key_type(key->dp->id); + if (SILABS_UNSUPPORTED_KEY_TYPE == key->key.type) + return WC_HW_E; + key->key.size = keySz; key->key.storage.method = SL_SE_KEY_STORAGE_EXTERNAL_PLAINTEXT; key->key.flags = SL_SE_KEY_FLAG_ASYMMETRIC_BUFFER_HAS_PUBLIC_KEY @@ -294,7 +303,7 @@ int silabs_ecc_shared_secret(ecc_key* private_key, ecc_key* public_key, sl_status_t sl_stat; pub_key = public_key->key; - pub_key.flags = 0x2000; + pub_key.flags = SL_SE_KEY_FLAG_ASYMMETRIC_BUFFER_HAS_PUBLIC_KEY; *outlen = pub_key.size * 2; pub_sz = pub_key.size * 2; diff --git a/wolfcrypt/src/port/silabs/silabs_hash.c b/wolfcrypt/src/port/silabs/silabs_hash.c index b1214e431..0fc290f2c 100644 --- a/wolfcrypt/src/port/silabs/silabs_hash.c +++ b/wolfcrypt/src/port/silabs/silabs_hash.c @@ -40,10 +40,10 @@ int wc_silabs_se_hash_init (wc_silabs_sha_t* sha, enum wc_HashType type) int ret = 0; sl_status_t rr; - // set sizes and state + /* set sizes and state */ XMEMSET(sha, 0, sizeof(wc_silabs_sha_t)); - // set init state + /* set init state */ switch(type) { case WC_HASH_TYPE_SHA: rr = sl_se_hash_starts(&sha->hash_ctx, @@ -88,7 +88,7 @@ int wc_silabs_se_hash_init (wc_silabs_sha_t* sha, enum wc_HashType type) } if (rr == SL_STATUS_OK) { - // init handles if it is already initialized + /* init handles if it is already initialized */ ret = sl_se_init(); } else { ret = BUFFER_E; diff --git a/wolfssl/wolfcrypt/port/silabs/silabs_ecc.h b/wolfssl/wolfcrypt/port/silabs/silabs_ecc.h index 3f6cef898..ca13ea451 100644 --- a/wolfssl/wolfcrypt/port/silabs/silabs_ecc.h +++ b/wolfssl/wolfcrypt/port/silabs/silabs_ecc.h @@ -36,7 +36,6 @@ typedef enum ecc_curve_id ecc_curve_id; typedef struct ecc_key ecc_key; -sl_se_key_type_t silabs_map_key_type (ecc_curve_id curve_id); int silabs_ecc_sign_hash (const byte* in, word32 inlen, byte* out, word32 *outlen, ecc_key* key); diff --git a/wolfssl/wolfcrypt/settings.h b/wolfssl/wolfcrypt/settings.h index 3a9a202ca..e32019090 100644 --- a/wolfssl/wolfcrypt/settings.h +++ b/wolfssl/wolfcrypt/settings.h @@ -1394,7 +1394,9 @@ extern void uITRON4_free(void *p) ; #if defined(RTOS_MODULE_NET_AVAIL) || (APP_CFG_TCPIP_EN == DEF_ENABLED) #include #include - //#include + #if (OS_VERSION < 50000) + #include + #endif #endif #include #include From 620fe2da145bd217adab835e5c104ad8ba6b9a56 Mon Sep 17 00:00:00 2001 From: Elms Date: Tue, 8 Dec 2020 12:22:35 -0800 Subject: [PATCH 15/20] SiLabs: Fix tests and wc_ecc_import_private_key --- wolfcrypt/src/ecc.c | 9 +++++++-- wolfcrypt/test/test.c | 5 +++-- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/wolfcrypt/src/ecc.c b/wolfcrypt/src/ecc.c index d3180fafd..16416b3d2 100644 --- a/wolfcrypt/src/ecc.c +++ b/wolfcrypt/src/ecc.c @@ -6231,7 +6231,7 @@ int wc_ecc_verify_hash_ex(mp_int *r, mp_int *s, const byte* hash, word32 msgLenInBytes = hashlen; CRYS_ECPKI_HASH_OpMode_t hash_mode; #elif defined(WOLFSSL_SILABS_SE_ACCEL) - byte sigRS[ECC_MAX_CRYPTO_HW_SIZE * 2]; + byte sigRS[ECC_MAX_CRYPTO_HW_SIZE * 4]; #elif !defined(WOLFSSL_SP_MATH) || defined(FREESCALE_LTC_ECC) int did_init = 0; ecc_point *mG = NULL, *mQ = NULL; @@ -7975,7 +7975,12 @@ int wc_ecc_import_private_key_ex(const byte* priv, word32 privSz, } #elif defined(WOLFSSL_SILABS_SE_ACCEL) if (ret == MP_OKAY) { - ret = silabs_ecc_import_private(key, privSz); + if (pub) { + ret = silabs_ecc_import(key, privSz); + } else + { + ret = silabs_ecc_import_private(key, privSz); + } } #else diff --git a/wolfcrypt/test/test.c b/wolfcrypt/test/test.c index 00f5ce35b..16455f72d 100644 --- a/wolfcrypt/test/test.c +++ b/wolfcrypt/test/test.c @@ -22337,19 +22337,20 @@ static int ecc_test_buffers(void) TEST_SLEEP(); XMEMSET(plain, 0, sizeof(plain)); + verify = 1; do { #if defined(WOLFSSL_ASYNC_CRYPT) ret = wc_AsyncWait(ret, cliKey.asyncDev, WC_ASYNC_FLAG_CALL_AGAIN); #endif if (ret == 0) - ret = wc_ecc_verify_hash(out, x, plain, sizeof(plain), &verify, + ret = wc_ecc_verify_hash(out, x, plain, inLen, &verify, cliKey); } while (ret == WC_PENDING_E); if (ret < 0) ERROR_OUT(-10430, done); - if (XMEMCMP(plain, in, (word32)ret)) + if (verify != 0) ERROR_OUT(-10431, done); TEST_SLEEP(); From ef4db5b808359feac5666eff92cd029174653999 Mon Sep 17 00:00:00 2001 From: Elms Date: Tue, 8 Dec 2020 13:16:13 -0800 Subject: [PATCH 16/20] SiLabs: simplify init --- wolfcrypt/src/port/silabs/silabs_ecc.c | 3 +-- wolfcrypt/src/port/silabs/silabs_hash.c | 7 ++----- wolfcrypt/src/wc_port.c | 5 +++++ 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/wolfcrypt/src/port/silabs/silabs_ecc.c b/wolfcrypt/src/port/silabs/silabs_ecc.c index 76e86d361..65ab1c53b 100644 --- a/wolfcrypt/src/port/silabs/silabs_ecc.c +++ b/wolfcrypt/src/port/silabs/silabs_ecc.c @@ -245,8 +245,7 @@ int silabs_ecc_sig_to_rs(ecc_key* key, word32 keySz) key->key.size = keySz; key->key.storage.method = SL_SE_KEY_STORAGE_EXTERNAL_PLAINTEXT; key->key.flags = SL_SE_KEY_FLAG_ASYMMETRIC_BUFFER_HAS_PUBLIC_KEY - | SL_SE_KEY_FLAG_ASYMMMETRIC_SIGNING_ONLY - ; + | SL_SE_KEY_FLAG_ASYMMMETRIC_SIGNING_ONLY; sl_stat = sl_se_get_storage_size(&key->key, &key->key.storage.location.buffer.size); key->key.storage.location.buffer.pointer = key->key_raw; diff --git a/wolfcrypt/src/port/silabs/silabs_hash.c b/wolfcrypt/src/port/silabs/silabs_hash.c index 0fc290f2c..8de8cdd61 100644 --- a/wolfcrypt/src/port/silabs/silabs_hash.c +++ b/wolfcrypt/src/port/silabs/silabs_hash.c @@ -87,11 +87,8 @@ int wc_silabs_se_hash_init (wc_silabs_sha_t* sha, enum wc_HashType type) break; } - if (rr == SL_STATUS_OK) { - /* init handles if it is already initialized */ - ret = sl_se_init(); - } else { - ret = BUFFER_E; + if (rr != SL_STATUS_OK) { + ret = WC_HW_E; } return ret; diff --git a/wolfcrypt/src/wc_port.c b/wolfcrypt/src/wc_port.c index cc3d1e0fa..5b9ee6132 100644 --- a/wolfcrypt/src/wc_port.c +++ b/wolfcrypt/src/wc_port.c @@ -216,6 +216,11 @@ int wolfCrypt_Init(void) } #endif + #ifdef WOLFSSL_SILABS_SE_ACCEL + /* init handles if it is already initialized */ + ret = sl_se_init(); + #endif + #ifdef WOLFSSL_ARMASM WOLFSSL_MSG("Using ARM hardware acceleration"); #endif From 586a75302bfd3788ad6850cc5b5b187121ddbfab Mon Sep 17 00:00:00 2001 From: Elms Date: Wed, 9 Dec 2020 12:54:24 -0800 Subject: [PATCH 17/20] SiLabs: extra check on importing key to se_key buffer --- wolfcrypt/src/port/silabs/silabs_ecc.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/wolfcrypt/src/port/silabs/silabs_ecc.c b/wolfcrypt/src/port/silabs/silabs_ecc.c index 65ab1c53b..10c243784 100644 --- a/wolfcrypt/src/port/silabs/silabs_ecc.c +++ b/wolfcrypt/src/port/silabs/silabs_ecc.c @@ -213,6 +213,7 @@ int silabs_ecc_import(ecc_key* key, word32 keysize) int silabs_ecc_import_private(ecc_key* key, word32 keysize) { sl_status_t sl_stat; + int ret = 0; word32 keySz = keysize; key->key.type = silabs_map_key_type(key->dp->id); if (SILABS_UNSUPPORTED_KEY_TYPE == key->key.type) @@ -228,9 +229,14 @@ int silabs_ecc_import_private(ecc_key* key, word32 keysize) if (sl_stat != SL_STATUS_OK) return WC_HW_E; - return wc_export_int(&key->k, key->key.storage.location.buffer.pointer, - &keySz, keySz, - WC_TYPE_UNSIGNED_BIN); + ret = wc_export_int(&key->k, key->key.storage.location.buffer.pointer, + &keySz, keySz, + WC_TYPE_UNSIGNED_BIN); + + if (keySz != keysize) + ret = WC_HW_E; + + return ret; } int silabs_ecc_sig_to_rs(ecc_key* key, word32 keySz) From 93fc37f87b4f730599494d202d4ecb4002b105f8 Mon Sep 17 00:00:00 2001 From: Elms Date: Wed, 9 Dec 2020 16:28:39 -0800 Subject: [PATCH 18/20] SiLabs: add cleanup and address PR comments --- wolfcrypt/src/ecc.c | 7 +++++-- wolfcrypt/src/wc_port.c | 3 +++ wolfcrypt/test/test.c | 5 ++--- 3 files changed, 10 insertions(+), 5 deletions(-) diff --git a/wolfcrypt/src/ecc.c b/wolfcrypt/src/ecc.c index 16416b3d2..9c81e7083 100644 --- a/wolfcrypt/src/ecc.c +++ b/wolfcrypt/src/ecc.c @@ -7974,12 +7974,15 @@ int wc_ecc_import_private_key_ex(const byte* priv, word32 privSz, ret = mp_read_unsigned_bin(&key->k, priv, privSz); } #elif defined(WOLFSSL_SILABS_SE_ACCEL) + if (ret == MP_OKAY) + ret = mp_read_unsigned_bin(&key->k, priv, privSz); + if (ret == MP_OKAY) { if (pub) { - ret = silabs_ecc_import(key, privSz); + ret = silabs_ecc_import(key, key->dp->size); } else { - ret = silabs_ecc_import_private(key, privSz); + ret = silabs_ecc_import_private(key, key->dp->size); } } #else diff --git a/wolfcrypt/src/wc_port.c b/wolfcrypt/src/wc_port.c index 5b9ee6132..055f7cd91 100644 --- a/wolfcrypt/src/wc_port.c +++ b/wolfcrypt/src/wc_port.c @@ -333,6 +333,9 @@ int wolfCrypt_Cleanup(void) #if defined(WOLFSSL_CRYPTOCELL) cc310_Free(); #endif + #ifdef WOLFSSL_SILABS_SE_ACCEL + ret = sl_se_deinit(); + #endif #if defined(WOLFSSL_RENESAS_TSIP_CRYPT) tsip_Close(); #endif diff --git a/wolfcrypt/test/test.c b/wolfcrypt/test/test.c index 16455f72d..f36ce8af4 100644 --- a/wolfcrypt/test/test.c +++ b/wolfcrypt/test/test.c @@ -22337,20 +22337,19 @@ static int ecc_test_buffers(void) TEST_SLEEP(); XMEMSET(plain, 0, sizeof(plain)); - verify = 1; do { #if defined(WOLFSSL_ASYNC_CRYPT) ret = wc_AsyncWait(ret, cliKey.asyncDev, WC_ASYNC_FLAG_CALL_AGAIN); #endif if (ret == 0) - ret = wc_ecc_verify_hash(out, x, plain, inLen, &verify, + ret = wc_ecc_verify_hash(out, x, in, inLen, &verify, cliKey); } while (ret == WC_PENDING_E); if (ret < 0) ERROR_OUT(-10430, done); - if (verify != 0) + if (verify != 1) ERROR_OUT(-10431, done); TEST_SLEEP(); From 9ba78eb825910bdb74bcb6713b74632b8d10b955 Mon Sep 17 00:00:00 2001 From: Elms Date: Thu, 10 Dec 2020 07:45:42 -0800 Subject: [PATCH 19/20] SiLabs: Clarify comments and fix sig buffer size --- wolfcrypt/src/ecc.c | 2 +- wolfcrypt/src/port/silabs/README.md | 6 ++++++ wolfssl/wolfcrypt/ecc.h | 4 ++++ 3 files changed, 11 insertions(+), 1 deletion(-) diff --git a/wolfcrypt/src/ecc.c b/wolfcrypt/src/ecc.c index 9c81e7083..c7b8415b0 100644 --- a/wolfcrypt/src/ecc.c +++ b/wolfcrypt/src/ecc.c @@ -6231,7 +6231,7 @@ int wc_ecc_verify_hash_ex(mp_int *r, mp_int *s, const byte* hash, word32 msgLenInBytes = hashlen; CRYS_ECPKI_HASH_OpMode_t hash_mode; #elif defined(WOLFSSL_SILABS_SE_ACCEL) - byte sigRS[ECC_MAX_CRYPTO_HW_SIZE * 4]; + byte sigRS[ECC_MAX_CRYPTO_HW_SIZE * 2]; #elif !defined(WOLFSSL_SP_MATH) || defined(FREESCALE_LTC_ECC) int did_init = 0; ecc_point *mG = NULL, *mQ = NULL; diff --git a/wolfcrypt/src/port/silabs/README.md b/wolfcrypt/src/port/silabs/README.md index 7c92067ad..d6d0f782b 100644 --- a/wolfcrypt/src/port/silabs/README.md +++ b/wolfcrypt/src/port/silabs/README.md @@ -29,6 +29,12 @@ Update was preformed under Simplicity Studio directory: versions requesting too much data or too quickly may result in system reset and setting `SESYSREQ`. +### Multi-threading + +The SE manager supports multi-threading for FreeRTOS and Micrium +([ref](https://docs.silabs.com/gecko-platform/latest/service/api/group-sl-se-manager#autotoc-md152)). +If a different OS is used with multi-threading, additional mutex +protection may be necessary. ## Benchmarks diff --git a/wolfssl/wolfcrypt/ecc.h b/wolfssl/wolfcrypt/ecc.h index 97b070ea2..777aa0e4d 100644 --- a/wolfssl/wolfcrypt/ecc.h +++ b/wolfssl/wolfcrypt/ecc.h @@ -404,6 +404,10 @@ struct ecc_key { #ifdef WOLFSSL_SILABS_SE_ACCEL sl_se_command_context_t cmd_ctx; sl_se_key_descriptor_t key; + /* Used for SiLabs "plaintext" with public X, public Y, and + * private D concatenated. These are respectively at offset `0`, + * offset `keysize`, and offset `2 * keysize`. + */ byte key_raw[3 * ECC_MAX_CRYPTO_HW_SIZE]; #endif From 40087f1fd0a7981544a841f17c5e5da6f8bbace7 Mon Sep 17 00:00:00 2001 From: Elms Date: Thu, 10 Dec 2020 20:26:59 -0800 Subject: [PATCH 20/20] SiLabs: AES return code fixup and comment cleanup --- wolfcrypt/src/port/silabs/silabs_aes.c | 4 ++-- wolfssl/wolfcrypt/settings.h | 5 +++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/wolfcrypt/src/port/silabs/silabs_aes.c b/wolfcrypt/src/port/silabs/silabs_aes.c index 2bcaf2258..e98b52f77 100644 --- a/wolfcrypt/src/port/silabs/silabs_aes.c +++ b/wolfcrypt/src/port/silabs/silabs_aes.c @@ -99,7 +99,7 @@ int wc_AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz) (uint8_t*)aes->reg, in, out); - return (status != SL_STATUS_OK); + return (status != SL_STATUS_OK) ? WC_HW_E : 0; } int wc_AesCbcDecrypt(Aes* aes, byte* out, const byte* in, word32 sz) @@ -112,7 +112,7 @@ int wc_AesCbcDecrypt(Aes* aes, byte* out, const byte* in, word32 sz) (uint8_t*)aes->reg, in, out); - return (status != SL_STATUS_OK); + return (status != SL_STATUS_OK) ? WC_HW_E : 0; } #ifdef HAVE_AESGCM diff --git a/wolfssl/wolfcrypt/settings.h b/wolfssl/wolfcrypt/settings.h index e32019090..3d0d39661 100644 --- a/wolfssl/wolfcrypt/settings.h +++ b/wolfssl/wolfcrypt/settings.h @@ -1463,8 +1463,9 @@ extern void uITRON4_free(void *p) ; (void *)(pmem_2), \ (CPU_SIZE_T)(size))) ? DEF_NO : DEF_YES) #else - // Work aroud for Micrium OS version 5.8 change in behavior - // that returns DEF_NO for 0 size compare + /* Work around for Micrium OS version 5.8 change in behavior + * that returns DEF_NO for 0 size compare + */ #define XMEMCMP(pmem_1, pmem_2, size) \ (( (size < 1 ) || \ ((CPU_BOOLEAN)Mem_Cmp((void *)(pmem_1), \