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) diff --git a/wolfcrypt/benchmark/benchmark.c b/wolfcrypt/benchmark/benchmark.c index 33de9b85f..0fce5ee1e 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 @@ -5315,7 +5317,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); @@ -6030,10 +6032,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/wolfcrypt/src/aes.c b/wolfcrypt/src/aes.c index 098d36bc9..c2795c64c 100644 --- a/wolfcrypt/src/aes.c +++ b/wolfcrypt/src/aes.c @@ -2688,6 +2688,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 */ @@ -3630,6 +3633,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 */ @@ -6790,6 +6796,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, @@ -7261,6 +7275,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( @@ -7539,6 +7560,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/ecc.c b/wolfcrypt/src/ecc.c index 05d3e6df6..e68fee460 100644 --- a/wolfcrypt/src/ecc.c +++ b/wolfcrypt/src/ecc.c @@ -3784,7 +3784,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 */ @@ -4201,7 +4202,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 @@ -4215,7 +4217,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) { @@ -4338,7 +4341,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) { @@ -4515,6 +4518,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 @@ -4846,8 +4851,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) @@ -4894,6 +4901,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 WC_HW_E; + } #elif defined(WOLFSSL_CRYPTOCELL) hash_mode = cc310_hashModeECC(msgLenInBytes); @@ -5091,7 +5103,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); @@ -6283,6 +6296,8 @@ 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) + 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; @@ -6393,6 +6408,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; + } + + 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) { @@ -7382,7 +7413,9 @@ 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) + /* Hardware based private key, so this operation is not supported */ + err = MP_OKAY; /* just report success */ #else ALLOC_CURVE_SPECS(2); @@ -7521,7 +7554,7 @@ int wc_ecc_check_key(ecc_key* key) #ifndef WOLFSSL_SP_MATH #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 */ @@ -7803,6 +7836,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); @@ -7993,7 +8030,18 @@ 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, key->dp->size); + } else + { + ret = silabs_ecc_import_private(key, key->dp->size); + } + } #else ret = mp_read_unsigned_bin(&key->k, priv, privSz); @@ -8141,6 +8189,11 @@ 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 @@ -8208,13 +8261,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; @@ -8252,8 +8310,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/include.am b/wolfcrypt/src/include.am index 5eb41df96..196feb42b 100644 --- a/wolfcrypt/src/include.am +++ b/wolfcrypt/src/include.am @@ -67,6 +67,11 @@ 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_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 \ 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..d6d0f782b --- /dev/null +++ b/wolfcrypt/src/port/silabs/README.md @@ -0,0 +1,74 @@ +# Silicon Labs (silabs) Port + +Support for the Silicon Labs hardware acceleration + +Tested on ERF32 Gecko Series 2 device config 1 (Secure Element) + +* https://docs.silabs.com/mcu/latest/efr32mg21/group-SE +* https://docs.silabs.com/gecko-platform/latest/service/api/group-sl-se-manager + +## Building + +To enable support define the following: + +``` +#define WOLFSSL_SILABS_SE_ACCEL +``` + +## Caveats + +:warning: **Be sure to update the SE firmware** Testing and results were done using SE firmware `1.2.6` + +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. On early SE firmware + 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 + +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 +``` + + +# 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..e98b52f77 --- /dev/null +++ b/wolfcrypt/src/port/silabs/silabs_aes.c @@ -0,0 +1,211 @@ +/* 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) ? WC_HW_E : 0; +} + +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) ? WC_HW_E : 0; +} + +#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 */ + + +#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/wolfcrypt/src/port/silabs/silabs_ecc.c b/wolfcrypt/src/port/silabs/silabs_ecc.c new file mode 100644 index 000000000..10c243784 --- /dev/null +++ b/wolfcrypt/src/port/silabs/silabs_ecc.c @@ -0,0 +1,333 @@ +/* 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 + + +#define SILABS_UNSUPPORTED_KEY_TYPE 0xFFFFFFFF + +static sl_se_key_type_t silabs_map_key_type (ecc_curve_id curve_id) +{ + sl_se_key_type_t res = SILABS_UNSUPPORTED_KEY_TYPE; + + 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: + res = SILABS_UNSUPPORTED_KEY_TYPE; + break; + } + + return res; +} + +int silabs_ecc_sign_hash(const byte* in, word32 inlen, byte* out, word32 *outlen, ecc_key* key) +{ + sl_status_t sl_stat = sl_se_init_command_context(&(key->cmd_ctx)); + word32 siglen = *outlen; + + sl_stat = sl_se_validate_key(&(key->key)); + + if (key->dp->size * 2 <= (int)siglen) { + siglen = key->dp->size * 2; + } + + sl_stat = sl_se_ecc_sign( + &(key->cmd_ctx), + &(key->key), + 0, + 1, + in, + inlen, + out, + siglen + ); + + return (sl_stat == SL_STATUS_OK) ? 0 : WC_HW_E; +} + +#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 sl_stat = sl_se_init_command_context(&(key->cmd_ctx)); + + sl_stat = sl_se_ecc_verify( + &(key->cmd_ctx), + &(key->key), + 0, + 1, + hash, + hashlen, + sig, + siglen); + + if (sl_stat == SL_STATUS_OK) { + *stat = 1; + } else if (sl_stat == SL_STATUS_INVALID_SIGNATURE) { + *stat = 0; + } else { + return WC_HW_E; + } + + 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); + 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_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 : WC_HW_E; +} + +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); + 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_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; + + /* 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; + int ret = 0; + 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_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; + + 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) +{ + sl_status_t sl_stat; + 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 + | 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 (sl_stat != SL_STATUS_OK) + return WC_HW_E; + + 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, const char* 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 (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); + 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 = SL_SE_KEY_FLAG_ASYMMETRIC_BUFFER_HAS_PUBLIC_KEY; + + *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 : WC_HW_E; +} + +#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..8de8cdd61 --- /dev/null +++ b/wolfcrypt/src/port/silabs/silabs_hash.c @@ -0,0 +1,302 @@ +/* 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) { + ret = WC_HW_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/port/silabs/silabs_random.c b/wolfcrypt/src/port/silabs/silabs_random.c new file mode 100644 index 000000000..582f400a8 --- /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..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; @@ -927,6 +931,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 +1916,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/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/src/wc_port.c b/wolfcrypt/src/wc_port.c index ced1711e1..36c2fe9f6 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 @@ -328,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 @@ -1232,14 +1240,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,26 +1265,27 @@ 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; #else + (void)m; return 0; #endif } 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 +1293,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 8920115ee..c49ab7c20 100644 --- a/wolfcrypt/test/test.c +++ b/wolfcrypt/test/test.c @@ -91,10 +91,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*, ...); @@ -9050,6 +9055,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))) @@ -9551,8 +9557,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[] = @@ -9587,8 +9594,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)); @@ -21077,6 +21085,7 @@ static int ecc_ssh_test(ecc_key* key, WC_RNG* rng) } while (ret == WC_PENDING_E); if (ret != 0) return -10085; + TEST_SLEEP(); return 0; } @@ -22289,7 +22298,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); @@ -22635,13 +22644,13 @@ static int ecc_test_buffers(void) 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, in, inLen, &verify, cliKey); } while (ret == WC_PENDING_E); if (ret < 0) ERROR_OUT(-10430, done); - if (XMEMCMP(plain, in, (word32)ret)) + if (verify != 1) ERROR_OUT(-10431, done); TEST_SLEEP(); diff --git a/wolfssl/wolfcrypt/aes.h b/wolfssl/wolfcrypt/aes.h index d879d4db9..1141b0c71 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 @@ -240,6 +245,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/ecc.h b/wolfssl/wolfcrypt/ecc.h index de714e43f..94530b2da 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, @@ -396,6 +402,16 @@ 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; + /* 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 + #ifdef WOLFSSL_ASYNC_CRYPT mp_int* r; /* sign/verify temps */ mp_int* s; diff --git a/wolfssl/wolfcrypt/include.am b/wolfssl/wolfcrypt/include.am index 8041a8bbc..647714956 100644 --- a/wolfssl/wolfcrypt/include.am +++ b/wolfssl/wolfcrypt/include.am @@ -80,6 +80,10 @@ 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_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 \ diff --git a/wolfssl/wolfcrypt/port/silabs/silabs_aes.h b/wolfssl/wolfcrypt/port/silabs/silabs_aes.h new file mode 100644 index 000000000..3b9d4f140 --- /dev/null +++ b/wolfssl/wolfcrypt/port/silabs/silabs_aes.h @@ -0,0 +1,67 @@ +/* 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; + +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, + 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 */ + +#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_ */ diff --git a/wolfssl/wolfcrypt/port/silabs/silabs_ecc.h b/wolfssl/wolfcrypt/port/silabs/silabs_ecc.h new file mode 100644 index 000000000..ca13ea451 --- /dev/null +++ b/wolfssl/wolfcrypt/port/silabs/silabs_ecc.h @@ -0,0 +1,63 @@ +/* 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; + +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, const char* 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/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/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 78f5b79ea..3e7be58d1 100644 --- a/wolfssl/wolfcrypt/settings.h +++ b/wolfssl/wolfcrypt/settings.h @@ -1391,11 +1391,18 @@ 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 + #if (OS_VERSION < 50000) + #include + #endif + #endif #include #include + #include + #include + #include #define USE_FAST_MATH #define TFM_TIMING_RESISTANT @@ -1419,7 +1426,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 @@ -1449,10 +1456,25 @@ 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 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), \ + (void *)(pmem_2), \ + (CPU_SIZE_T)(size)) == DEF_YES)) \ + ? 0 : 1) + #define XSNPRINTF snprintf + #endif + #define XMEMMOVE XMEMCPY #if (OS_CFG_MUTEX_EN == DEF_DISABLED) 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