From 79c31a5f2c809d110410e20f1733876056fcafeb Mon Sep 17 00:00:00 2001 From: Elms Date: Fri, 6 Nov 2020 12:20:03 -0800 Subject: [PATCH] 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