diff --git a/configure.ac b/configure.ac index 72b1cb500..cdc5fb41d 100644 --- a/configure.ac +++ b/configure.ac @@ -1336,6 +1336,60 @@ AC_ARG_WITH([cryptoauthlib], ] ) +# NXP SE050 +# Example: "./configure --with-se050=/home/pi/simw_top" +ENABLED_SE050="no" +trylibse050dir="" +AC_ARG_WITH([se050], + [AS_HELP_STRING([--with-se050=PATH],[PATH to SE050 install (default /usr/local/lib/)])], + [ + AC_MSG_CHECKING([for SE050]) + + LIBS="$LIBS -lSSS_APIs" + AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include ]], [[ sss_mac_init(0);]])],[ libse050_linked=yes ],[ libse050_linked=no ]) + + if test "x$libse050_linked" = "xno" ; then + if test "x$withval" != "xno" ; then + trylibse050dir=$withval + fi + if test "x$withval" = "xyes" ; then + trylibse050dir="/usr/local/lib/" + fi + LDFLAGS="$LDFLAGS -L$trylibse050dir/build/sss" + CPPFLAGS="$CPPFLAGS -I$trylibse050dir/build" + CPPFLAGS="$CPPFLAGS -I$trylibse050dir/sss/inc" + CPPFLAGS="$CPPFLAGS -I$trylibse050dir/sss/ex/inc" + CPPFLAGS="$CPPFLAGS -I$trylibse050dir/sss/port/default" + CPPFLAGS="$CPPFLAGS -I$trylibse050dir/hostlib/hostLib/inc" + CPPFLAGS="$CPPFLAGS -I$trylibse050dir/hostlib/hostLib/libCommon/infra" + + AC_CHECK_FILES([$trylibse050dir/build/sss/libSSS_APIs.a], [SE050_STATIC=yes], [SE050_STATIC=no]) + if test "x$SE050_STATIC" = "xyes"; then + LIB_STATIC_ADD="$trylibse050dir/build/sss/ex/src/libex_common.a \ + $trylibse050dir/build/sss/libSSS_APIs.a \ + $trylibse050dir/build/hostlib/hostLib/se05x/libse05x.a \ + $trylibse050dir/build/hostlib/hostLib/liba7x_utils.a \ + $trylibse050dir/build/hostlib/hostLib/libCommon/libsmCom.a $LIB_STATIC_ADD" + else + AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include ]], [[ sss_mac_init(0); ]])],[ libse050_linked=yes ],[ libse050_linked=no ]) + if test "x$libse050_linked" = "xno" ; then + AC_MSG_ERROR([SE050 isn't found. + If it's already installed, specify its path using --with-se050=/dir/]) + fi + fi + + # Requires AES direct + AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_AES_DIRECT" + + AC_MSG_RESULT([yes]) + else + AC_MSG_RESULT([yes]) + fi + + ENABLED_SE050="yes" + AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_SE050 -DSSS_USE_FTR_FILE" + ] +) # sniffer doesn't work in maxstrength mode if test "$ENABLED_SNIFFER" = "yes" && test "$ENABLED_MAXSTRENGTH" = "yes" @@ -7035,6 +7089,7 @@ AM_CONDITIONAL([BUILD_RC2],[test "x$ENABLED_RC2" = "xyes"]) AM_CONDITIONAL([BUILD_QNXCAAM],[test "x$ENABLED_CAAM" = "xqnx"]) AM_CONDITIONAL([BUILD_IOTSAFE],[test "x$ENABLED_IOTSAFE" = "xyes"]) AM_CONDITIONAL([BUILD_IOTSAFE_HWRNG],[test "x$ENABLED_IOTSAFE_HWRNG" = "xyes"]) +AM_CONDITIONAL([BUILD_SE050],[test "x$ENABLED_SE050" = "xyes"]) if test "$ax_enable_debug" = "yes" || test "$ENABLED_STACKSIZE" != "no" || @@ -7409,6 +7464,7 @@ echo " * Crypto callbacks: $ENABLED_CRYPTOCB" echo " * i.MX6 CAAM: $ENABLED_CAAM" echo " * IoT-Safe: $ENABLED_IOTSAFE" echo " * IoT-Safe HWRNG: $ENABLED_IOTSAFE_HWRNG" +echo " * NXP SE050: $ENABLED_SE050" echo "" echo "---" diff --git a/wolfcrypt/src/aes.c b/wolfcrypt/src/aes.c index 16354ee50..1538f095e 100644 --- a/wolfcrypt/src/aes.c +++ b/wolfcrypt/src/aes.c @@ -68,7 +68,9 @@ block cipher mechanism that uses n-bit binary string parameter key with 128-bits #ifdef WOLFSSL_IMXRT_DCP #include #endif - +#ifdef WOLFSSL_SE050 + #include +#endif /* fips wrapper calls, user can call direct */ #if defined(HAVE_FIPS) && \ @@ -867,6 +869,28 @@ block cipher mechanism that uses n-bit binary string parameter key with 128-bits #elif defined(WOLFSSL_DEVCRYPTO_AES) /* implemented in wolfcrypt/src/port/devcrypto/devcrypto_aes.c */ +#elif defined(WOLFSSL_SE050) + static int AES_ECB_encrypt(Aes* aes, const byte* inBlock, byte* outBlock, + int sz) + { + return se050_aes_crypt(aes, inBlock, outBlock, sz, AES_ENCRYPTION, + kAlgorithm_SSS_AES_ECB); + } + static int AES_ECB_decrypt(Aes* aes, const byte* inBlock, byte* outBlock, + int sz) + { + return se050_aes_crypt(aes, inBlock, outBlock, sz, AES_DECRYPTION, + kAlgorithm_SSS_AES_ECB); + } + static int wc_AesEncrypt(Aes* aes, const byte* inBlock, byte* outBlock) + { + return AES_ECB_encrypt(aes, inBlock, outBlock, AES_BLOCK_SIZE); + } + static int wc_AesDecrypt(Aes* aes, const byte* inBlock, byte* outBlock) + { + return AES_ECB_decrypt(aes, inBlock, outBlock, AES_BLOCK_SIZE); + } + #elif defined(WOLFSSL_SCE) && !defined(WOLFSSL_SCE_NO_AES) #include "hal_data.h" @@ -2576,6 +2600,35 @@ static void wc_AesDecrypt(Aes* aes, const byte* inBlock, byte* outBlock) return wc_AesSetKey(aes, userKey, keylen, iv, dir); } +#elif defined(WOLFSSL_SE050) + int wc_AesSetKey(Aes* aes, const byte* userKey, word32 keylen, const byte* iv, + int dir) + { + int ret; + + if (aes == NULL || (keylen != 16 && keylen != 24 && keylen != 32)) { + return BAD_FUNC_ARG; + } + + aes->ctxInitDone = 0; + #if defined(WOLFSSL_AES_CFB) || defined(WOLFSSL_AES_COUNTER) || \ + defined(WOLFSSL_AES_OFB) + aes->left = 0; + #endif + + ret = se050_aes_set_key(aes, userKey, keylen, iv, dir); + if (ret == 0) { + ret = wc_AesSetIV(aes, iv); + } + return ret; + } + + int wc_AesSetKeyDirect(Aes* aes, const byte* userKey, word32 keylen, + const byte* iv, int dir) + { + return wc_AesSetKey(aes, userKey, keylen, iv, dir); + } + #elif defined(WOLFSSL_NRF51_AES) int wc_AesSetKey(Aes* aes, const byte* userKey, word32 keylen, const byte* iv, int dir) @@ -3830,6 +3883,18 @@ 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_SE050) + int wc_AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz) + { + return se050_aes_crypt(aes, in, out, sz, AES_ENCRYPTION, + kAlgorithm_SSS_AES_CBC); + } + int wc_AesCbcDecrypt(Aes* aes, byte* out, const byte* in, word32 sz) + { + return se050_aes_crypt(aes, in, out, sz, AES_DECRYPTION, + kAlgorithm_SSS_AES_CBC); + } + #elif defined(WOLFSSL_SILABS_SE_ACCEL) /* implemented in wolfcrypt/src/port/silabs/silabs_hash.c */ @@ -10331,6 +10396,11 @@ void wc_AesFree(Aes* aes) XFREE(aes->streamData, aes->heap, DYNAMIC_TYPE_AES); } #endif + +#if defined(WOLFSSL_SE050) + se050_aes_free(aes); +#endif + } diff --git a/wolfcrypt/src/ecc.c b/wolfcrypt/src/ecc.c index 7c764c83d..037dba0b0 100644 --- a/wolfcrypt/src/ecc.c +++ b/wolfcrypt/src/ecc.c @@ -3943,6 +3943,8 @@ int wc_ecc_shared_secret(ecc_key* private_key, ecc_key* public_key, byte* out, err = silabs_ecc_shared_secret(private_key, public_key, out, outlen); #elif defined(WOLFSSL_KCAPI_ECC) err = KcapiEcc_SharedSecret(private_key, public_key, out, outlen); +#elif defined(WOLFSSL_SE050) + err = se050_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 */ @@ -4615,7 +4617,8 @@ int wc_ecc_make_key_ex2(WC_RNG* rng, int keysize, ecc_key* key, int curve_id, int err; #if !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_ATECC608A) && \ - !defined(WOLFSSL_CRYPTOCELL) && !defined(WOLFSSL_KCAPI_ECC) + !defined(WOLFSSL_CRYPTOCELL) && !defined(WOLFSSL_KCAPI_ECC) && \ + !defined(WOLFSSL_SE050) #if !defined(WOLFSSL_SP_MATH) DECLARE_CURVE_SPECS(curve, ECC_CURVE_FIELD_COUNT); #endif @@ -4698,6 +4701,9 @@ int wc_ecc_make_key_ex2(WC_RNG* rng, int keysize, ecc_key* key, int curve_id, else { err = NOT_COMPILED_IN; } +#elif defined(WOLFSSL_SE050) + err = se050_ecc_create_key(key, curve_id, keysize); + key->type = ECC_PRIVATEKEY; #elif defined(WOLFSSL_CRYPTOCELL) pDomain = CRYS_ECPKI_GetEcDomain(cc310_mapCurve(key->dp->id)); @@ -5002,6 +5008,11 @@ int wc_ecc_init_ex(ecc_key* key, void* heap, int devId) #if defined(WOLFSSL_DSP) key->handle = -1; #endif + +#ifdef WOLFSSL_SE050 + key->keyId = -1; +#endif + return ret; } @@ -5098,7 +5109,8 @@ static int wc_ecc_get_curve_order_bit_count(const ecc_set_type* dp) #if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A) || \ defined(PLUTON_CRYPTO_ECC) || defined(WOLFSSL_CRYPTOCELL) || \ - defined(WOLFSSL_SILABS_SE_ACCEL) || defined(WOLFSSL_KCAPI_ECC) + defined(WOLFSSL_SILABS_SE_ACCEL) || defined(WOLFSSL_KCAPI_ECC) || \ + defined(WOLFSSL_SE050) 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) @@ -5183,6 +5195,12 @@ static int wc_ecc_sign_hash_hw(const byte* in, word32 inlen, #elif defined(WOLFSSL_KCAPI_ECC) err = KcapiEcc_Sign(key, in, inlen, out, outlen); (void)rng; + #elif defined(WOLFSSL_SE050) + err = se050_ecc_sign_hash_ex(in, inlen, out, outlen, key); + if (err == 0) + err = DecodeECC_DSA_Sig(out, *outlen, r, s); + + return err; #endif /* Load R and S */ @@ -5357,7 +5375,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(WOLFSSL_SILABS_SE_ACCEL) || defined(WOLFSSL_KCAPI_ECC) + defined(WOLFSSL_SILABS_SE_ACCEL) || defined(WOLFSSL_KCAPI_ECC) || \ + defined(WOLFSSL_SE050) 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); @@ -6280,6 +6299,10 @@ int wc_ecc_free(ecc_key* key) } #endif +#ifdef WOLFSSL_SE050 + se050_ecc_free_key(key); +#endif + #if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A) atmel_ecc_free(key->slot); key->slot = ATECC_INVALID_SLOT; @@ -6952,6 +6975,12 @@ int wc_ecc_verify_hash_ex(mp_int *r, mp_int *s, const byte* hash, byte sigRS[ECC_MAX_CRYPTO_HW_SIZE * 2]; #elif defined(WOLFSSL_KCAPI_ECC) byte sigRS[MAX_ECC_BYTES*2]; +#elif defined(WOLFSSL_SE050) + #ifdef WOLFSSL_SMALL_STACK + byte* sigRS = NULL; + #else + byte sigRS[ECC_MAX_CRYPTO_HW_SIZE * 2]; + #endif #elif !defined(WOLFSSL_SP_MATH) || defined(FREESCALE_LTC_ECC) int did_init = 0; ecc_point *mG = NULL, *mQ = NULL; @@ -7095,6 +7124,42 @@ int wc_ecc_verify_hash_ex(mp_int *r, mp_int *s, const byte* hash, } err = KcapiEcc_Verify(key, hash, hashlen, sigRS, key->dp->size * 2); +#elif defined(WOLFSSL_SE050) + { + /* Used when following a hardware sign operation */ + int rLeadingZero = mp_leading_bit(r); + int sLeadingZero = mp_leading_bit(s); + int rLen = mp_unsigned_bin_size(r); + int sLen = mp_unsigned_bin_size(s); + word32 signatureLen = rLeadingZero + sLeadingZero + + rLen + sLen + SIG_HEADER_SZ; /* see StoreECC_DSA_Sig */ + + #ifdef WOLFSSL_SMALL_STACK + sigRS = (byte*)XMALLOC(signatureLen, NULL, DYNAMIC_TYPE_SIGNATURE); + if (sigRS == NULL) { + err = MEMORY_E; + } + #else + if (signatureLen > sizeof(sigRS)) { + err = BUFFER_E; + } + #endif + if (err == 0) { + err = StoreECC_DSA_Sig(sigRS, &signatureLen, r, s); + } + if (err == 0) { + err = se050_ecc_verify_hash_ex(hash, hashlen, sigRS, + signatureLen, key, res); + } + #ifdef WOLFSSL_SMALL_STACK + if (sigRS != NULL) { + XFREE(sigRS, NULL, DYNAMIC_TYPE_SIGNATURE); + sigRS = NULL; + } + #endif + if (err != 0) + return err; + } #else /* checking if private key with no public part */ if (key->type == ECC_PRIVATEKEY_ONLY) { diff --git a/wolfcrypt/src/ed25519.c b/wolfcrypt/src/ed25519.c index b161008e4..2b87c86f0 100644 --- a/wolfcrypt/src/ed25519.c +++ b/wolfcrypt/src/ed25519.c @@ -262,6 +262,13 @@ int wc_ed25519_sign_msg_ex(const byte* in, word32 inLen, byte* out, word32 *outLen, ed25519_key* key, byte type, const byte* context, byte contextLen) { + int ret; +#ifdef WOLFSSL_SE050 + (void)context; + (void)contextLen; + (void)type; + ret = se050_ed25519_sign_msg(in, inLen, out, outLen, key); +#else #ifdef FREESCALE_LTC_ECC byte tempBuf[ED25519_PRV_KEY_SIZE]; ltc_pkha_ecc_point_t ltcPoint = {0}; @@ -271,7 +278,6 @@ int wc_ed25519_sign_msg_ex(const byte* in, word32 inLen, byte* out, byte nonce[WC_SHA512_DIGEST_SIZE]; byte hram[WC_SHA512_DIGEST_SIZE]; byte az[ED25519_PRV_KEY_SIZE]; - int ret; /* sanity check on arguments */ if (in == NULL || out == NULL || outLen == NULL || key == NULL || @@ -406,7 +412,7 @@ int wc_ed25519_sign_msg_ex(const byte* in, word32 inLen, byte* out, sc_reduce(hram); sc_muladd(out + (ED25519_SIG_SIZE/2), hram, az, nonce); #endif - +#endif /* WOLFSSL_SE050 */ return ret; } @@ -492,7 +498,7 @@ int wc_ed25519ph_sign_msg(const byte* in, word32 inLen, byte* out, #endif /* HAVE_ED25519_SIGN */ #ifdef HAVE_ED25519_VERIFY - +#ifndef WOLFSSL_SE050 /* sig is array of bytes containing the signature sigLen is the length of sig byte array @@ -633,6 +639,7 @@ static int ed25519_verify_msg_final_with_sha(const byte* sig, word32 sigLen, return ret; } +#endif /* WOLFSSL_SE050 */ #ifdef WOLFSSL_ED25519_STREAMING_VERIFY @@ -670,6 +677,13 @@ int wc_ed25519_verify_msg_ex(const byte* sig, word32 sigLen, const byte* msg, byte type, const byte* context, byte contextLen) { int ret; +#ifdef WOLFSSL_SE050 + (void)type; + (void)context; + (void)contextLen; + (void)ed25519Ctx; + ret = se050_ed25519_verify_msg(sig, sigLen, msg, msgLen, key, res); +#else #ifdef WOLFSSL_ED25519_PERSISTENT_SHA wc_Sha512 *sha; #else @@ -709,7 +723,7 @@ int wc_ed25519_verify_msg_ex(const byte* sig, word32 sigLen, const byte* msg, #ifndef WOLFSSL_ED25519_PERSISTENT_SHA ed25519_hash_free(key, sha); #endif - +#endif /* WOLFSSL_SE050 */ return ret; } @@ -813,6 +827,10 @@ int wc_ed25519_init_ex(ed25519_key* key, void* heap, int devId) fe_init(); #endif +#ifdef WOLFSSL_SE050 + se050_ed25519_create_key(key); +#endif + #ifdef WOLFSSL_ED25519_PERSISTENT_SHA return ed25519_hash_init(key, &key->sha); #else /* !WOLFSSL_ED25519_PERSISTENT_SHA */ @@ -835,6 +853,10 @@ void wc_ed25519_free(ed25519_key* key) ed25519_hash_free(key, &key->sha); #endif +#ifdef WOLFSSL_SE050 + se050_ed25519_free_key(key); +#endif + ForceZero(key, sizeof(ed25519_key)); } diff --git a/wolfcrypt/src/include.am b/wolfcrypt/src/include.am index 868fdadfe..c08529519 100644 --- a/wolfcrypt/src/include.am +++ b/wolfcrypt/src/include.am @@ -68,6 +68,8 @@ EXTRA_DIST += wolfcrypt/src/port/ti/ti-aes.c \ wolfcrypt/src/port/arm/armv8-32-sha512-asm.c \ wolfcrypt/src/port/nxp/ksdk_port.c \ wolfcrypt/src/port/nxp/dcp_port.c \ + wolfcrypt/src/port/nxp/se050_port.c \ + wolfcrypt/src/port/nxp/README.md \ wolfcrypt/src/port/atmel/README.md \ wolfcrypt/src/port/xilinx/xil-sha3.c \ wolfcrypt/src/port/xilinx/xil-aesgcm.c \ @@ -174,3 +176,7 @@ src_libwolfssl_la_SOURCES += wolfcrypt/src/port/caam/wolfcaam_qnx.c src_libwolfssl_la_SOURCES += wolfcrypt/src/port/caam/wolfcaam_ecdsa.c src_libwolfssl_la_SOURCES += wolfcrypt/src/port/caam/wolfcaam_cmac.c endif + +if BUILD_SE050 +src_libwolfssl_la_SOURCES += wolfcrypt/src/port/nxp/se050_port.c +endif diff --git a/wolfcrypt/src/port/nxp/README.md b/wolfcrypt/src/port/nxp/README.md new file mode 100644 index 000000000..ba47856ce --- /dev/null +++ b/wolfcrypt/src/port/nxp/README.md @@ -0,0 +1,114 @@ +# NXP Ports + +Support for the NXP DCP, KSDK and SE050 hardware acceleration boards. + +## NXP SE050 + +Support for the SE050 on-board crypto hardware acceleration for symmetric AES, SHA1/SHA256/SHA384/SHA512, ECC (including ed25519) and RNG. + +## SE050 Acceleration + +For details about SE050 HW acceleration, see [NXP's SE050 page](https://www.nxp.com/products/security-and-authentication/authentication/edgelock-se050-plug-trust-secure-element-family-enhanced-iot-security-with-maximum-flexibility:SE050). + +## Building simw-top + +The code required to communicate with the SE050 is the `EdgeLock SE05x Plug & Trust Middleware (03.03.00)`, which can be found here [link](https://www.nxp.com/products/security-and-authentication/authentication/edgelock-se050-plug-trust-secure-element-family-enhanced-iot-security-with-maximum-flexibility:SE050?tab=Design_Tools_Tab) (An NXP account is required to download). + +Follow the build instruction in AN12570 (EdgeLockTM SE05x Quick start guide with Raspberry Pi) [here](https://www.nxp.com/docs/en/application-note/AN12570.pdf). + +In summary here are the steps for building: + +``` +# from simw-top directory +mkdir build +cd build +ccmake .. +# Change: +# `Host OS` to `Raspbian` +# `Host Crypto` to `None` +# `SMCOM` to `T1oI2C` +c # to configure +q +make +``` + +## Building wolfSSL + +To enable support run: + +``sh +./configure --with-se050=PATH +make +`` + +Where `PATH` is the directory location of `simw-top`. +Example: `./configure --enable-debug --disable-shared --with-se050=/home/pi/simw-top CFLAGS="-DWOLFSSL_SE050_INIT"` + +## Building Examples + +Confirm that you are able to run the examples from the directory: + +``sh +/simw-top_build/raspbian_native_se050_t1oi2c/bin/ +`` + +Modify one of those examples in order to tie into wolfSSL. The `./se05x_Minimal` is the easiest one to modify. + +Open the `simw-top/demos/se05x/se05x_Minimal` directory and edit `se05x_Minimal.c`. Add these headers to source file: + +``c +#include +#include +#include +`` + +If you would like to run our wolfcrypt test or benchmark tool, add: `#include "test.h"` or `#include benchmark.h`. + +Below is the code that was replaced in `ex_sss_entry()` to run the wolfcrypt test: + +``c +sss_status_t status = kStatus_SSS_Success; +int ret; + +sss_session_t *pSession2 = (sss_session_t *)&pCtx->session; +sss_key_store_t *pHostSession = (sss_key_store_t *)&pCtx->host_ks; + +LOG_I("running setconfig"); +ret = wc_se050_set_config(pSession2, pHostSession); +if (ret != 0) { + return kStatus_SSS_Fail; +} +LOG_I("ran setconfig correctly"); +wolfcrypt_test(NULL); + +LOG_I("ran wolfcrypt test"); +return status; +`` + +Note: `wolfcrypt_test(NULL);` can be replaced with `benchmark_test();` + +The two variables used in `wc_se050_set_config` are session and key store variables that are required to reference parts of the hardware. + +The Makefile needs to be edited. At the top of the Makefile, the base wolfssl directory needs to be added to `INCLUDE_FLAGS`. + +Next, Inside `CFLAGS`, the `se05x_Minimal` directory needs to be added so that test.c and benchmark.c are included. + +Finally, underneath 'all', test.c, test.h, benchmark.c and benchmark.h need to be added, along with `-L[wolfssl directory] -lwolfssl` at the end of the line. + +### Wolfcrypt Test + +To run the wolfcrypt test, two files, `test.h` and `test.c` need to be added to the `./se05x_Minimal` directory. These files can be found inside of `/wolfcrypt/test`. +Make sure `NO_MAIN_DRIVER` is defined to avoid `int main()` conflicts. Either in the Makefile or modify test.h to define it. + +You should be able to run `wolfcrypt_test()` now. + +### wolfCrypt Benchmark + +To run the benchmark, both `benchmark.c` and `benchmark.h` need to be copied from wolfcrypt/benchmark to the `./se05x_Minimal` directory. +In addition, the entire `./certs` directory will need to copied into the directory. +Make sure `NO_MAIN_DRIVER` is defined to avoid `int main()` conflicts. Either in the Makefile or modify test.h to define it. +Now you can run `benchmark_test()`. + +## Support + +For questions please email support@wolfssl.com diff --git a/wolfcrypt/src/port/nxp/se050_port.c b/wolfcrypt/src/port/nxp/se050_port.c new file mode 100644 index 000000000..92b42dd16 --- /dev/null +++ b/wolfcrypt/src/port/nxp/se050_port.c @@ -0,0 +1,1029 @@ +/* se050_port.c + * + * Copyright (C) 2006-2021 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 + +#include + +#ifdef WOLFSSL_SE050 + +#include +#include +#include +#include +#include +#include + +#include + +#ifdef WOLFSSL_SE050_INIT + #ifndef SE050_DEFAULT_PORT + #define SE050_DEFAULT_PORT "/dev/i2c-1" + #endif + + #include "ex_sss_boot.h" +#endif + +#ifdef WOLFSSL_SP_MATH + struct sp_int; + #define MATH_INT_T struct sp_int +#elif defined(USE_FAST_MATH) + struct fp_int; + #define MATH_INT_T struct fp_int +#else + struct mp_int; + #define MATH_INT_T struct mp_int +#endif +struct ecc_key; +#include +#include + +/* AES 55 = keyStoreId - Implementation specific ID */ +/* ECC SIGN 56 = keyStoreId - Implementation specific ID */ +/* ECC VERIFY 57 = keyStoreId - Implementation specific ID */ +/* ED25519 58 = keyStoreId - Implementation specific ID */ + +/* Global variables */ +static sss_session_t *cfg_se050_i2c_pi; +static sss_key_store_t *hostKeyStore; +static sss_key_store_t *keyStore; + +int wc_se050_set_config(sss_session_t *pSession, sss_key_store_t *pHostKeyStore, + sss_key_store_t *pKeyStore) +{ + WOLFSSL_MSG("Setting SE050 session configuration"); + + cfg_se050_i2c_pi = pSession; + hostKeyStore = pHostKeyStore; + keyStore = pKeyStore; + + return 0; +} + +#ifdef WOLFSSL_SE050_INIT +int wc_se050_init(const char* portName) +{ + int ret; + sss_status_t status; + static ex_sss_boot_ctx_t pCtx; + + if (portName == NULL) { + portName = SE050_DEFAULT_PORT; + } + + status = ex_sss_boot_open(&pCtx, portName); + if (status == kStatus_SSS_Success) { + ret = wc_se050_set_config(&pCtx.session, + #if SSS_HAVE_HOSTCRYPTO_ANY + &pCtx.host_ks, + #else + NULL, + #endif + &pCtx.ks); + } + else { + ret = WC_HW_E; + } + return ret; +} +#endif + +int se050_allocate_key(int keyType) +{ + int keyId = 0; + static int keyId_allocator = 100; + switch (keyType) { + case SE050_AES_KEY: + keyId = SE050_KEYID_AES; + break; + case SE050_ECC_SIGN: + keyId = SE050_KEYID_ECC_SIGN; + break; + case SE050_ECC_VERIFY: + keyId = SE050_KEYID_ECC_VERIFY; + break; + case SE050_ED25519: + keyId = SE050_KEYID_ED25519; + break; + case SE050_KEYID_ANY: + keyId = keyId_allocator++; + break; + } + return keyId; +} + +#ifndef WC_NO_RNG +int se050_get_random_number(uint32_t count, uint8_t* rand_out) +{ + sss_status_t status; + sss_rng_context_t rng; + int ret = 0; + + if (cfg_se050_i2c_pi == NULL) { + return WC_HW_E; + } + + if (wolfSSL_CryptHwMutexLock() != 0) { + return BAD_MUTEX_E; + } + status = sss_rng_context_init(&rng, cfg_se050_i2c_pi); + + if (status == kStatus_SSS_Success) + status = sss_rng_get_random(&rng, rand_out, count); + + if (status == kStatus_SSS_Success) + status = sss_rng_context_free(&rng); + + if (status != kStatus_SSS_Success) { + ret = RNG_FAILURE_E; + } + wolfSSL_CryptHwMutexUnLock(); + + return ret; +} +#endif /* !WC_NO_RNG */ + +/* Used for sha/sha224/sha384/sha512 */ +int se050_hash_init(SE050_HASH_Context* se050Ctx, void* heap) +{ + se050Ctx->heap = heap; + se050Ctx->len = 0; + se050Ctx->used = 0; + se050Ctx->msg = NULL; + return 0; +} + +int se050_hash_update(SE050_HASH_Context* se050Ctx, const byte* data, word32 len) +{ + if (se050Ctx == NULL || (len > 0 && data == NULL)) { + return BAD_FUNC_ARG; + } + + if (se050Ctx->len < se050Ctx->used + len) { + if (se050Ctx->msg == NULL) { + se050Ctx->msg = (byte*)XMALLOC(se050Ctx->used + len, + se050Ctx->heap, DYNAMIC_TYPE_TMP_BUFFER); + } + else { + se050Ctx->msg = (byte*)XREALLOC(se050Ctx->msg, se050Ctx->used + len, + se050Ctx->heap, DYNAMIC_TYPE_TMP_BUFFER); + } + if (se050Ctx->msg == NULL) { + return MEMORY_E; + } + se050Ctx->len = se050Ctx->used + len; + } + + XMEMCPY(se050Ctx->msg + se050Ctx->used, data , len); + se050Ctx->used += len; + + return 0; +} + +int se050_hash_final(SE050_HASH_Context* se050Ctx, byte* hash, size_t digestLen, + sss_algorithm_t algo) +{ + sss_status_t status; + sss_digest_t digest_ctx; + const byte* data = se050Ctx->msg; + int size = (se050Ctx->len) / SSS_BLOCK_SIZE; + int leftover = (se050Ctx->len) % SSS_BLOCK_SIZE; + const byte* blocks = data; + + if (cfg_se050_i2c_pi == NULL) { + return WC_HW_E; + } + + if (wolfSSL_CryptHwMutexLock() != 0) { + return BAD_MUTEX_E; + } + + status = sss_digest_context_init(&digest_ctx, cfg_se050_i2c_pi, algo, + kMode_SSS_Digest); + if (status == kStatus_SSS_Success) { + status = sss_digest_init(&digest_ctx); + } + if (status == kStatus_SSS_Success) { + /* used to send chunks of size 512 */ + while (status == kStatus_SSS_Success && size--) { + status = sss_digest_update(&digest_ctx, blocks, SSS_BLOCK_SIZE); + blocks += SSS_BLOCK_SIZE; + } + if (status == kStatus_SSS_Success && leftover) { + status = sss_digest_update(&digest_ctx, blocks, leftover); + } + if (status == kStatus_SSS_Success) { + status = sss_digest_finish(&digest_ctx, hash, &digestLen); + } + sss_digest_context_free(&digest_ctx); + } + + wolfSSL_CryptHwMutexUnLock(); + + return 0; +} + +void se050_hash_free(SE050_HASH_Context* se050Ctx) +{ + (void)se050Ctx; +} + +#ifndef NO_AES +int se050_aes_set_key(Aes* aes, const byte* key, word32 len, + const byte* iv, int dir) +{ + sss_status_t status; + sss_object_t newKey; + sss_key_store_t host_keystore; + int keyId = se050_allocate_key(SE050_AES_KEY); + int ret = BAD_MUTEX_E; + + if (cfg_se050_i2c_pi == NULL) { + return WC_HW_E; + } + + (void)dir; + (void)iv; + + aes->rounds = len/4 + 6; + aes->keyId = keyId; + + if (wolfSSL_CryptHwMutexLock() != 0) { + return BAD_MUTEX_E; + } + + status = sss_key_store_context_init(&host_keystore, cfg_se050_i2c_pi); + + if (status == kStatus_SSS_Success) { + status = sss_key_store_allocate(&host_keystore, 55); + } + + if (status == kStatus_SSS_Success) { + status = sss_key_object_init(&newKey, &host_keystore); + } + + /* aes_test runs perfectly with kKeyObject_Mode_Persistent, + * but might have caused previous board to have no free key slots */ + if (status == kStatus_SSS_Success) { + status = sss_key_object_allocate_handle(&newKey, keyId, + kSSS_KeyPart_Default, kSSS_CipherType_AES, len, + kKeyObject_Mode_Transient); + } + + if (status == kStatus_SSS_Success) { + status = sss_key_store_set_key(&host_keystore, &newKey, key, len, + len * 8, NULL, 0); + } + + wolfSSL_CryptHwMutexUnLock(); + + if (status != kStatus_SSS_Success) + ret = WC_HW_E; + return ret; +} + + +int se050_aes_crypt(Aes* aes, const byte* in, byte* out, word32 sz, int dir, + sss_algorithm_t algorithm) +{ + sss_status_t status; + sss_object_t keyObject; + sss_mode_t mode; + sss_key_store_t host_keystore; + int ret = BAD_MUTEX_E; + + if (cfg_se050_i2c_pi == NULL) { + return WC_HW_E; + } + + XMEMSET(&mode, 0, sizeof(mode)); + + if (dir == AES_DECRYPTION) + mode = kMode_SSS_Decrypt; + else if (dir == AES_ENCRYPTION) + mode = kMode_SSS_Encrypt; + + if (wolfSSL_CryptHwMutexLock() != 0) { + return BAD_MUTEX_E; + } + + status = sss_key_store_context_init(&host_keystore, cfg_se050_i2c_pi); + + if (status == kStatus_SSS_Success) { + status = sss_key_store_allocate(&host_keystore, 55); + } + + if (status == kStatus_SSS_Success) { + status = sss_key_object_init(&keyObject, &host_keystore); + } + + if (status == kStatus_SSS_Success) { + status = sss_key_object_get_handle(&keyObject, aes->keyId); + } + + /* The first call to this function needs an initialization call, + * subsequent calls just need to call update */ + if (aes->ctxInitDone == 0) { + aes->ctxInitDone = 1; + if (status == kStatus_SSS_Success) { + status = sss_symmetric_context_init(&aes->aes_ctx, + cfg_se050_i2c_pi, &keyObject, algorithm, mode); + } + + if (status == kStatus_SSS_Success) { + status = sss_cipher_init(&aes->aes_ctx, (uint8_t*)aes->reg, + sizeof(aes->reg)); + } + } + if (status == kStatus_SSS_Success) { + size_t outSz = (size_t)sz; + status = sss_cipher_update(&aes->aes_ctx, in, sz, out, &outSz); + } + + wolfSSL_CryptHwMutexUnLock(); + + if (status != kStatus_SSS_Success) + ret = WC_HW_E; + return ret; +} + +void se050_aes_free(Aes* aes) +{ + sss_status_t status; + sss_key_store_t host_keystore; + sss_object_t keyObject; + + if (cfg_se050_i2c_pi == NULL) { + return; + } + + /* sets back to zero to indicate that a free has been called */ + aes->ctxInitDone = 0; + + if (wolfSSL_CryptHwMutexLock() != 0) { + return; + } + + status = sss_key_store_context_init(&host_keystore, cfg_se050_i2c_pi); + + if (status == kStatus_SSS_Success) { + status = sss_key_store_allocate(&host_keystore, 55); + } + + if (status == kStatus_SSS_Success) { + status = sss_key_object_init(&keyObject, &host_keystore); + } + + if (status == kStatus_SSS_Success) { + status = sss_key_object_get_handle(&keyObject, aes->keyId); + } + sss_key_object_free(&keyObject); + + sss_symmetric_context_free(&aes->aes_ctx); + + wolfSSL_CryptHwMutexUnLock(); +} + +#endif /* !NO_AES */ + +#ifdef HAVE_ECC +int se050_ecc_sign_hash_ex(const byte* in, word32 inLen, byte* out, + word32 *outLen, struct ecc_key* key) +{ + sss_status_t status; + sss_asymmetric_t ctx_asymm; + sss_key_store_t host_keystore; + sss_object_t newKey; + sss_algorithm_t algorithm = kAlgorithm_None; + int keyId = se050_allocate_key(SE050_ECC_SIGN); + int keysize = (word32)key->dp->size; + int ret = BAD_MUTEX_E; + + if (cfg_se050_i2c_pi == NULL) { + return WC_HW_E; + } + + /* truncate if digest is larger than 64 */ + if (inLen > 64) + inLen = 64; + + if (inLen == 20) + algorithm = kAlgorithm_SSS_SHA1; + else if (inLen == 28) + algorithm = kAlgorithm_SSS_SHA224; + else if (inLen == 32) + algorithm = kAlgorithm_SSS_SHA256; + else if (inLen == 48) + algorithm = kAlgorithm_SSS_SHA384; + else if (inLen == 64) + algorithm = kAlgorithm_SSS_SHA512; + + if (wolfSSL_CryptHwMutexLock() != 0) { + return BAD_MUTEX_E; + } + + status = sss_key_store_context_init(&host_keystore, cfg_se050_i2c_pi); + + if (status == kStatus_SSS_Success) { + status = sss_key_store_allocate(&host_keystore, 70); + } + + if (status == kStatus_SSS_Success) { + status = sss_key_object_init(&newKey, &host_keystore); + } + + + if (status == kStatus_SSS_Success) { + status = sss_key_object_allocate_handle(&newKey, keyId, + kSSS_KeyPart_Pair, kSSS_CipherType_EC_NIST_P, keysize, + kKeyObject_Mode_Transient); + } + + if (status == kStatus_SSS_Success) { + status = sss_key_store_generate_key(&host_keystore, &newKey, + keysize * 8, NULL); + } + + if (status == kStatus_SSS_Success) { + status = sss_asymmetric_context_init(&ctx_asymm, cfg_se050_i2c_pi, + &newKey, algorithm, kMode_SSS_Sign); + } + + if (status == kStatus_SSS_Success) { + size_t outLenSz = (size_t)*outLen; + status = sss_asymmetric_sign_digest(&ctx_asymm, (uint8_t *)in, inLen, + out, &outLenSz); + *outLen = (word32)outLenSz; + } + sss_asymmetric_context_free(&ctx_asymm); + + wolfSSL_CryptHwMutexUnLock(); + + if (status == kStatus_SSS_Success) { + key->keyId = keyId; + ret = 0; + } + else { + ret = WC_HW_E; + } + + return ret; +} + +int se050_ecc_verify_hash_ex(const byte* hash, word32 hashLen, byte* signature, + word32 signatureLen, struct ecc_key* key, int* res) +{ + sss_status_t status; + sss_asymmetric_t ctx_asymm; + sss_object_t newKey; + sss_key_store_t host_keystore; + sss_algorithm_t algorithm = kAlgorithm_None; + word32 derSz = 0; + int ret; + int keySize = (word32)key->dp->size; + + *res = 0; + + if (cfg_se050_i2c_pi == NULL) { + return WC_HW_E; + } + + if (hashLen > 64) + hashLen = 64; + + if (hashLen == 20) + algorithm = kAlgorithm_SSS_SHA1; + else if (hashLen == 28) + algorithm = kAlgorithm_SSS_SHA224; + else if (hashLen == 32) + algorithm = kAlgorithm_SSS_SHA256; + else if (hashLen == 48) + algorithm = kAlgorithm_SSS_SHA384; + else if (hashLen == 64) + algorithm = kAlgorithm_SSS_SHA512; + + if (wolfSSL_CryptHwMutexLock() != 0) { + return BAD_MUTEX_E; + } + + /* this is run when a key was not generated and was instead passed in */ + if (key->keyId == 0) { + int keyId = se050_allocate_key(SE050_ECC_VERIFY); + byte* derBuf = NULL; + + ret = wc_EccKeyToPKCS8(key, NULL, &derSz); + if (ret != LENGTH_ONLY_E) { + return ret; + } + + derBuf = (byte*)XMALLOC(derSz, NULL, DYNAMIC_TYPE_TMP_BUFFER); + if (derBuf == NULL) { + return MEMORY_E; + } + ret = wc_EccKeyToPKCS8(key, derBuf, &derSz); + if (ret <= 0) { + XFREE(derBuf, NULL, DYNAMIC_TYPE_TMP_BUFFER); + return ret; + } + + status = sss_key_store_context_init(&host_keystore, cfg_se050_i2c_pi); + if (status == kStatus_SSS_Success) { + status = sss_key_store_allocate(&host_keystore, 61); + } + if (status == kStatus_SSS_Success) { + status = sss_key_object_init(&newKey, &host_keystore); + } + if (status == kStatus_SSS_Success) { + status = sss_key_object_allocate_handle(&newKey, keyId, + kSSS_KeyPart_Pair, kSSS_CipherType_EC_NIST_P, derSz, + kKeyObject_Mode_Transient); + } + if (status == kStatus_SSS_Success) { + status = sss_key_store_set_key(&host_keystore, &newKey, derBuf, + derSz, keySize * 8, NULL, 0); + } + if (derBuf) { + XFREE(derBuf, NULL, DYNAMIC_TYPE_TMP_BUFFER); + } + + if (status == kStatus_SSS_Success) { + status = sss_asymmetric_context_init(&ctx_asymm, cfg_se050_i2c_pi, + &newKey, algorithm, kMode_SSS_Verify); + } + if (status == kStatus_SSS_Success) { + status = sss_asymmetric_verify_digest(&ctx_asymm, (uint8_t *)hash, + hashLen, signature, signatureLen); + } + + sss_asymmetric_context_free(&ctx_asymm); + + key->keyId = keyId; + } + /* this is run after a sign function has taken place */ + else { + status = sss_key_store_context_init(&host_keystore, cfg_se050_i2c_pi); + + if (status == kStatus_SSS_Success) { + status = sss_key_store_allocate(&host_keystore, 60); + } + if (status == kStatus_SSS_Success) { + status = sss_key_object_init(&newKey, &host_keystore); + } + if (status == kStatus_SSS_Success) { + status = sss_key_object_get_handle(&newKey, key->keyId); + } + if (status == kStatus_SSS_Success) { + status = sss_asymmetric_context_init(&ctx_asymm, cfg_se050_i2c_pi, + &newKey, algorithm, kMode_SSS_Verify); + } + if (status == kStatus_SSS_Success) { + status = sss_asymmetric_verify_digest(&ctx_asymm, (uint8_t *)hash, + hashLen, signature, signatureLen); + } + + sss_asymmetric_context_free(&ctx_asymm); + } + wolfSSL_CryptHwMutexUnLock(); + + if (status == kStatus_SSS_Success) { + *res = 1; + ret = 0; + } + else { + ret = WC_HW_E; + } + + return 0; +} + + +int se050_ecc_free_key(struct ecc_key* key) +{ + sss_status_t status = kStatus_SSS_Success; + sss_object_t keyObject; + int ret = WC_HW_E; + sss_key_store_t host_keystore; + + if (cfg_se050_i2c_pi == NULL) { + return WC_HW_E; + } + + if (key->keyId <= 0) { + return BAD_FUNC_ARG; + } + + if (wolfSSL_CryptHwMutexLock() != 0) { + return BAD_MUTEX_E; + } + + status = sss_key_store_context_init(&host_keystore, cfg_se050_i2c_pi); + + if (status == kStatus_SSS_Success) { + status = sss_key_store_allocate(&host_keystore, 60); + } + if (status == kStatus_SSS_Success) { + status = sss_key_object_init(&keyObject, &host_keystore); + } + if (status == kStatus_SSS_Success) { + status = sss_key_object_get_handle(&keyObject, key->keyId); + } + if (status == kStatus_SSS_Success) { + sss_key_object_free(&keyObject); + } + wolfSSL_CryptHwMutexUnLock(); + + if (status != kStatus_SSS_Success) { + ret = WC_CLEANUP_E; + } + + return ret; +} +int se050_ecc_create_key(struct ecc_key* key, int curve_id, int keySize) +{ + sss_status_t status = kStatus_SSS_Success; + sss_object_t keyPair; + sss_key_store_t host_keystore; + int keyId = se050_allocate_key(SE050_KEYID_ANY); + uint8_t keyPairExport[MAX_ECC_BYTES]; + size_t keyPairExportLen = sizeof(keyPairExport); + size_t keyPairExportBitLen = sizeof(keyPairExport) * 8; + int ret; + + if (cfg_se050_i2c_pi == NULL) { + return WC_HW_E; + } + + + (void)curve_id; + + if (wolfSSL_CryptHwMutexLock() != 0) { + return BAD_MUTEX_E; + } + + status = sss_key_store_context_init(&host_keystore, cfg_se050_i2c_pi); + if (status == kStatus_SSS_Success) { + status = sss_key_store_allocate(&host_keystore, 60); + } + if (status == kStatus_SSS_Success) { + status = sss_key_object_init(&keyPair, &host_keystore); + } + if (status == kStatus_SSS_Success) { + status = sss_key_object_allocate_handle(&keyPair, keyId, + kSSS_KeyPart_Pair, kSSS_CipherType_EC_NIST_P, 256, + kKeyObject_Mode_None); + } + if (status == kStatus_SSS_Success) { + status = sss_key_store_generate_key(&host_keystore, &keyPair, + 256, NULL); + } + if (status == kStatus_SSS_Success) { + status = sss_key_store_get_key(&host_keystore, &keyPair, + keyPairExport, &keyPairExportLen, &keyPairExportBitLen); + } + + wolfSSL_CryptHwMutexUnLock(); + + if (status == kStatus_SSS_Success) { + mp_read_unsigned_bin(key->pubkey.x, keyPairExport, keySize); + mp_read_unsigned_bin(key->pubkey.y, keyPairExport + keySize, keySize); + key->keyId = keyId; + ret = 0; + } + else { + ret = WC_HW_E; + } + + return ret; +} + + +int se050_ecc_shared_secret(ecc_key* private_key, ecc_key* public_key, + byte* out, word32* outlen) +{ + sss_status_t status = kStatus_SSS_Success; + sss_key_store_t host_keystore; + sss_key_store_t host_keystore_2; + sss_object_t ref_private_key; + sss_object_t ref_public_key; + sss_object_t deriveKey; + sss_derive_key_t ctx_derive_key; + int keyId; + int keySize = (word32)public_key->dp->size; + size_t ecdhKeyLen = keySize; + size_t ecdhKeyBitLen = keySize; + int ret = WC_HW_E; + + if (cfg_se050_i2c_pi == NULL) { + return WC_HW_E; + } + + if (private_key->keyId <= 0 || public_key->keyId <= 0) { + return BAD_FUNC_ARG; + } + + if (wolfSSL_CryptHwMutexLock() != 0) { + return BAD_MUTEX_E; + } + + status = sss_key_store_context_init(&host_keystore, cfg_se050_i2c_pi); + if (status == kStatus_SSS_Success) { + status = sss_key_store_allocate(&host_keystore, 60); + } + + if (status == kStatus_SSS_Success) { + status = sss_key_object_init(&ref_public_key, &host_keystore); + } + + if (status == kStatus_SSS_Success) { + status = sss_key_object_get_handle(&ref_public_key, public_key->keyId); + } + + if (status == kStatus_SSS_Success) { + status = sss_key_store_context_init(&host_keystore_2, cfg_se050_i2c_pi); + } + + if (status == kStatus_SSS_Success) { + status = sss_key_store_allocate(&host_keystore_2, 60); + } + + if (status == kStatus_SSS_Success) { + status = sss_key_object_init(&ref_private_key, &host_keystore_2); + } + + if (status == kStatus_SSS_Success) { + status = sss_key_object_get_handle(&ref_private_key, private_key->keyId); + } + + if (status == kStatus_SSS_Success) { + status = sss_key_object_init(&deriveKey, hostKeyStore); + } + + if (status == kStatus_SSS_Success) { + keyId = se050_allocate_key(SE050_KEYID_ANY); + + status = sss_key_object_allocate_handle(&deriveKey, + keyId, + kSSS_KeyPart_Default, + kSSS_CipherType_AES, + ecdhKeyLen, + kKeyObject_Mode_Transient); + } + + if (status == kStatus_SSS_Success) { + status = sss_derive_key_context_init(&ctx_derive_key, cfg_se050_i2c_pi, + &ref_private_key, kAlgorithm_SSS_ECDH, + kMode_SSS_ComputeSharedSecret); + } + + if (status == kStatus_SSS_Success) { + status = sss_derive_key_dh(&ctx_derive_key, &ref_public_key, &deriveKey); + } + + if (status == kStatus_SSS_Success) { + size_t outlenSz = (size_t)*outlen; + status = sss_key_store_get_key(hostKeyStore, &deriveKey, out, &outlenSz, + &ecdhKeyBitLen); + *outlen = (word32)outlenSz; + } + if (ctx_derive_key.session != NULL) + sss_derive_key_context_free(&ctx_derive_key); + if (deriveKey.keyStore != NULL) + sss_key_object_free(&deriveKey); + + if (status == kStatus_SSS_Success) + ret = 0; + else + ret = WC_HW_E; + + wolfSSL_CryptHwMutexUnLock(); + + return ret; +} +#endif /* HAVE_ECC */ + +#ifdef HAVE_ED25519 + +int se050_ed25519_create_key(ed25519_key* key) +{ + sss_status_t status; + sss_key_store_t host_keystore; + sss_object_t newKey; + int keysize = ED25519_KEY_SIZE; + int keyId; + int ret = 0; + + if (cfg_se050_i2c_pi == NULL) { + return WC_HW_E; + } + + if (wolfSSL_CryptHwMutexLock() != 0) { + return BAD_MUTEX_E; + } + + status = sss_key_store_context_init(&host_keystore, cfg_se050_i2c_pi); + if (status == kStatus_SSS_Success) { + status = sss_key_store_allocate(&host_keystore, 55); + } + + if (status == kStatus_SSS_Success) { + status = sss_key_object_init(&newKey, &host_keystore); + } + + if (status == kStatus_SSS_Success) { + keyId = se050_allocate_key(SE050_ED25519); + status = sss_key_object_allocate_handle(&newKey, keyId, + kSSS_KeyPart_Pair, kSSS_CipherType_EC_TWISTED_ED, keysize, + kKeyObject_Mode_Transient); + } + + if (status == kStatus_SSS_Success) { + status = sss_key_store_generate_key(&host_keystore, &newKey, + keysize * 8, NULL); + } + + if (status == kStatus_SSS_Success) { + key->keyId = keyId; + ret = 0; + } + else { + sss_key_object_free(&newKey); + ret = WC_HW_E; + } + + wolfSSL_CryptHwMutexUnLock(); + + return ret; +} + +void se050_ed25519_free_key(ed25519_key* key) +{ + sss_status_t status; + sss_object_t newKey; + sss_key_store_t host_keystore; + + if (cfg_se050_i2c_pi == NULL) { + return; + } + + if (wolfSSL_CryptHwMutexLock() != 0) { + return /*BAD_MUTEX_E*/; + } + + status = sss_key_store_context_init(&host_keystore, cfg_se050_i2c_pi); + + if (status == kStatus_SSS_Success) { + status = sss_key_store_allocate(&host_keystore, 55); + } + if (status == kStatus_SSS_Success) { + status = sss_key_object_init(&newKey, &host_keystore); + } + if (status == kStatus_SSS_Success) { + status = sss_key_object_get_handle(&newKey, key->keyId); + } + if (status == kStatus_SSS_Success) { + sss_key_object_free(&newKey); + } + wolfSSL_CryptHwMutexUnLock(); +} + +int se050_ed25519_sign_msg(const byte* in, word32 inLen, byte* out, + word32 *outLen, ed25519_key* key) +{ + sss_status_t status = kStatus_SSS_Success; + sss_asymmetric_t ctx_asymm; + sss_key_store_t host_keystore; + sss_object_t newKey; + int ret = 0; + + inLen = 64; + *outLen = 64; + + if (cfg_se050_i2c_pi == NULL) { + return WC_HW_E; + } + + if (wolfSSL_CryptHwMutexLock() != 0) { + return BAD_MUTEX_E; + } + + status = sss_key_store_context_init(&host_keystore, cfg_se050_i2c_pi); + + if (status == kStatus_SSS_Success) { + status = sss_key_store_allocate(&host_keystore, 55); + } + + if (status == kStatus_SSS_Success) { + status = sss_key_object_init(&newKey, &host_keystore); + } + + if (status == kStatus_SSS_Success) { + status = sss_key_object_get_handle(&newKey, key->keyId); + } + + if (status == kStatus_SSS_Success) { + status = sss_asymmetric_context_init(&ctx_asymm, cfg_se050_i2c_pi, + &newKey, kAlgorithm_SSS_SHA512, kMode_SSS_Sign); + } + + if (status == kStatus_SSS_Success) { + size_t outlenSz = (size_t)*outLen; + status = sss_se05x_asymmetric_sign((sss_se05x_asymmetric_t *)&ctx_asymm, + (uint8_t *)in, inLen, out, &outlenSz); + *outLen = (word32)outlenSz; + } + + sss_asymmetric_context_free(&ctx_asymm); + + if (status != kStatus_SSS_Success) { + sss_key_object_free(&newKey); + ret = WC_HW_E; + } + + wolfSSL_CryptHwMutexUnLock(); + + return ret; +} + + +int se050_ed25519_verify_msg(const byte* signature, word32 signatureLen, + const byte* msg, word32 msgLen, struct ed25519_key* key, int* res) +{ + sss_status_t status = kStatus_SSS_Success; + sss_asymmetric_t ctx_asymm; + sss_object_t newKey; + sss_key_store_t host_keystore; + int ret = 0; + + if (cfg_se050_i2c_pi == NULL) { + return WC_HW_E; + } + + msgLen = 64; + + if (wolfSSL_CryptHwMutexLock() != 0) { + return BAD_MUTEX_E; + } + + status = sss_key_store_context_init(&host_keystore, cfg_se050_i2c_pi); + + if (status == kStatus_SSS_Success) { + status = sss_key_store_allocate(&host_keystore, 61); + } + + if (status == kStatus_SSS_Success) { + status = sss_key_object_init(&newKey, &host_keystore); + } + + if (status == kStatus_SSS_Success) { + status = sss_key_object_get_handle(&newKey, key->keyId); + } + + if (status == kStatus_SSS_Success) { + status = sss_asymmetric_context_init(&ctx_asymm, cfg_se050_i2c_pi, + &newKey, kAlgorithm_SSS_SHA512, kMode_SSS_Verify); + } + + if (status == kStatus_SSS_Success) { + status = sss_se05x_asymmetric_verify( + (sss_se05x_asymmetric_t*)&ctx_asymm, (uint8_t*)msg, msgLen, + (uint8_t*)signature, (size_t)signatureLen); + } + + sss_asymmetric_context_free(&ctx_asymm); + + wolfSSL_CryptHwMutexUnLock(); + + if (status == kStatus_SSS_Success) { + *res = 1; + } + else { + ret = WC_HW_E; + } + return ret; +} + +#endif /* HAVE_ED25519 */ + +#endif /* WOLFSSL_SE050 */ diff --git a/wolfcrypt/src/random.c b/wolfcrypt/src/random.c index a97c29508..722e49a1d 100644 --- a/wolfcrypt/src/random.c +++ b/wolfcrypt/src/random.c @@ -2574,6 +2574,24 @@ int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz) } return 0; } +#elif defined(WOLFSSL_SE050) + #include + + int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz){ + int ret = 0; + + (void)os; + + if (output == NULL) { + return BUFFER_E; + } + ret = wolfSSL_CryptHwMutexLock(); + if (ret == 0) { + ret = se050_get_random_number(sz, output); + wolfSSL_CryptHwMutexUnLock(); + } + return ret; + } #elif defined(DOLPHIN_EMULATOR) diff --git a/wolfcrypt/src/sha.c b/wolfcrypt/src/sha.c index af68da78b..3952200c1 100644 --- a/wolfcrypt/src/sha.c +++ b/wolfcrypt/src/sha.c @@ -336,6 +336,41 @@ #elif defined(WOLFSSL_SILABS_SE_ACCEL) /* implemented in wolfcrypt/src/port/silabs/silabs_hash.c */ +#elif defined(WOLFSSL_SE050) + + #include + int wc_InitSha_ex(wc_Sha* sha, void* heap, int devId) + { + if (sha == NULL) { + return BAD_FUNC_ARG; + } + (void)devId; + + return se050_hash_init(&sha->se050Ctx, heap); + } + + int wc_ShaUpdate(wc_Sha* sha, const byte* data, word32 len) + { + return se050_hash_update(&sha->se050Ctx, data, len); + + } + + int wc_ShaFinal(wc_Sha* sha, byte* hash) + { + int ret = 0; + ret = se050_hash_final(&sha->se050Ctx, hash, WC_SHA_DIGEST_SIZE, + kAlgorithm_SSS_SHA1); + (void)wc_InitSha(sha); + return ret; + } + int wc_ShaFinalRaw(wc_Sha* sha, byte* hash) + { + int ret = 0; + ret = se050_hash_final(&sha->se050Ctx, hash, WC_SHA_DIGEST_SIZE, + kAlgorithm_SSS_SHA1); + (void)wc_InitSha(sha); + return ret; + } #else /* Software implementation */ @@ -811,6 +846,9 @@ void wc_ShaFree(wc_Sha* sha) #ifdef WOLFSSL_PIC32MZ_HASH wc_ShaPic32Free(sha); #endif +#ifdef WOLFSSL_SE050 + se050_hash_free(&sha->se050Ctx); +#endif #if (defined(WOLFSSL_RENESAS_TSIP_CRYPT) && \ !defined(NO_WOLFSSL_RENESAS_TSIP_CRYPT_HASH)) if (sha->msg != NULL) { diff --git a/wolfcrypt/src/sha256.c b/wolfcrypt/src/sha256.c index 9c342dcd7..21b956d55 100644 --- a/wolfcrypt/src/sha256.c +++ b/wolfcrypt/src/sha256.c @@ -184,7 +184,7 @@ where 0 <= L < 2^64. (!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_SILABS_SE_ACCEL) && \ - !defined(WOLFSSL_KCAPI_HASH) + !defined(WOLFSSL_KCAPI_HASH) && !defined(WOLFSSL_SE050) static int InitSha256(wc_Sha256* sha256) @@ -597,6 +597,41 @@ static int InitSha256(wc_Sha256* sha256) !defined(WOLFSSL_QNX_CAAM) /* functions defined in wolfcrypt/src/port/caam/caam_sha256.c */ +#elif defined(WOLFSSL_SE050) + + #include + int wc_InitSha256_ex(wc_Sha256* sha256, void* heap, int devId) + { + if (sha256 == NULL) { + return BAD_FUNC_ARG; + } + (void)devId; + + return se050_hash_init(&sha256->se050Ctx, heap); + } + + int wc_Sha256Update(wc_Sha256* sha256, const byte* data, word32 len) + { + return se050_hash_update(&sha256->se050Ctx, data, len); + } + + int wc_Sha256Final(wc_Sha256* sha256, byte* hash) + { + int ret = 0; + ret = se050_hash_final(&sha256->se050Ctx, hash, WC_SHA256_DIGEST_SIZE, + kAlgorithm_SSS_SHA256); + (void)wc_InitSha256(sha256); + return ret; + } + int wc_Sha256FinalRaw(wc_Sha256* sha256, byte* hash) + { + int ret = 0; + ret = se050_hash_final(&sha256->se050Ctx, hash, WC_SHA256_DIGEST_SIZE, + kAlgorithm_SSS_SHA256); + (void)wc_InitSha256(sha256); + return ret; + } + #elif defined(WOLFSSL_AFALG_HASH) /* implemented in wolfcrypt/src/port/af_alg/afalg_hash.c */ @@ -1388,6 +1423,32 @@ static int InitSha256(wc_Sha256* sha256) return ret; } +#elif defined(WOLFSSL_SE050) + + #include + int wc_InitSha224_ex(wc_Sha224* sha224, void* heap, int devId) + { + if (sha224 == NULL) { + return BAD_FUNC_ARG; + } + (void)devId; + + return se050_hash_init(&sha224->se050Ctx, heap); + } + + int wc_Sha224Update(wc_Sha224* sha224, const byte* data, word32 len) + { + return se050_hash_update(&sha224->se050Ctx, data, len); + } + + int wc_Sha224Final(wc_Sha224* sha224, byte* hash) + { + int ret = 0; + ret = se050_hash_final(&sha224->se050Ctx, hash, WC_SHA224_DIGEST_SIZE, + kAlgorithm_SSS_SHA224); + (void)wc_InitSha224(sha224); + return ret; + } #elif defined(WOLFSSL_IMX6_CAAM) && !defined(NO_IMX6_CAAM_HASH) && \ !defined(WOLFSSL_QNX_CAAM) diff --git a/wolfcrypt/src/sha512.c b/wolfcrypt/src/sha512.c index 4b8d1d1cd..256aae06e 100644 --- a/wolfcrypt/src/sha512.c +++ b/wolfcrypt/src/sha512.c @@ -49,6 +49,10 @@ #include #endif +#ifdef WOLFSSL_SE050 + #include +#endif + /* deprecated USE_SLOW_SHA2 (replaced with USE_SLOW_SHA512) */ #if defined(USE_SLOW_SHA2) && !defined(USE_SLOW_SHA512) #define USE_SLOW_SHA512 @@ -199,6 +203,60 @@ #elif defined(WOLFSSL_KCAPI_HASH) /* functions defined in wolfcrypt/src/port/kcapi/kcapi_hash.c */ +#elif defined(WOLFSSL_SE050) + int wc_InitSha512(wc_Sha512* sha512) + { + if (sha512 == NULL) + return BAD_FUNC_ARG; + return se050_hash_init(&sha512->se050Ctx, NULL); + } + int wc_InitSha512_ex(wc_Sha512* sha512, void* heap, int devId) + { + if (sha512 == NULL) { + return BAD_FUNC_ARG; + } + (void)devId; + return se050_hash_init(&sha512->se050Ctx, heap); + } + int wc_Sha512Update(wc_Sha512* sha512, const byte* data, word32 len) + { + return se050_hash_update(&sha512->se050Ctx, data, len); + } + int wc_Sha512Final(wc_Sha512* sha512, byte* hash) + { + int ret = 0; + int devId = INVALID_DEVID; + if (sha512 == NULL) { + return BAD_FUNC_ARG; + } + #ifdef WOLF_CRYPTO_CB + devId = sha512->devId; + #endif + ret = se050_hash_final(&sha512->se050Ctx, hash, WC_SHA512_DIGEST_SIZE, + kAlgorithm_SSS_SHA512); + (void)wc_InitSha512_ex(sha512, sha512->heap, devId); + return ret; + } + int wc_Sha512FinalRaw(wc_Sha512* sha512, byte* hash) + { + int ret = 0; + int devId = INVALID_DEVID; + if (sha512 == NULL) { + return BAD_FUNC_ARG; + } + #ifdef WOLF_CRYPTO_CB + devId = sha512->devId; + #endif + ret = se050_hash_final(&sha512->se050Ctx, hash, WC_SHA512_DIGEST_SIZE, + kAlgorithm_SSS_SHA512); + (void)wc_InitSha512_ex(sha512, sha512->heap, devId); + return ret; + } + void wc_Sha512Free(wc_Sha512* sha512) + { + (void)sha512; + } + #else #ifdef WOLFSSL_SHA512 @@ -900,8 +958,10 @@ int wc_Sha512Update(wc_Sha512* sha512, const byte* data, word32 len) #endif /* WOLFSSL_IMX6_CAAM || WOLFSSL_SILABS_SHA384 */ + #if defined(WOLFSSL_KCAPI_HASH) /* functions defined in wolfcrypt/src/port/kcapi/kcapi_hash.c */ +#elif defined(WOLFSSL_SE050) #else @@ -1012,6 +1072,7 @@ static WC_INLINE int Sha512Final(wc_Sha512* sha512) #if defined(WOLFSSL_KCAPI_HASH) /* functions defined in wolfcrypt/src/port/kcapi/kcapi_hash.c */ +#elif defined(WOLFSSL_SE050) #else @@ -1083,6 +1144,7 @@ int wc_Sha512Final(wc_Sha512* sha512, byte* hash) #endif /* WOLFSSL_KCAPI_HASH */ +#ifndef WOLFSSL_SE050 int wc_InitSha512(wc_Sha512* sha512) { return wc_InitSha512_ex(sha512, NULL, INVALID_DEVID); @@ -1164,6 +1226,8 @@ int wc_Sha512Transform(wc_Sha512* sha, const unsigned char* data) } #endif /* OPENSSL_EXTRA */ #endif /* WOLFSSL_SHA512 */ +#endif /* !WOLFSSL_SE050 */ + /* -------------------------------------------------------------------------- */ /* SHA384 */ @@ -1173,6 +1237,36 @@ int wc_Sha512Transform(wc_Sha512* sha, const unsigned char* data) #if defined(WOLFSSL_IMX6_CAAM) && !defined(NO_IMX6_CAAM_HASH) && \ !defined(WOLFSSL_QNX_CAAM) /* functions defined in wolfcrypt/src/port/caam/caam_sha.c */ +#elif defined(WOLFSSL_SE050) + int wc_InitSha384_ex(wc_Sha384* sha384, void* heap, int devId) + { + if (sha384 == NULL) { + return BAD_FUNC_ARG; + } + (void)devId; + return se050_hash_init(&sha384->se050Ctx, heap); + } + int wc_Sha384Update(wc_Sha384* sha384, const byte* data, word32 len) + { + return se050_hash_update(&sha384->se050Ctx, data, len); + + } + int wc_Sha384Final(wc_Sha384* sha384, byte* hash) + { + int ret = 0; + ret = se050_hash_final(&sha384->se050Ctx, hash, WC_SHA384_DIGEST_SIZE, + kAlgorithm_SSS_SHA384); + (void)wc_InitSha384(sha384); + return ret; + } + int wc_Sha384FinalRaw(wc_Sha384* sha384, byte* hash) + { + int ret = 0; + ret = se050_hash_final(&sha384->se050Ctx, hash, WC_SHA384_DIGEST_SIZE, + kAlgorithm_SSS_SHA384); + (void)wc_InitSha384(sha384); + return ret; + } #elif defined(WOLFSSL_SILABS_SHA512) /* functions defined in wolfcrypt/src/port/silabs/silabs_hash.c */ @@ -1478,8 +1572,10 @@ int wc_Sha512_224Update(wc_Sha512* sha, const byte* data, word32 len) { return wc_Sha512Update(sha, data, len); } + #if defined(WOLFSSL_KCAPI_HASH) /* functions defined in wolfcrypt/src/port/kcapi/kcapi_hash.c */ +#elif defined(WOLFSSL_SE050) #else int wc_Sha512_224FinalRaw(wc_Sha512* sha, byte* hash) @@ -1498,6 +1594,8 @@ void wc_Sha512_224Free(wc_Sha512* sha) } #if defined(WOLFSSL_KCAPI_HASH) /* functions defined in wolfcrypt/src/port/kcapi/kcapi_hash.c */ +#elif defined(WOLFSSL_SE050) + #else int wc_Sha512_224GetHash(wc_Sha512* sha512, byte* hash) @@ -1541,6 +1639,7 @@ int wc_Sha512_256Update(wc_Sha512* sha, const byte* data, word32 len) } #if defined(WOLFSSL_KCAPI_HASH) /* functions defined in wolfcrypt/src/port/kcapi/kcapi_hash.c */ +#elif defined(WOLFSSL_SE050) #else int wc_Sha512_256FinalRaw(wc_Sha512* sha, byte* hash) diff --git a/wolfcrypt/src/wc_port.c b/wolfcrypt/src/wc_port.c index 23fb898d8..01570b0ed 100644 --- a/wolfcrypt/src/wc_port.c +++ b/wolfcrypt/src/wc_port.c @@ -91,6 +91,10 @@ #include #endif +#if defined(WOLFSSL_SE050) && defined(WOLFSSL_SE050_INIT) +#include +#endif + #ifdef WOLFSSL_SCE #include "hal_data.h" #endif @@ -230,6 +234,10 @@ int wolfCrypt_Init(void) ret = sl_se_init(); #endif + #if defined(WOLFSSL_SE050) && defined(WOLFSSL_SE050_INIT) + ret = wc_se050_init(NULL); + #endif + #ifdef WOLFSSL_ARMASM WOLFSSL_MSG("Using ARM hardware acceleration"); #endif diff --git a/wolfssl/wolfcrypt/aes.h b/wolfssl/wolfcrypt/aes.h index 775c2fef3..f7619c1e9 100644 --- a/wolfssl/wolfcrypt/aes.h +++ b/wolfssl/wolfcrypt/aes.h @@ -70,6 +70,10 @@ block cipher mechanism that uses n-bit binary string parameter key with 128-bits #include "xsecure_aes.h" #endif +#ifdef WOLFSSL_SE050 + #include +#endif + #if defined(WOLFSSL_AFALG) || defined(WOLFSSL_AFALG_XILINX_AES) /* included for struct msghdr */ #include @@ -178,6 +182,12 @@ struct Aes { word32 aadLen; /* additional authenticated data len */ #endif +#ifdef WOLFSSL_SE050 + sss_symmetric_t aes_ctx; /* used as the function context */ + int ctxInitDone; + int keyId; +#endif + #ifdef GCM_TABLE /* key-based fast multiplication table. */ ALIGN16 byte M0[256][AES_BLOCK_SIZE]; diff --git a/wolfssl/wolfcrypt/ecc.h b/wolfssl/wolfcrypt/ecc.h index da9dd8d70..76bbb6567 100644 --- a/wolfssl/wolfcrypt/ecc.h +++ b/wolfssl/wolfcrypt/ecc.h @@ -66,6 +66,10 @@ #include #endif +#ifdef WOLFSSL_SE050 + #include +#endif + #ifdef WOLFSSL_HAVE_SP_ECC #include #endif @@ -168,8 +172,12 @@ enum { CRYPTOCELL_KEY_SIZE = ECC_MAXSIZE, #endif ECC_MAX_CRYPTO_HW_SIZE = CRYPTOCELL_KEY_SIZE, +#elif defined(WOLFSSL_SE050) + ECC_MAX_CRYPTO_HW_SIZE = 32, + ECC_MAX_CRYPTO_HW_PUBKEY_SIZE = 64, #endif + /* point compression type */ ECC_POINT_COMP_EVEN = 0x02, ECC_POINT_COMP_ODD = 0x03, @@ -436,6 +444,9 @@ struct ecc_key { word32 securePubKey; /* address of public key in secure memory */ int partNum; /* partition number*/ #endif +#ifdef WOLFSSL_SE050 + int keyId; +#endif #if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A) int slot; /* Key Slot Number (-1 unknown) */ byte pubkey_raw[ECC_MAX_CRYPTO_HW_PUBKEY_SIZE]; diff --git a/wolfssl/wolfcrypt/ed25519.h b/wolfssl/wolfcrypt/ed25519.h index e1b090f79..a4608d11f 100644 --- a/wolfssl/wolfcrypt/ed25519.h +++ b/wolfssl/wolfcrypt/ed25519.h @@ -85,6 +85,9 @@ struct ed25519_key { /* uncompressed point coordinates */ byte pointX[ED25519_KEY_SIZE]; /* recovered X coordinate */ byte pointY[ED25519_KEY_SIZE]; /* Y coordinate is the public key with The most significant bit of the final octet always zero. */ +#endif +#ifdef WOLFSSL_SE050 + int keyId; #endif word16 pubKeySet:1; #ifdef WOLFSSL_ASYNC_CRYPT diff --git a/wolfssl/wolfcrypt/include.am b/wolfssl/wolfcrypt/include.am index b68d0a471..8195584b5 100644 --- a/wolfssl/wolfcrypt/include.am +++ b/wolfssl/wolfcrypt/include.am @@ -78,6 +78,7 @@ noinst_HEADERS+= \ wolfssl/wolfcrypt/port/nrf51.h \ wolfssl/wolfcrypt/port/nxp/ksdk_port.h \ wolfssl/wolfcrypt/port/nxp/dcp_port.h \ + wolfssl/wolfcrypt/port/nxp/se050_port.h \ wolfssl/wolfcrypt/port/xilinx/xil-sha3.h \ wolfssl/wolfcrypt/port/caam/caam_driver.h \ wolfssl/wolfcrypt/port/caam/caam_error.h \ diff --git a/wolfssl/wolfcrypt/port/nxp/se050_port.h b/wolfssl/wolfcrypt/port/nxp/se050_port.h new file mode 100644 index 000000000..bd3759236 --- /dev/null +++ b/wolfssl/wolfcrypt/port/nxp/se050_port.h @@ -0,0 +1,151 @@ +/* se050_port.h + * + * Copyright (C) 2006-2021 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 _SE050_PORT_H_ +#define _SE050_PORT_H_ + +#include +#include + +#ifdef __GNUC__ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wundef" +#pragma GCC diagnostic ignored "-Wredundant-decls" +#endif + +#include "fsl_sss_se05x_types.h" +#include "fsl_sss_se05x_apis.h" + +#if (SSS_HAVE_SSS > 1) +#include "fsl_sss_api.h" +#endif + +#ifdef WOLFSSL_SE050 + /* NXP SE050 - Disable SHA512 224/256 support */ + #ifndef WOLFSSL_NOSHA512_224 + #define WOLFSSL_NOSHA512_224 + #endif + #ifndef WOLFSSL_NOSHA512_256 + #define WOLFSSL_NOSHA512_256 + #endif +#endif + +#ifdef __GNUC__ +#pragma GCC diagnostic pop +#endif + + +/* Default key ID's */ +#ifndef SE050_KEYID_AES +#define SE050_KEYID_AES 55 +#endif +#ifndef SE050_KEYID_ECC_SIGN +#define SE050_KEYID_ECC_SIGN 56 +#endif +#ifndef SE050_KEYID_ECC_VERIFY +#define SE050_KEYID_ECC_VERIFY 57 +#endif +#ifndef SE050_KEYID_ED25519 +#define SE050_KEYID_ED25519 58 +#endif + + +enum { + SSS_BLOCK_SIZE = 512 +}; + +enum SE050KeyType { + SE050_KEYID_ANY, + SE050_AES_KEY, + SE050_ECC_SIGN, + SE050_ECC_VERIFY, + SE050_ED25519, +}; + + +typedef struct { + void* heap; + byte* msg; + word32 used; + word32 len; +} SE050_HASH_Context; + +/* Public Functions */ +WOLFSSL_API int wc_se050_set_config(sss_session_t *pSession, + sss_key_store_t *pHostKeyStore, sss_key_store_t *pKeyStore); +#ifdef WOLFSSL_SE050_INIT +WOLFSSL_API int wc_se050_init(const char* portName); +#endif + +/* Private Functions */ +WOLFSSL_LOCAL int se050_allocate_key(int keyType); +WOLFSSL_LOCAL int se050_get_random_number(uint32_t count, uint8_t* rand_out); + +WOLFSSL_LOCAL int se050_hash_init(SE050_HASH_Context* se050Ctx, void* heap); +WOLFSSL_LOCAL int se050_hash_update(SE050_HASH_Context* se050Ctx, + const byte* data, word32 len); +WOLFSSL_LOCAL int se050_hash_final(SE050_HASH_Context* se050Ctx, byte* hash, + size_t digestLen, word32 algo); +WOLFSSL_LOCAL void se050_hash_free(SE050_HASH_Context* se050Ctx); + +struct Aes; +WOLFSSL_LOCAL int se050_aes_set_key(struct Aes* aes, const byte* key, + word32 len, const byte* iv, int dir); +WOLFSSL_LOCAL int se050_aes_crypt(struct Aes* aes, const byte* in, byte* out, + word32 sz, int dir, sss_algorithm_t algorithm); +WOLFSSL_LOCAL void se050_aes_free(struct Aes* aes); + + +struct ecc_key; +struct WC_RNG; +#ifdef WOLFSSL_SP_MATH + struct sp_int; + #define MATH_INT_T struct sp_int +#elif defined(USE_FAST_MATH) + struct fp_int; + #define MATH_INT_T struct fp_int +#else + struct mp_int; + #define MATH_INT_T struct mp_int +#endif + +WOLFSSL_LOCAL int se050_ecc_sign_hash_ex(const byte* in, word32 inLen, + byte* out, word32 *outLen, struct ecc_key* key); + +WOLFSSL_LOCAL int se050_ecc_verify_hash_ex(const byte* hash, word32 hashlen, + byte* signature, word32 signatureLen, struct ecc_key* key, int* res); + +WOLFSSL_LOCAL int se050_ecc_create_key(struct ecc_key* key, int curve_id, int keySize); +WOLFSSL_LOCAL int se050_ecc_shared_secret(struct ecc_key* private_key, + struct ecc_key* public_key, byte* out, word32* outlen); +WOLFSSL_LOCAL int se050_ecc_free_key(struct ecc_key* key); + +struct ed25519_key; +WOLFSSL_LOCAL int se050_ed25519_create_key(struct ed25519_key* key); +WOLFSSL_LOCAL void se050_ed25519_free_key(struct ed25519_key* key); +WOLFSSL_LOCAL int se050_ed25519_sign_msg(const byte* in, word32 inLen, + byte* out, word32 *outLen, struct ed25519_key* key); + +WOLFSSL_LOCAL int se050_ed25519_verify_msg(const byte* signature, + word32 signatureLen, const byte* msg, word32 msgLen, + struct ed25519_key* key, int* res); + +#endif /* _SE050_PORT_H_ */ diff --git a/wolfssl/wolfcrypt/sha.h b/wolfssl/wolfcrypt/sha.h index cc55fa00d..8fca499fb 100644 --- a/wolfssl/wolfcrypt/sha.h +++ b/wolfssl/wolfcrypt/sha.h @@ -110,10 +110,16 @@ enum { #include "wolfssl/wolfcrypt/port/Renesas/renesas-tsip-crypt.h" #else +#if defined(WOLFSSL_SE050) + #include "wolfssl/wolfcrypt/port/nxp/se050_port.h" +#endif + /* Sha digest */ struct wc_Sha { #ifdef FREESCALE_LTC_SHA ltc_hash_ctx_t ctx; +#elif defined(WOLFSSL_SE050) + SE050_HASH_Context se050Ctx; #elif defined(STM32_HASH) STM32_HASH_Context stmCtx; #elif defined(WOLFSSL_SILABS_SE_ACCEL) diff --git a/wolfssl/wolfcrypt/sha256.h b/wolfssl/wolfcrypt/sha256.h index 706123716..5dfb3603a 100644 --- a/wolfssl/wolfcrypt/sha256.h +++ b/wolfssl/wolfcrypt/sha256.h @@ -144,10 +144,16 @@ enum { #include "wolfssl/wolfcrypt/port/Renesas/renesas-tsip-crypt.h" #else +#if defined(WOLFSSL_SE050) + #include "wolfssl/wolfcrypt/port/nxp/se050_port.h" +#endif + /* wc_Sha256 digest */ struct wc_Sha256 { #ifdef FREESCALE_LTC_SHA ltc_hash_ctx_t ctx; +#elif defined(WOLFSSL_SE050) + SE050_HASH_Context se050Ctx; #elif defined(STM32_HASH_SHA2) STM32_HASH_Context stmCtx; #elif defined(WOLFSSL_SILABS_SE_ACCEL) diff --git a/wolfssl/wolfcrypt/sha512.h b/wolfssl/wolfcrypt/sha512.h index a1bb131e2..f821d94ef 100644 --- a/wolfssl/wolfcrypt/sha512.h +++ b/wolfssl/wolfcrypt/sha512.h @@ -138,6 +138,9 @@ enum { #if defined(WOLFSSL_IMX6_CAAM) && !defined(WOLFSSL_QNX_CAAM) #include "wolfssl/wolfcrypt/port/caam/wolfcaam_sha.h" #else +#if defined(WOLFSSL_SE050) + #include "wolfssl/wolfcrypt/port/nxp/se050_port.h" +#endif /* wc_Sha512 digest */ struct wc_Sha512 { #ifdef WOLFSSL_PSOC6_CRYPTO @@ -170,6 +173,9 @@ struct wc_Sha512 { #ifdef WOLFSSL_KCAPI_HASH wolfssl_KCAPI_Hash kcapi; #endif +#if defined(WOLFSSL_SE050) + SE050_HASH_Context se050Ctx; +#endif #ifdef WOLF_CRYPTO_CB int devId; void* devCtx; /* generic crypto callback context */