From 3f76a76c46e6a1c4150fe954c7485d2177ba0dd9 Mon Sep 17 00:00:00 2001 From: Ethan Date: Fri, 20 Aug 2021 12:59:41 -0600 Subject: [PATCH] SE050 port with support for RNG, SHA, AES, ECC (sign/verify/shared secret) and ED25519 --- configure.ac | 44 ++ wolfcrypt/src/aes.c | 68 +- wolfcrypt/src/ecc.c | 41 +- wolfcrypt/src/ed25519.c | 29 +- wolfcrypt/src/port/nxp/se050_port.c | 927 ++++++++++++++++++++++++ wolfcrypt/src/random.c | 18 + wolfcrypt/src/sha.c | 39 + wolfcrypt/src/sha256.c | 63 +- wolfcrypt/src/sha512.c | 75 ++ wolfssl/wolfcrypt/aes.h | 10 + wolfssl/wolfcrypt/ecc.h | 11 + wolfssl/wolfcrypt/ed25519.h | 3 + wolfssl/wolfcrypt/port/nxp/README.md | 68 ++ wolfssl/wolfcrypt/port/nxp/se050_port.h | 98 +++ wolfssl/wolfcrypt/sha.h | 6 + wolfssl/wolfcrypt/sha256.h | 6 + wolfssl/wolfcrypt/sha512.h | 6 + 17 files changed, 1505 insertions(+), 7 deletions(-) create mode 100644 wolfcrypt/src/port/nxp/se050_port.c create mode 100644 wolfssl/wolfcrypt/port/nxp/README.md create mode 100644 wolfssl/wolfcrypt/port/nxp/se050_port.h diff --git a/configure.ac b/configure.ac index 72b1cb500..c1048664d 100644 --- a/configure.ac +++ b/configure.ac @@ -1336,6 +1336,50 @@ AC_ARG_WITH([cryptoauthlib], ] ) +# NXP SE050 +#current configure options line: "./configure --with-se050=/home/pi/Downloads/new_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]) + CPPFLAGS="$CPPFLAGS -DWOLFSSL_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/simw-top_build/raspbian_native_se050_t1oi2c/sss/" + CPPFLAGS="$CPPFLAGS -I$trylibse050dir/simw-top/sss/inc -I$trylibse050dir/simw-top/sss/port/default \ + -I$trylibse050dir/simw-top/hostlib/hostLib/inc/ -I$trylibse050dir/simw-top/hostlib/hostLib/libCommon/infra " + + + 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 + AM_LDFLAGS="$AM_LDFLAGS -L$trylibse050dir/simw-top_build/raspbian_native_se050_t1oi2c/sss/" + AM_CFLAGS="$AM_CFLAGS -I$trylibse050dir/simw-top/sss/inc/ \ + -DWOLFSSL_AES_DIRECT" + + AC_MSG_RESULT([yes]) + else + AC_MSG_RESULT([yes]) + fi + + ENABLED_SE050="yes" + AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_SE050" + ] +) # sniffer doesn't work in maxstrength mode if test "$ENABLED_SNIFFER" = "yes" && test "$ENABLED_MAXSTRENGTH" = "yes" diff --git a/wolfcrypt/src/aes.c b/wolfcrypt/src/aes.c index 16354ee50..8cd2a7b83 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,27 @@ 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 +2599,32 @@ 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 = 0; + + 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 +3879,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 +10392,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..cdff3b34f 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 */ @@ -4698,6 +4700,10 @@ 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) + key->keyId = se050_allocate_key(); + err = se050_ecc_create_key(key, key->keyId, keysize); + key->type = ECC_PRIVATEKEY; #elif defined(WOLFSSL_CRYPTOCELL) pDomain = CRYS_ECPKI_GetEcDomain(cc310_mapCurve(key->dp->id)); @@ -5098,7 +5104,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 +5190,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 +5370,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 +6294,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 +6970,8 @@ 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) + 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; @@ -7095,6 +7115,23 @@ 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 */ + + err = StoreECC_DSA_Sig(sigRS, &signatureLen, r, s); + if (err != 0) + return err; + + err = se050_ecc_verify_hash_ex(hash, hashlen, sigRS, signatureLen, key, res); + 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..f8f726031 100644 --- a/wolfcrypt/src/ed25519.c +++ b/wolfcrypt/src/ed25519.c @@ -262,6 +262,12 @@ 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) { +#ifdef WOLFSSL_SE050 + (void)context; + (void)contextLen; + (void)type; + int 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}; @@ -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,14 @@ 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; + if (ed25519Ctx != NULL) + (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 +724,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 +828,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 +854,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/port/nxp/se050_port.c b/wolfcrypt/src/port/nxp/se050_port.c new file mode 100644 index 000000000..4384f3994 --- /dev/null +++ b/wolfcrypt/src/port/nxp/se050_port.c @@ -0,0 +1,927 @@ +/* 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 +#include +#include +#include +#include +#include + + +#if defined(WOLFSSL_SE050) + +#include +#include "fsl_sss_api.h" +#include "fsl_sss_se05x_types.h" + + +/* Global variables */ +static sss_session_t *cfg_se050_i2c_pi; +static sss_key_store_t *hostKeyStore; +static sss_key_store_t *keyStore; +int keyId_allocater = 100; + +int wolfcrypt_se050_SetConfig(sss_session_t *pSession, sss_key_store_t *pHostKeyStore, sss_key_store_t *pKeyStore) +{ + printf("Setting SE050 session configuration\n"); + + XMEMSET(&cfg_se050_i2c_pi, 0, sizeof(cfg_se050_i2c_pi)); + cfg_se050_i2c_pi = pSession; + + XMEMSET(&hostKeyStore, 0, sizeof(hostKeyStore)); + hostKeyStore = pHostKeyStore; + + XMEMSET(&keyStore, 0, sizeof(keyStore)); + keyStore = pKeyStore; + + return 0; +} + +int se050_allocate_key() +{ + return keyId_allocater++; +} + +#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 (wolfSSL_CryptHwMutexLock() == 0) { + 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); + if (se050Ctx->msg == NULL) { + return MEMORY_E; + } + } + else { + byte* pt = (byte*)XREALLOC(se050Ctx->msg, se050Ctx->used + len, se050Ctx->heap, + DYNAMIC_TYPE_TMP_BUFFER); + if (pt == NULL) { + return MEMORY_E; + } + se050Ctx->msg = pt; + } + 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; + // XMEMSET(&digest_ctx, 0, sizeof(digest_ctx)); + + const byte* data = se050Ctx->msg; + int size = (se050Ctx->len) / SSS_BLOCK_SIZE; + int leftover = (se050Ctx->len) % SSS_BLOCK_SIZE; + const byte* blocks; + blocks = data; + + + if (wolfSSL_CryptHwMutexLock() == 0) { + status = sss_digest_context_init(&digest_ctx, cfg_se050_i2c_pi, algo, kMode_SSS_Digest); + if(status != kStatus_SSS_Success){ + printf("error 1\n"); + return -1; + } + + status = sss_digest_init(&digest_ctx); + if(status != kStatus_SSS_Success){ + printf("error 2 - hash_final...\n"); + return -1; + } + /* used to send chunks of size 512 */ + while (size--) { + status = sss_digest_update(&digest_ctx, blocks, SSS_BLOCK_SIZE); + if(status != kStatus_SSS_Success){ + printf("error 3\n"); + return -1; + } + blocks += SSS_BLOCK_SIZE; + } + if (leftover) { + status = sss_digest_update(&digest_ctx, blocks, leftover); + if(status != kStatus_SSS_Success){ + printf("error 3\n"); + return -1; + } + } + + status = sss_digest_finish(&digest_ctx, hash, &digestLen); + if(status != kStatus_SSS_Success){ + printf("error 4\n"); + return -1; + } + 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) +{ + printf("\n\nrunning se050_set_key\n"); + (void)dir; + (void)iv; + sss_status_t status; + aes->rounds = len/4 + 6; + sss_object_t newKey; + sss_key_store_t host_keystore; + uint32_t keyId = se050_allocate_key(); + aes->keyId = keyId; + int ret = BAD_MUTEX_E; + + if (wolfSSL_CryptHwMutexLock() == 0) { + ret = 0; + 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); //kKeyObject_Mode_Persistent + } + + 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; + 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) { + ret = 0; + + 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) { + status = sss_cipher_update(&aes->aes_ctx, in, sz, out, &sz); + } + } + 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; + aes->ctxInitDone = 0; /* sets back to zero to indicate that a free has been called */ + + if (wolfSSL_CryptHwMutexLock() == 0) { + 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 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 + + +#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; + XMEMSET(&algorithm, 0, sizeof(algorithm)); + + uint32_t keyId = se050_allocate_key(); + int keysize = (word32)key->dp->size; + int ret = BAD_MUTEX_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) { + ret = 0; + 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) { + status = sss_asymmetric_sign_digest(&ctx_asymm, (uint8_t *)in, inLen, + out, outLen); + } + sss_asymmetric_context_free(&ctx_asymm); + + + } + wolfSSL_CryptHwMutexUnLock(); + + if (status != kStatus_SSS_Success) + ret = WC_HW_E; + + key->keyId = keyId; + + return ret; +} + +int se050_ecc_verify_hash_ex(const byte* hash, word32 hashLen, byte* signature, + word32 signatureLen, struct ecc_key* key, int* res) +{ + printf("runing verify!\n"); + + sss_status_t status; + sss_asymmetric_t ctx_asymm; + sss_object_t newKey; + sss_key_store_t host_keystore; + sss_algorithm_t algorithm; + + XMEMSET(&algorithm, 0, sizeof(algorithm)); + + word32 derSz = 0; + int ret = WC_HW_E; + byte* derBuf; + uint32_t keyId = rand(); + int keySize = (word32)key->dp->size; + *res = 0; + + 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; + + printf("KeyId 3 = %d\n", key->keyId); + + if (wolfSSL_CryptHwMutexLock() == 0) { + if (key->keyId == 0) { //this is run when a key was not generated and was instead passed in + + ret = wc_EccKeyToPKCS8(key, NULL, &derSz); + if (ret != -202){ + printf("first wc_EccKeyToPKCS8 failed\n"); + return -1; + } + derBuf = (byte*)XMALLOC(derSz, NULL, DYNAMIC_TYPE_OPENSSL); + ret = wc_EccKeyToPKCS8(key, derBuf, &derSz); + if (ret <= 0){ + printf("second wc_EccKeyToPKCS8 failed, ret = %d\n", ret); + return -1; + } + + 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 (status == kStatus_SSS_Success) { + status = sss_asymmetric_context_init(&ctx_asymm, cfg_se050_i2c_pi, + &newKey, algorithm, kMode_SSS_Verify); + } + + printf("ran through inital key setup !\n"); + + + if (status == kStatus_SSS_Success) { + status = sss_asymmetric_verify_digest(&ctx_asymm, (uint8_t *)hash, + hashLen, signature, signatureLen); + } + + sss_asymmetric_context_free(&ctx_asymm); + printf("sss_asymmetric_verify_digest with set key worked!\n\n\n"); + + } + else if (key->keyId != 0) { //this is run after a sign function has taken place + ret = 0; + + 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) + ret = WC_HW_E; + + printf("ran verify correctly!!\n\n\n"); + + + *res = 1; + 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; + + /* less tha 10,000 as one example from test.c tried to free a key that was not created on the SE050 */ + if(key->keyId != 0 && key->keyId < 10000) { + if (wolfSSL_CryptHwMutexLock() == 0) { + ret = 0; + + 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 keyId, int keySize) +{ + sss_status_t status = kStatus_SSS_Success; + sss_object_t keyPair; + sss_key_store_t host_keystore; + + uint8_t keyPairExport[128]; + size_t keyPairExportLen = sizeof(keyPairExport); + size_t keyPairExportBitLen = sizeof(keyPairExport) * 8; + int ret = WC_HW_E; + + + if (wolfSSL_CryptHwMutexLock() == 0) { + ret = 0; + + 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); //kKeyObject_Mode_Transient + } + + 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) + ret = WC_CLEANUP_E; + + mp_read_unsigned_bin(key->pubkey.x, keyPairExport, keySize); + mp_read_unsigned_bin(key->pubkey.y, keyPairExport + keySize, keySize); + + 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 = se050_allocate_key(); + int keySize = (word32)public_key->dp->size; + size_t ecdhKeyLen = keySize; + size_t ecdhKeyBitLen = keySize; + int ret = WC_HW_E; + + + if (public_key->keyId == 0) { + public_key->keyId = se050_allocate_key(); + se050_ecc_create_key(public_key, public_key->keyId, keySize); + + } + if (private_key->keyId == 0) { + private_key->keyId = se050_allocate_key(); + se050_ecc_create_key(private_key, private_key->keyId, keySize); + } + + if (wolfSSL_CryptHwMutexLock() == 0) { + ret = 0; + 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) { + status = sss_key_object_allocate_handle(&deriveKey, + keyId, + kSSS_KeyPart_Default, //try kSSS_KeyPart_Part, didn't have any noticable changes + kSSS_CipherType_AES, + ecdhKeyLen, + kKeyObject_Mode_Transient); //try kKeyObject_Mode_None + } + + 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) { + status = sss_key_store_get_key(hostKeyStore, &deriveKey, out, outlen, + &ecdhKeyBitLen); + } + 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 = WC_HW_E; + } + wolfSSL_CryptHwMutexUnLock(); + + return ret; +} +#endif /* HAVE_ECC */ + +#ifdef HAVE_ED25519 + + +int se050_ed25519_create_key(ed25519_key* key) +{ + printf("\n\nrunning se050_ed25519_create_key\n"); + sss_status_t status; + sss_key_store_t host_keystore; + sss_object_t newKey; + int keysize = ED25519_KEY_SIZE; + uint32_t keyId = se050_allocate_key(); + key->keyId = keyId; + int ret = 0; + + if (wolfSSL_CryptHwMutexLock() == 0) { + 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_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) { + sss_key_object_free(&newKey); + ret = WC_HW_E; + } + + } + wolfSSL_CryptHwMutexUnLock(); + + + printf("ran se050_ed25519_create_key\n\n\n"); + 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 (wolfSSL_CryptHwMutexLock() == 0) { + + 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) { + sss_key_object_free(&newKey); + } + } + wolfSSL_CryptHwMutexUnLock(); +} + + +int se050_ed25519_sign_msg(const byte* in, word32 inLen, byte* out, + word32 *outLen, ed25519_key* key) +{ + printf("\n\nhit se050_ed25519_sign_msg...\n"); + 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; + + /* used to fix edge case when ed25519_init is not called prior to signing */ + /* figure out if needed or not for -10801 */ + if (key->keyId > 10000 || key->keyId == 0) { + key->keyId = se050_allocate_key(); + ret = se050_ed25519_create_key(key); + if (ret != 0) { + printf("calling se050_ed25519_create_key failed..., ret = %d\n", ret); + } + + } + + if (wolfSSL_CryptHwMutexLock() == 0 && ret == 0) { + 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, kAlgorithm_SSS_SHA512, kMode_SSS_Sign); + } + + if (status == kStatus_SSS_Success) { + status = sss_se05x_asymmetric_sign((sss_se05x_asymmetric_t *)&ctx_asymm, + (uint8_t *)in, inLen, out, outLen); + } + + if(status != kStatus_SSS_Success){ + printf("status != kStatus_SSS_Success, status = %d\n", status); + sss_key_object_free(&newKey); + ret = WC_HW_E; + } + sss_asymmetric_context_free(&ctx_asymm); + } + 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) +{ + printf("runing se050_ed25519_verify_msg!\n"); + + 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; + msgLen = 64; + *res = 1; + + if (wolfSSL_CryptHwMutexLock() == 0) { + 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) { + ret = WC_HW_E; + *res = 0; + } + return ret; +} + +#endif /* HAVE_ED25519 */ + +#endif /* SE050 */ diff --git a/wolfcrypt/src/random.c b/wolfcrypt/src/random.c index a97c29508..41e0f682a 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..925519168 100644 --- a/wolfcrypt/src/sha.c +++ b/wolfcrypt/src/sha.c @@ -336,6 +336,42 @@ #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 +847,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..558325832 100644 --- a/wolfcrypt/src/sha512.c +++ b/wolfcrypt/src/sha512.c @@ -199,6 +199,49 @@ #elif defined(WOLFSSL_KCAPI_HASH) /* functions defined in wolfcrypt/src/port/kcapi/kcapi_hash.c */ +#elif defined(WOLFSSL_SE050) + //#include + int wc_InitSha512(wc_Sha512* sha512) + { + if (sha512 == NULL) + return BAD_FUNC_ARG; + //void* heap; + 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; + ret = se050_hash_final(&sha512->se050Ctx, hash, WC_SHA512_DIGEST_SIZE, + kAlgorithm_SSS_SHA512); + (void)wc_InitSha512_ex(sha512); + return ret; + } + int wc_Sha512FinalRaw(wc_Sha512* sha512, byte* hash) + { + int ret = 0; + ret = se050_hash_final(&sha512->se050Ctx, hash, WC_SHA512_DIGEST_SIZE, + kAlgorithm_SSS_SHA512); + (void)wc_InitSha512(sha512); + return ret; + } + void wc_Sha512Free(wc_Sha512* sha512) + { + (void)sha512; + } + #else #ifdef WOLFSSL_SHA512 @@ -1173,6 +1216,38 @@ 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) + #include + + 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 */ 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/port/nxp/README.md b/wolfssl/wolfcrypt/port/nxp/README.md new file mode 100644 index 000000000..1e1e37bf3 --- /dev/null +++ b/wolfssl/wolfcrypt/port/nxp/README.md @@ -0,0 +1,68 @@ + +# 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. **(discuss p-256 ECC)** + +## 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 + +To enable support run: +``` +./configure --with-se050=PATH +``` +Followed by: +``` +make && make install +``` +With PATH being the directory location of simw-top. + +The code required to communicate with the SE050 can be found at this NXP [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 instructions [here](https://www.nxp.com/docs/en/application-note/AN12570.pdf) to install and setup with a Raspberry Pi. +Confirm that you are able to run the examples from the +``` +/simw-top_build/raspbian_native_se050_t1oi2c/bin/ +``` +directory. Once that's done, it's time to 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: +``` +#include +#include +#include +``` +If you would like to run our wolfcrypt test or benchmark tool, add: +``#include "test.h"`` or ``#include benchmark.h``, respectively. Below is the code that was replaced in ``ex_sss_entry()`` that ran the wolfcrypt test: +``` + 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 = wolfcrypt_se050_SetConfig(pSession2, pHostSession); + if (ret != 0) { + return kStatus_SSS_Fail; + } + LOG_I("ran setconfig correctly"); + wolfcrypt_test(NULL); + + LOG_I("ran wolfcrypt test"); + return status; +``` + +``wolfcrypt_test(NULL);`` can be replaced with ``benchmark_test();`` +The two variables used in ``wolfcrypt_se050_SetConfig`` are session and key store variables that are required to reference parts of the hardware. + +Next, 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``. +Next, ``#define NO_MAIN_DRIVER`` needs to be added to test.h. +You should be able to run `wolfcrypt_test()` now. + +## 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. ``#define NO_MAIN_DRIVER`` will need to be added to `benchmark.h`. You should be able to run `benchmark_test() ` now. diff --git a/wolfssl/wolfcrypt/port/nxp/se050_port.h b/wolfssl/wolfcrypt/port/nxp/se050_port.h new file mode 100644 index 000000000..7db7884e3 --- /dev/null +++ b/wolfssl/wolfcrypt/port/nxp/se050_port.h @@ -0,0 +1,98 @@ +/* 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 "fsl_sss_api.h" + +enum { + SSS_BLOCK_SIZE = 512 +}; + +typedef struct { + void* heap; + byte* msg; + word32 used; + word32 len; +} SE050_HASH_Context; + + +WOLFSSL_API int wolfcrypt_se050_SetConfig(sss_session_t *pSession, sss_key_store_t *pHostKeyStore, sss_key_store_t *pKeyStore); + +int se050_allocate_key(void); + +int se050_get_random_number(uint32_t count, uint8_t* rand_out); + + + +int se050_hash_init(SE050_HASH_Context* se050Ctx, void* heap); +int se050_hash_update(SE050_HASH_Context* se050Ctx, const byte* data, word32 len); +int se050_hash_final(SE050_HASH_Context* se050Ctx, byte* hash, size_t digestLen, word32 algo); +void se050_hash_free(SE050_HASH_Context* se050Ctx); + + + +struct Aes; +int se050_aes_set_key(struct Aes* aes, const byte* key, word32 len, const byte* iv, int dir); +int se050_aes_crypt(struct Aes* aes, const byte* in, byte* out, word32 sz, int dir, sss_algorithm_t algorithm); +void se050_aes_free(struct Aes* aes); +//int se050_aes_ctr_crypt(struct Aes* aes, const byte* in, byte* out, word32 sz); + + + +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 +int se050_ecc_sign_hash_ex(const byte* in, word32 inLen, byte* out, + word32 *outLen, struct ecc_key* key); + +int se050_ecc_verify_hash_ex(const byte* hash, word32 hashlen, byte* signature, + word32 signatureLen, struct ecc_key* key, int* res); + +int se050_ecc_create_key(struct ecc_key* key, int keyId, int keySize); +int se050_ecc_shared_secret(struct ecc_key* private_key, struct ecc_key* public_key, byte* out, + word32* outlen); +int se050_ecc_free_key(struct ecc_key* key); + +struct ed25519_key; +//#include +int se050_ed25519_create_key(struct ed25519_key* key); +void se050_ed25519_free_key(struct ed25519_key* key); +int se050_ed25519_sign_msg(const byte* in, word32 inLen, byte* out, + word32 *outLen, struct ed25519_key* key); + +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 */