Browse Source

Merge pull request #5760 from cconlon/se050

NXP SE050: feature expansion and fixes
David Garske 1 year ago
parent
commit
9036c098b0

+ 6 - 4
configure.ac

@@ -1927,7 +1927,7 @@ AC_ARG_WITH([cryptoauthlib],
 ENABLED_SE050="no"
 trylibse050dir=""
 AC_ARG_WITH([se050],
-    [AS_HELP_STRING([--with-se050=PATH],[PATH to SE050 install (default /usr/local/lib/)])],
+    [AS_HELP_STRING([--with-se050=PATH],[PATH to SE050 install (default /usr/local)])],
     [
         AC_MSG_CHECKING([for SE050])
 
@@ -1939,9 +1939,11 @@ AC_ARG_WITH([se050],
                 trylibse050dir=$withval
             fi
             if test "x$withval" = "xyes" ; then
-                trylibse050dir="/usr/local/lib/"
+                trylibse050dir="/usr/local"
             fi
+            LDFLAGS="$LDFLAGS -L$trylibse050dir/lib"
             LDFLAGS="$LDFLAGS -L$trylibse050dir/build/sss"
+            CPPFLAGS="$CPPFLAGS -I$trylibse050dir/include/se05x"
             CPPFLAGS="$CPPFLAGS -I$trylibse050dir/build"
             CPPFLAGS="$CPPFLAGS -I$trylibse050dir/sss/inc"
             CPPFLAGS="$CPPFLAGS -I$trylibse050dir/sss/ex/inc"
@@ -1971,7 +1973,7 @@ AC_ARG_WITH([se050],
             fi
 
             # Requires AES direct
-            AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_AES_DIRECT"
+            AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_AES_DIRECT -DHAVE_AES_ECB"
 
             # Does not support SHA2-512 224/256
             AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_NOSHA512_224 -DWOLFSSL_NOSHA512_256"
@@ -7723,7 +7725,7 @@ AS_IF([test "x$ENABLED_STRONGSWAN" = "xyes"],
 
 AS_IF([test "x$ENABLED_OPENLDAP" = "xyes"], [AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_SIGNER_DER_CERT"])
 
-if test "$ENABLED_ED25519_STREAM" != "no"
+if test "$ENABLED_ED25519_STREAM" != "no" && test "$ENABLED_SE050" != "yes"
 then
     AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_ED25519_STREAMING_VERIFY"
     AM_CCASFLAGS="$AM_CCASFLAGS -DWOLFSSL_ED25519_STREAMING_VERIFY"

+ 44 - 66
wolfcrypt/src/aes.c

@@ -895,30 +895,6 @@ 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) && defined(WOLFSSL_SE050_CRYPT)
-    static WARN_UNUSED_RESULT 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 WARN_UNUSED_RESULT 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 WARN_UNUSED_RESULT int wc_AesEncrypt(
-        Aes* aes, const byte* inBlock, byte* outBlock)
-    {
-        return AES_ECB_encrypt(aes, inBlock, outBlock, AES_BLOCK_SIZE);
-    }
-    static WARN_UNUSED_RESULT 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"
 
@@ -1853,6 +1829,13 @@ static WARN_UNUSED_RESULT int wc_AesEncrypt(
     }
 #endif
 
+#if defined(WOLFSSL_SE050) && defined(WOLFSSL_SE050_CRYPT)
+    if (aes->useSWCrypt == 0) {
+        return se050_aes_crypt(aes, inBlock, outBlock, AES_BLOCK_SIZE,
+                               AES_ENCRYPTION, kAlgorithm_SSS_AES_ECB);
+    }
+#endif
+
     /*
      * map byte array block to cipher state
      * and add initial round key:
@@ -2185,6 +2168,12 @@ static WARN_UNUSED_RESULT int wc_AesDecrypt(
         return 0;
     }
 #endif
+#if defined(WOLFSSL_SE050) && defined(WOLFSSL_SE050_CRYPT)
+    if (aes->useSWCrypt == 0) {
+        return se050_aes_crypt(aes, inBlock, outBlock, AES_BLOCK_SIZE,
+                               AES_DECRYPTION, kAlgorithm_SSS_AES_ECB);
+    }
+#endif
 
     /*
      * map byte array block to cipher state
@@ -2644,35 +2633,6 @@ static WARN_UNUSED_RESULT int wc_AesDecrypt(
         return wc_AesSetKey(aes, userKey, keylen, iv, dir);
     }
 
-#elif defined(WOLFSSL_SE050) && defined(WOLFSSL_SE050_CRYPT)
-    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)
@@ -2964,6 +2924,18 @@ static WARN_UNUSED_RESULT int wc_AesDecrypt(
                                   ((psa_algorithm_t)0), dir);
 #endif
 
+#if defined(WOLFSSL_SE050) && defined(WOLFSSL_SE050_CRYPT)
+        /* wolfSSL HostCrypto in SE05x SDK can request to use SW crypto
+         * instead of SE05x crypto by setting useSWCrypt */
+        if (aes->useSWCrypt == 0) {
+            ret = se050_aes_set_key(aes, userKey, keylen, iv, dir);
+            if (ret == 0) {
+                ret = wc_AesSetIV(aes, iv);
+            }
+            return ret;
+        }
+#endif
+
         rk = aes->key;
         XMEMCPY(rk, userKey, keylen);
     #if defined(LITTLE_ENDIAN_ORDER) && !defined(WOLFSSL_PIC32MZ_CRYPT) && \
@@ -3973,18 +3945,6 @@ 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) && defined(WOLFSSL_SE050_CRYPT)
-    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 */
 
@@ -4051,6 +4011,14 @@ int wc_AesSetIV(Aes* aes, const byte* iv)
         }
     #endif /* WOLFSSL_ASYNC_CRYPT */
 
+    #if defined(WOLFSSL_SE050) && defined(WOLFSSL_SE050_CRYPT)
+        /* Implemented in wolfcrypt/src/port/nxp/se050_port.c */
+        if (aes->useSWCrypt == 0) {
+            return se050_aes_crypt(aes, in, out, sz, AES_ENCRYPTION,
+                                   kAlgorithm_SSS_AES_CBC);
+        }
+    #endif
+
     #ifdef WOLFSSL_AESNI
         if (haveAESNI) {
             #ifdef DEBUG_AESNI
@@ -4176,6 +4144,14 @@ int wc_AesSetIV(Aes* aes, const byte* iv)
         }
     #endif
 
+    #if defined(WOLFSSL_SE050) && defined(WOLFSSL_SE050_CRYPT)
+        /* Implemented in wolfcrypt/src/port/nxp/se050_port.c */
+        if (aes->useSWCrypt == 0) {
+            return se050_aes_crypt(aes, in, out, sz, AES_DECRYPTION,
+                                   kAlgorithm_SSS_AES_CBC);
+        }
+    #endif
+
     #ifdef WOLFSSL_AESNI
         if (haveAESNI) {
             #ifdef DEBUG_AESNI
@@ -10813,7 +10789,9 @@ void wc_AesFree(Aes* aes)
 #endif
 
 #if defined(WOLFSSL_SE050) && defined(WOLFSSL_SE050_CRYPT)
-    se050_aes_free(aes);
+    if (aes->useSWCrypt == 0) {
+        se050_aes_free(aes);
+    }
 #endif
 
 #if defined(WOLFSSL_HAVE_PSA) && !defined(WOLFSSL_PSA_NO_AES)

+ 3 - 2
wolfcrypt/src/asn.c

@@ -6307,7 +6307,7 @@ static int DecodeRsaPssParams(const byte* params, word32 sz,
 #ifndef HAVE_USER_RSA
 #if defined(WOLFSSL_ASN_TEMPLATE) || (!defined(NO_CERTS) && \
     (defined(WOLFSSL_KEY_GEN) || defined(OPENSSL_EXTRA) || \
-     defined(WOLFSSL_KCAPI_RSA)))
+     defined(WOLFSSL_KCAPI_RSA) || defined(WOLFSSL_SE050)))
 /* Byte offset of numbers in RSA key. */
 size_t rsaIntOffset[] = {
     OFFSETOF(RsaKey, n),
@@ -24223,7 +24223,8 @@ int wc_RsaKeyToPublicDer_ex(RsaKey* key, byte* output, word32 inLen,
             ((OPENSSL_EXTRA || WOLFSSL_KEY_GEN) && !HAVE_USER_RSA))) */
 
 #if (defined(WOLFSSL_KEY_GEN) || defined(OPENSSL_EXTRA) || \
-     defined(WOLFSSL_KCAPI_RSA)) && !defined(NO_RSA) && !defined(HAVE_USER_RSA)
+     defined(WOLFSSL_KCAPI_RSA) || defined(WOLFSSL_SE050)) && \
+     !defined(NO_RSA) && !defined(HAVE_USER_RSA)
 
 /* Encode private RSA key in DER format.
  *

+ 14 - 1
wolfcrypt/src/cmac.c

@@ -97,6 +97,9 @@ int wc_InitCmac_ex(Cmac* cmac, const byte* key, word32 keySz,
                 int type, void* unused, void* heap, int devId)
 {
     int ret;
+#if defined(WOLFSSL_SE050) && defined(WOLFSSL_SE050_CRYPT)
+    byte useSW = 0;
+#endif
 
     (void)unused;
     (void)heap;
@@ -105,6 +108,10 @@ int wc_InitCmac_ex(Cmac* cmac, const byte* key, word32 keySz,
         return BAD_FUNC_ARG;
     }
 
+#if defined(WOLFSSL_SE050) && defined(WOLFSSL_SE050_CRYPT)
+    /* save if we should use SW crypt, restore after memset */
+    useSW = cmac->useSWCrypt;
+#endif
     XMEMSET(cmac, 0, sizeof(Cmac));
 
 #ifdef WOLF_CRYPTO_CB
@@ -126,6 +133,13 @@ int wc_InitCmac_ex(Cmac* cmac, const byte* key, word32 keySz,
         return BAD_FUNC_ARG;
     }
 
+#if defined(WOLFSSL_SE050) && defined(WOLFSSL_SE050_CRYPT)
+    cmac->useSWCrypt = useSW;
+    if (cmac->useSWCrypt == 1) {
+        cmac->aes.useSWCrypt = 1;
+    }
+#endif
+
     ret = wc_AesSetKey(&cmac->aes, key, keySz, NULL, AES_ENCRYPTION);
     if (ret == 0) {
         byte l[AES_BLOCK_SIZE];
@@ -328,5 +342,4 @@ int wc_AesCmacVerify(const byte* check, word32 checkSz,
     return ret;
 }
 
-
 #endif /* WOLFSSL_CMAC && NO_AES && WOLFSSL_AES_DIRECT */

+ 57 - 8
wolfcrypt/src/ecc.c

@@ -5750,7 +5750,8 @@ int wc_ecc_init_ex(ecc_key* key, void* heap, int devId)
 #endif
 
 #ifdef WOLFSSL_SE050
-    key->keyId = -1;
+    key->keyId = 0;
+    key->keyIdSet = 0;
 #endif
 
 #ifdef WOLFSSL_CHECK_MEM_ZERO
@@ -5966,7 +5967,7 @@ static int wc_ecc_sign_hash_hw(const byte* in, word32 inlen,
         }
         (void)rng;
     #elif defined(WOLFSSL_SE050)
-        err = se050_ecc_sign_hash_ex(in, inlen, out, outlen, key);
+        err = se050_ecc_sign_hash_ex(in, inlen, r, s, out, outlen, key);
         if (err != MP_OKAY) {
             return err;
         }
@@ -6042,7 +6043,8 @@ error_out:
         }
     #endif /* HW-specific #if-#elif chain */
 
-        /* Load R and S */
+    #ifndef WOLFSSL_SE050
+        /* Load R and S, SE050 does this in port layer */
         err = mp_read_unsigned_bin(r, &out[0], keysize);
         if (err != MP_OKAY) {
             return err;
@@ -6051,6 +6053,7 @@ error_out:
         if (err != MP_OKAY) {
             return err;
         }
+    #endif
 
         /* Check for zeros */
         if (mp_iszero(r) || mp_iszero(s)) {
@@ -8066,12 +8069,11 @@ 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_XILINX_CRYPT_VERSAL)
    byte sigRS[ECC_MAX_CRYPTO_HW_SIZE * 2];
    byte hashcopy[ECC_MAX_CRYPTO_HW_SIZE] = {0};
-#elif !defined(WOLFSSL_SP_MATH) || defined(FREESCALE_LTC_ECC)
+#elif (!defined(WOLFSSL_SP_MATH) || defined(FREESCALE_LTC_ECC)) && \
+   !defined(WOLFSSL_SE050)
    int          did_init = 0;
    ecc_point    *mG = NULL, *mQ = NULL;
    #ifdef WOLFSSL_NO_MALLOC
@@ -8137,7 +8139,9 @@ int wc_ecc_verify_hash_ex(mp_int *r, mp_int *s, const byte* hash,
     defined(WOLFSSL_KCAPI_ECC) || defined(WOLFSSL_SE050) || \
     defined(WOLFSSL_XILINX_CRYPT_VERSAL)
 
-    /* Extract R and S with front zero padding (if required) */
+#ifndef WOLFSSL_SE050
+    /* Extract R and S with front zero padding (if required),
+     * SE050 does this in port layer  */
     XMEMSET(sigRS, 0, sizeof(sigRS));
     err = mp_to_unsigned_bin(r, sigRS +
                                 (keySz - mp_unsigned_bin_size(r)));
@@ -8149,6 +8153,7 @@ int wc_ecc_verify_hash_ex(mp_int *r, mp_int *s, const byte* hash,
     if (err != MP_OKAY) {
         return err;
     }
+#endif /* WOLFSSL_SE050 */
 
 #if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A)
     err = atmel_ecc_verify(hash, sigRS, key->pubkey_raw, res);
@@ -8193,7 +8198,7 @@ int wc_ecc_verify_hash_ex(mp_int *r, mp_int *s, const byte* hash,
         *res = 1;
     }
 #elif defined(WOLFSSL_SE050)
-    err = se050_ecc_verify_hash_ex(hash, hashlen, sigRS, keySz * 2, key, res);
+    err = se050_ecc_verify_hash_ex(hash, hashlen, r, s, key, res);
 #elif defined(WOLFSSL_XILINX_CRYPT_VERSAL)
     if (hashlen > sizeof(hashcopy))
         return ECC_BAD_ARG_E;
@@ -10067,6 +10072,12 @@ int wc_ecc_import_x963_ex(const byte* in, word32 inLen, ecc_key* key,
 #elif defined(WOLFSSL_SILABS_SE_ACCEL)
     if (err == MP_OKAY)
         err = silabs_ecc_import(key, keysize);
+#elif defined(WOLFSSL_SE050)
+    if (err == MP_OKAY) {
+        /* reset key ID, in case used before */
+        key->keyId = 0;
+        key->keyIdSet = 0;
+    }
 #elif defined(WOLFSSL_XILINX_CRYPT_VERSAL)
     #ifndef HAVE_COMP_KEY
     if (err == MP_OKAY) {
@@ -14543,6 +14554,44 @@ int wc_X963_KDF(enum wc_HashType type, const byte* secret, word32 secretSz,
 }
 #endif /* HAVE_X963_KDF */
 
+#ifdef WOLFSSL_SE050
+/* Use specified hardware key ID with ecc_key operations. Unlike devId,
+ * keyId is a word32, can be used for key IDs larger than an int.
+ *
+ * key    initialized ecc_key struct
+ * keyId  hardware key ID which stores ECC key
+ * flags  optional flags, currently unused
+ *
+ * Return 0 on success, negative on error */
+int wc_ecc_use_key_id(ecc_key* key, word32 keyId, word32 flags)
+{
+    (void)flags;
+
+    if (key == NULL) {
+        return BAD_FUNC_ARG;
+    }
+
+    return se050_ecc_use_key_id(key, keyId);
+}
+
+/* Get hardware key ID associated with this ecc_key structure.
+ *
+ * key    initialized ecc_key struct
+ * keyId  [OUT] output for key ID associated with this structure
+ *
+ * Returns 0 on success, negative on error.
+ */
+int wc_ecc_get_key_id(ecc_key* key, word32* keyId)
+{
+    if (key == NULL || keyId == NULL) {
+        return BAD_FUNC_ARG;
+    }
+
+    return se050_ecc_get_key_id(key, keyId);
+}
+#endif /* WOLFSSL_SE050 */
+
+
 #ifdef WC_ECC_NONBLOCK
 /* Enable ECC support for non-blocking operations */
 int wc_ecc_set_nonblock(ecc_key *key, ecc_nb_ctx_t* ctx)

+ 2 - 2
wolfcrypt/src/ed25519.c

@@ -697,7 +697,7 @@ static int ed25519_verify_msg_final_with_sha(const byte* sig, word32 sigLen,
 }
 #endif /* WOLFSSL_SE050 */
 
-#ifdef WOLFSSL_ED25519_STREAMING_VERIFY
+#if defined(WOLFSSL_ED25519_STREAMING_VERIFY) && !defined(WOLFSSL_SE050)
 
 int wc_ed25519_verify_msg_init(const byte* sig, word32 sigLen, ed25519_key* key,
                                byte type, const byte* context, byte contextLen) {
@@ -717,7 +717,7 @@ int wc_ed25519_verify_msg_final(const byte* sig, word32 sigLen, int* res,
                                          key, &key->sha);
 }
 
-#endif /* WOLFSSL_ED25519_STREAMING_VERIFY */
+#endif /* WOLFSSL_ED25519_STREAMING_VERIFY && !WOLFSSL_SE050 */
 
 /*
    sig     is array of bytes containing the signature

+ 4 - 109
wolfcrypt/src/port/nxp/README.md

@@ -1,116 +1,11 @@
-# NXP Ports
+# wolfSSL NXP Hardware Acceleration Ports
 
-Support for the NXP DCP, KSDK and SE050 hardware acceleration boards. 
+wolfSSL supports hardware acceleration on NXP DCP, LTC (KSDK), and SE050.
 
 ## 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 --with-se050=/home/pi/simw-top CFLAGS="-DWOLFSSL_SE050_INIT"`
-
-To enable AES Cipher support use `WOLFSSL_SE050_CRYPT`
-To enable SHA-1 and SHA-2 support use `WOLFSSL_SE050_HASH`
-
-## 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 <wolfssl/options.h>
-#include <wolfssl/wolfcrypt/types.h>
-#include <wolfssl/wolfcrypt/port/nxp/se050_port.h>
-`` 
-
-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()`. 
+For details on wolfSSL integration with NXP SE050,
+see [README_SE050.md](./README_SE050.md).
 
 ## Support
 

+ 559 - 0
wolfcrypt/src/port/nxp/README_SE050.md

@@ -0,0 +1,559 @@
+# wolfSSL NXP SE050 Support
+
+wolfSSL includes support for the NXP SE050 Plug & Trust Secure Element.
+
+For details about the NXP SE050, 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).
+
+## SE050 Acceleration
+
+wolfSSL supports the following hardware acceleration with SE050:
+
+- TRNG
+- AES (128, 192, 256) encrypt/decrypt
+- SHA-1, SHA2-224, SHA2-256, SHA2-384, SHA2-512
+- ECC support and key generation (NIST 192-521 bit, Brainpool, Koblitz)
+    * ECDSA sign/verify and key generation
+    * ECDH shared secret generation
+- Ed25519 sign/verify and key generation (Twisted Edwards)
+- Curve25519 shared secret and key generation
+- RSA sign/verify/encrypt/decrypt and key generation (up to 4096-bit)
+
+## Building SE05x Plug & Trust Middleware (simw-top)
+
+wolfSSL uses the "EdgeLock SE05x Plug & Trust Middleware" to interface with
+SE050. This can be downloaded from the NXP website [here](https://www.nxp.com/products/security-and-authentication/authentication/edgelock-se050-plug-trust-secure-element-family-enhanced-iot-security-with-high-flexibility:SE050#design-resources).
+An free NXP account is required to download the middleware.
+
+wolfSSL last tested with SE05x middleware version 04.02.00.
+
+Instructions for building will vary on target platform and host operating
+system. A Raspberry Pi with an NXP EdgeLock SE050 Development Kit can be used
+to easily set up and test the SE050. For build instructions on this combination,
+follow the AN12570 application note (EdgeLock SE05x Quick start guide with
+Raspberry Pi, [here](https://www.nxp.com/docs/en/application-note/AN12570.pdf).
+
+Summarizing the build steps for Raspberry Pi:
+
+```sh
+$ cd ~
+$ mkdir se_mw
+$ unzip SE-PLUG-TRUST-MW.zip -d se_mw
+$ cd se_mw/simw-top/scripts
+$ python create_cmake_projects.py rpi
+$ cd ~/se_mw/simw-top_build/raspbian_native_se050_t1oi2c
+$ ccmake .
+# Make sure the following are set:
+#    `Host OS` to `Raspbian`
+#    `Host Crypto` to `None` (see HostCrypto section below)
+#    `SMCOM` to `T1oI2C`
+$ c # to configure
+$ g # to generate
+$ q
+$ cmake --build .
+$ sudo make install
+```
+
+This will also compile several demo apps which can be run if wanted, ie:
+
+```sh
+$ cd ~/se_mw/simw-top_build/raspbian_native_se050_t1oi2c/bin
+$ ./ex_ecc  # (or, ./se05x_GetInfo, etc)
+```
+
+Running `sudo make install` will install SE050 library and header files to:
+
+    /usr/local/lib
+    /usr/local/include/se05x
+
+### Customizing SE05x Middleware
+
+The SE05x Middleware can be configured to use a custom `fsl_sss_ftr.h` header
+file when **`SSS_USE_FTR_FILE`** is defined when compiling the SDK.
+
+When wolfSSL tested SE050 integration on an embedded target, `fsl_sss_ftr.h`:
+
+- Enabled SE050 variant C (`SSS_HAVE_APPLET_SE05X_C`)
+- Enabled SE05X applet version 03 for SE050 (`SSS_HAVE_SE05X_VER_03_XX`)
+- Enabled wolfSSL HostCrypto support (`SSS_HAVE_HOSTCRYPTO_WOLFSSL`)
+- Disabled mbedTLS alt API (`SSS_HAVE_MBEDTLS_ALT_NONE`)
+- Enabled SSS layer for SCP03 (`SSS_HAVE_SCP_SCP03_SSS`)
+- Enabled Platform SCP03 (`SSS_HAVE_SE05X_AUTH_PLATFSCP03`)
+- Set default SCP03 ENC/MAC/DEK keys to match variant in use
+- Algorithm selection left same as default configuration
+
+## Building wolfSSL
+
+To compile wolfSSL with SE050 support using Autoconf/configure:
+
+```sh
+$ cd wolfssl-X.X.X
+$ ./configure --with-se050
+OR
+$ ./configure --with-se050=PATH
+$ make
+```
+
+If no installation path is provided to `--with-se05x`, wolfSSL will use the
+default installation locations above.
+
+If the SE05x middleware libraries have been linked against OpenSSL (on Linux),
+and you run into compiler errors in wolfSSL due to conflicts with the wolfSSL
+compatibility layer headers when compiling wolfSSL's examples and test apps,
+you can compile and install only the wolfSSL library proper using:
+
+```sh
+$ cd wolfssl-X.X.X
+$ ./configure --with-se050 <options>
+$ make src/libwolfssl.la
+$ sudo make install-binPROGRAMS
+$ sudo make install-nobase_includeHEADERS
+```
+
+### wolfSSL Key Generation Inside SE050
+
+wolfSSL can generate RSA and ECC keys inside the SE050. To include that support,
+wolfSSL should be configured with `--enable-keygen` or `-DWOLFSSL_KEY_GEN`.
+
+```sh
+$ ./configure --with-se0500 --enable-keygen
+```
+
+### wolfSSL HostCrypto support for SCP03 Authentication
+
+wolfSSL can be used on the host side (HostCrypto) for secure SCP03
+authentication, in place of OpenSSL or mbedTLS. See the HostCrypto section
+below. To support SCP03, wolfSSL also needs to be compiled with CMAC support:
+
+```
+$ cd wolfssl-X.X.X
+$ ./configure --with-se050 --enable-keygen --enable-cmac
+```
+
+To disable SCP03 and use a non-authenticated I2C connection, wolfSSL was using
+the following define set in `fsl_sss_ftr.h`, with other defines left to the
+defaults:
+
+```c
+#define SSS_HAVE_APPLET_SE05X_C 1
+#define SSS_HAVE_SE05X_VER_03_XX 1
+#define SSS_HAVE_HOSTCRYPTO_NONE 1
+#define SSS_HAVE_MBEDTLS_ALT_NONE 1
+#define SSS_HAVE_SCP_NONE 1
+#define SSS_HAVE_SCP_SCP03_SSS 0
+#define SSS_HAVE_SCP_SCP03_HOSTCRYPTO 0
+#define SSS_HAVE_SE05X_AUTH_NONE 1
+#define SSS_HAVE_SE05X_AUTH_PLATFSCP03 0
+```
+
+To enable SCP03 authentication, wolfSSL was using the following defines:
+
+```c
+#define SSS_HAVE_APPLET_SE05X_C 1
+#define SSS_HAVE_SE05X_VER_03_XX 1
+#define SSS_HAVE_HOSTCRYPTO_WOLFSSL 1
+#define SSS_HAVE_HOSTCRYPTO_NONE 0
+#define SSS_HAVE_MBEDTLS_ALT_NONE 1
+#define SSS_HAVE_SCP_NONE 0
+#define SSS_HAVE_SCP_SCP03_SSS 1
+#define SSS_HAVE_SCP_SCP03_HOSTCRYPTO 0
+#define SSS_HAVE_SE05X_AUTH_NONE 0
+#define SSS_HAVE_SE05X_AUTH_PLATFSCP03 1
+```
+
+Default ENC, MAC, and DEK keys for SCP03 should be set by defining the
+following values. Thes are the default keys wolfSSL used for the SE50C2
+variant (OEF OID: A201). The variant can be seen by running the
+`se05x_GetInfo` sample application.
+
+```c
+#define EX_SSS_AUTH_SE05X_KEY_ENC SSS_AUTH_SE050C2_KEY_ENC
+#define EX_SSS_AUTH_SE05X_KEY_MAC SSS_AUTH_SE050C2_KEY_MAC
+#define EX_SSS_AUTH_SE05X_KEY_DEK SSS_AUTH_SE050C2_KEY_DEK
+```
+
+Default SCP03 keys are located in the following middleware file:
+
+```sh
+<middleware>/simw-top/sss/ex/inc/ex_sss_tp_scp03_keys.h
+```
+
+### wolfSSL SE050 Build Customization
+
+There are several preprocessor defines that can control wolfSSL's SE050
+integration behavior, including:
+
+**`WOLFSSL_SE050_INIT`**
+
+wolfSSL will initialize the SE050 internally. When this is used, developers
+also need to define `SE050_DEFAULT_PORT`. See wolfSSL library initialization
+below.
+
+**`SE050_DEFAULT_PORT`**
+
+Mentinoed above, this should be defined to match the mount location of the
+SE050 if on Linux. Or defined to **NULL** for embedded targets.
+
+**`SE050_KEYID_START`**
+
+When generating keys inside SE050, wolfSSL will automatically pick a key ID
+value based on an incrementing counter past the value defined by this define.
+
+If not defined, this value will default to **100**.
+
+**`WOLFSSL_SE050_FACTORY_RESET`**
+
+When defined, calls to `wolfSSL_Init()` or `wolfCrypt_Init()` will factory
+reset the SE050 board by calling `ex_sss_boot_factory_reset()` internally.
+
+This will erase all user-provisioned key and credential material, leaving only
+the NXP pre-provisioned credentials in place.
+
+**`WOLFSSL_SE050_HASH`**
+
+wolfSSL supports offloading hash operations (SHA-1, SHA2-224, SHA2-256,
+SHA2-384, SHA2-512) to the SE050. This is MUCH slower than using wolfCrypt
+software cryptography due to the I2C communication channel. This support is
+disabled by default unless this define explicitly enables it.
+
+**`WOLFSSL_SE050_CRYPT`**
+
+wolfSSL supports offloading symmetric crypto operations (AES-ECB/CBC) to the
+SE050. Also due to the I2C communication channel, this is MUCH slower than using
+wolfCrypt software crypto. This support is disabled by default unless this
+define explicitly enables it.
+
+**`WOLFSSL_SE050_NO_TRNG`**
+
+By default when `WOLFSSL_SE050` is defined, wolfSSL will try to use the TRNG
+on the SE050 device as a TRNG for seeding wolfCrypt's PRNG/DRBG. To disable
+the use of the SE050 TRNG inside wolfCrypt and instead fall back to the system
+default, this can be defined. This might be used for example when working on
+a Raspberry Pi with SE05x EdgeLock dev kit. If `WOLFSSL_SE050_NO_TRNG` is
+defined, wolfCrypt will instead fall back to using `/dev/random` and
+`/dev/urandom` on the Raspberry Pi.
+
+## wolfSSL HostCrypto Support
+
+The NXP SE05x Plug & Trust Middleware by default can use either OpenSSL or
+mbedTLS has a HostCrypto provider to support secure SCP03 authenticated
+communication between the host and SE050. The HostCrypto provider is used
+for AES CMAC operations on the host side to set up and authenticate the SE050.
+If SCP03 is not used, a plaintext communication channel can be used.
+
+wolfSSL has implemented a HostCrypto layer that can integrate into the
+SE05x Middleware to provide an alternative crypto provider to OpenSSL or
+mbedTLS. To learn more about access to this layer, please contact wolfSSL
+at support@wolfssl.com.
+
+Once a SE05x Middleware source tree has been updated with wolfSSL HostCrypto
+support, wolfSSL support can be enabled by defining
+`SSS_HAVE_HOSTCRYPTO_WOLFSSL` in `fsl_sss_ftr.h`. In this scenario, all of the
+following must be defined to 0 in `fsl_sss_ftr.h`:
+
+```c
+#define SSS_HAVE_HOSTCRYPTO_WOLFSSL 1
+#define SSS_HAVE_HOSTCRYPTO_MBEDTLS 0
+#define SSS_HAVE_HOSTCRYPTO_OPENSSL 0
+#define SSS_HAVE_HOSTCRYPTO_USER 0
+#define SSS_HAVE_HOSTCRYPTO_NONE 0
+```
+## wolfSSL Usage with NXP SE050
+
+### Library and SE050 Initialization and Cleanup
+
+When looking at NXP's SE050 demo applications, developers will notice that the
+connection to SE050 is handled by shared code in
+`<middleware>/sss/ex/inc/ex_sss_main_inc.h`. This code calls
+`ex_sss_boot_open()` to open the connection to SE050. NXP demo applications then
+implement an `ex_sss_entry()` function, which is called by `main()` in
+`ex_sss_main_inc.h`.
+
+wolfSSL has the ability to open the connection to SE050 internally upon library
+initialization. This can make it much easier and simpler for developers who will
+be using the SE050 primarily underneath the wolfSSL APIs.
+
+wolfSSL will initialize the SE050 when the wolfSSL library has been compiled
+with `WOLFSSL_SE050_INIT` defined. When this is used, applications need to:
+
+1. Also define `SE050_DEFAULT_PORT` when compiling wolfSSL
+(ie: `user_settings.h`) to match the mount location of SE050 if on Linux. Or, if
+on an embedded target, this should be defined to **NULL**.
+
+2. Application code should initialize the wolfSSL library like normal with
+`wolfSSL_Init()` or `wolfCrypt_Init()`. When the application is done using
+wolfSSL, resources can be freed and the SE050 connection closed using
+`wolfSSL_Cleanup()` or `wolfCrypt_Cleanup()`. For example:
+
+```c
+/* Initialize wolfCrypt, debugging, logging */
+wolfCrypt_Init();
+wolfSSL_SetLoggingCb(my_logging_cb);
+wolfSSL_Debugging_ON();
+...
+wolfCrypt_Cleanup();
+```
+
+If `WOLFSSL_SE050_INIT` has not been defined when compiling wolfSSL, the
+following API can be called after wolfSSL library initialization to pass the
+correct pre-initialized `sss_session_t` and `sss_key_store_t` structure
+pointers to wolfSSL for internal use. These structures would need to be set up
+by the application using NXP's SSS API from the middleware SDK.
+
+```c
+#include <wolfssl/wolfcrypt/port/nxp/se050_port.h>
+int wc_se050_set_config(
+        sss_session_t *pSession,
+        sss_key_store_t *pHostKeyStore,
+        sss_key_store_t *pKeyStore);
+```
+
+### wolfSSL SE050 Key Generation
+
+wolfSSL includes APIs for key generation when `WOLFSSL_KEY_GEN` has been
+defined while compiling wolfSSL. When wolfSSL has been compiled with SE050
+support (`WOLFSSL_SE050`), it will delegate these key generation operations to
+the SE050 and the private keys will remain in the SE050 for added security.
+
+wolfSSL APIs that will generate keys internal to SE050 are:
+
+```c
+int wc_ecc_make_key(WC_RNG* rng, int keysize, ecc_key* key);
+int wc_MakeRsaKey(RsaKey* key, int size, long e, WC_RNG* rng);
+int wc_ed25519_make_key(WC_RNG* rng, int keysize, ed25519_key* key);
+int wc_curve25519_make_key(WC_RNG* rng, int keysize, curve25519_key* key);
+```
+
+wolfSSL will also use the SE050 for ECDH shared secret generation, but will
+extract the shared secret to hand back to the application.
+
+When generating keys in SE050 wolfSSL will automatically pick a key ID value
+based on an incrementing counter past the value defined by `SE050_KEYID_START`.
+`SE050_KEYID_START` should be defined when compiling wolfSSL
+(`user_settings.h`), otherwise it will default to 100.
+
+### wolfSSL SE050 Key Insertion
+
+Applications can insert public or private RSA and ECC keys into the SE050 at a
+specific key ID using the following wolfSSL helper functions:
+
+```c
+#include <wolfssl/wolfcrypt/port/nxp/se050_port.h>
+
+int wc_se050_ecc_insert_public_key(word32 keyId,
+        const byte* eccDer, word32 eccDerSize);
+int wc_se050_ecc_insert_private_key(word32 keyId,
+        const byte* eccDer, word32 eccDerSize);
+
+int wc_se050_rsa_insert_public_key(word32 keyId,
+        const byte* rsaDer, word32 rsaDerSize);
+int wc_se050_rsa_insert_private_key(word32 keyId,
+        const byte* rsaDer, word32 rsaDerSize);
+```
+
+These APIs will all return 0 on success or a negative error code on failure.
+The input to all these functions is a DER-encoded key and the size of that DER
+array in bytes.
+
+### wolfSSL SE050 Certificate Insertion and Retrieval
+
+Applications can insert or retrieve certificates or binary data into an SE050
+key ID using the following wolfSSL helper functions:
+
+```c
+int wc_se050_insert_binary_object(word32 keyId,
+        const byte* object, word32 objectSz);
+int wc_se050_get_binary_object(word32 keyId,
+        byte* out, word32* outSz);
+```
+
+These APIs will all return 0 on success or a negative error code on failure.
+The input to `wc_se050_insert_binary_object()` is a byte array to be stored in
+the SE050 along with the size of that array in bytes.
+
+The arguments to `wc_se050_get_binary_object()` are the key ID to retrieve data
+from, the output array for data to be placed, and an IN/OUT variable “outSz”
+representing the size of the “out” buffer on input, and on output “outSz” gets
+set to the number of bytes written into “out”.
+
+### wolfSSL SE050 Credential Deletion
+
+wolfSSL will not auto-delete generated keys associated with wolfCrypt
+structures (ex: `RsaKey`, `ecc_key`, etc) when the respective key free function
+is called (ex: `wc_ecc_free()`, `wc_FreeRsaKey()`). This is done by design in
+case the application wants to re-use that key that has been generated and
+stored in the SE050.
+
+Credentials can be deleted from the SE050 storage by calling the wolfSSL helper
+function `wc_se050_erase_object(int keyId)`. This function is available through
+`<wolfssl/wolfcrypt/port/nxp/se050_port.h>`, and should be passed the key ID
+to be deleted.
+
+### wolfSSL SE050 Factory Reset
+
+If wolfSSL is compiled with `WOLFSSL_SE050_FACTORY_RESET` defined, when
+`wolfSSL_Init()` or `wolfCrypt_Init()` is called, wolfSSL will factory reset
+the SE050 board by calling `ex_sss_boot_factory_reset()` internally.
+
+This will erase all user-provisioned key and credential material, leaving only
+the NXP pre-provisioned credentials in place.
+
+## Building wolfSSL SE050 Examples
+
+wolfSSL demos can be easily added to the SE05x middleware source tree such that
+they are build with CMake when the middleware is compiled.
+
+Assuming a Raspberry Pi host platform is being used, with an SE05x EdgeLock
+dev kit:
+
+1. Create a `wolfssl` directory under the demos directory for wolfSSL demos:
+
+```sh
+$ mkdir /home/pi/se_mw/simw-top/demos/wolfssl
+```
+
+2. Create a directory for a wolfSSL demo, for example to create one for the
+wolfCrypt test application:
+
+```sh
+$ mkdir /home/pi/se_mw/simw-top/demos/wolfssl/wolfcrypt_test
+```
+
+3. Create a CMakeLists.txt to put inside `demos/wolfssl`, tying the
+`wolfcrypt_test` app into CMake. This CMakeLists.txt would contain:
+
+```cmake
+ADD_SUBDIRECTORY(wolfcrypt_test)
+```
+
+4. Add the `demos/wolfssl` directory to the top `demos/CMakeLists.txt` file.
+At the bottom of that file, place:
+
+```cmake
+ADD_SUBDIRECTORY(wolfssl)
+```
+
+5. Inside `demos/wolfssl/wolfcrypt_test`, copy the wolfCrypt `test.c` and
+`test.h` files from a wolfSSL installation:
+
+```sh
+$ cd /home/pi/se_mw/simw-top/demos/wolfssl/wolfcrypt_test
+$ cp wolfssl-X.X.X/wolfcrypt/test/test.c ./
+$ cp wolfssl-X.X.X/wolfcrypt/test/test.h ./
+```
+
+6. Create a file called `wolfcrypt_test.c` which will act as the demo
+application. That file would look similar to:
+
+```c
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <wolfssl/options.h>
+#include <wolfssl/wolfcrypt/types.h>
+#include <wolfssl/wolfcrypt/port/nxp/se050_port.h>
+#include <wolfssl/ssl.h>
+#include "test.h"
+
+#include <ex_sss_boot.h>
+#include <fsl_sss_se05x_apis.h>
+#include <nxLog_App.h>
+
+#ifdef __cplusplus
+}
+#endif
+
+#if defined(SIMW_DEMO_ENABLE__DEMO_WOLFCRYPTTEST)
+
+static ex_sss_boot_ctx_t gex_sss_boot_ctx;
+
+#define EX_SSS_BOOT_PCONTEXT (&gex_sss_boot_ctx)
+#define EX_SSS_BOOT_DO_ERASE 1
+#define EX_SSS_BOOT_EXPOSE_ARGC_ARGV 0
+
+#include <ex_sss_main_inc.h>
+
+sss_status_t ex_sss_entry(ex_sss_boot_ctx_t *pCtx)
+{
+    int ret = 0;
+    sss_status_t status = kStatus_SSS_Success;
+    sss_session_t *pSession = (sss_session_t*)&pCtx->session;
+    sss_key_store_t *pKeyStore = (sss_key_store_t*)&pCtx->ks;
+
+    LOG_I("running setconfig");
+    ret = wc_se050_set_config(pSession, NULL, pKeyStore);
+    if (ret != 0) {
+        LOG_E("wc_se050_set_config failed");
+        return kStatus_SSS_Fail;
+    }
+    LOG_I("Ran setconfig successfully");
+
+    wolfSSL_Init();
+    wolfcrypt_test(NULL);
+    wolfSSL_Cleanup();
+
+    LOG_I("Ran wolfCrypt test");
+    return status;
+}
+
+#endif /* SIMW_DEMO_ENABLE__DEMO_WOLFCRYPTTEST */
+```
+
+7. Create a CMakeLists.txt inside `demos/wolfssl/wolfcrypt_test` so that it
+can be compiled with CMake:
+
+```cmake
+PROJECT(wolfcrypt_test)
+FILE(
+    GLOB
+    files
+    *.c
+)
+
+ADD_EXECUTABLE(
+    ${PROJECT_NAME}
+    ${KSDK_STARTUP_FILE} ${files}
+)
+
+TARGET_COMPILE_DEFINITIONS(
+    ${PROJECT_NAME}
+    PRIVATE SIMW_DEMO_ENABLE__DEMO_WOLFCRYPTTEST NO_MAIN_DRIVER BENCH_EMBEDDED USE_CERT_BUFFERS_2048 USE_CERT_BUFFERS_256
+)
+
+TARGET_INCLUDE_DIRECTORIES(
+    ${PROJECT_NAME}
+    PRIVATE ${SIMW_TOP_DIR}/sss/ex/inc /home/pi/se_mw/wolfssl
+)
+
+TARGET_LINK_LIBRARIES(
+    ${PROJECT_NAME}
+    SSS_APIs
+    ex_common
+    wolfssl
+)
+
+CREATE_BINARY(${PROJECT_NAME})
+
+IF(SSS_HAVE_HOST_LINUX_LIKE)
+    INSTALL(TARGETS ${PROJECT_NAME} DESTINATION bin)
+ENDIF()
+```
+
+8. Build the demo app with CMake
+
+The wolfCrypt test demo app should now compile along with the SE05x middleware.
+This assumes that the NXP instructions for setting up the build have been
+completed.
+
+```sh
+$ cd /home/pi/se_mw/simw-top_build/raspbian_native_se050_t1oi2c
+$ cmake --build .
+```
+
+Once the build has finished, the `wolfcrypt_test` executable can be run with:
+
+```sh
+$ cd /home/pi/se_mw/simw-top_build/raspbian_native_se050_t1oi2c/bin
+$ ./wolfcrypt_test
+```
+

File diff suppressed because it is too large
+ 1411 - 45
wolfcrypt/src/port/nxp/se050_port.c


+ 1 - 1
wolfcrypt/src/random.c

@@ -2806,7 +2806,7 @@ int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
             }
             return 0;
         }
-#elif defined(WOLFSSL_SE050)
+#elif defined(WOLFSSL_SE050) && !defined(WOLFSSL_SE050_NO_TRNG)
      #include <wolfssl/wolfcrypt/port/nxp/se050_port.h>
 
     int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz){

+ 100 - 20
wolfcrypt/src/rsa.c

@@ -55,6 +55,9 @@ RSA keys can be used to encrypt, decrypt, sign and verify data.
 #if defined(WOLFSSL_XILINX_CRYPT_VERSAL)
 #include <xsecure_rsaclient.h>
 #endif
+#ifdef WOLFSSL_SE050
+#include <wolfssl/wolfcrypt/port/nxp/se050_port.h>
+#endif
 #ifdef WOLFSSL_HAVE_SP_RSA
 #include <wolfssl/wolfcrypt/sp.h>
 #endif
@@ -573,6 +576,43 @@ static int cc310_RSA_GenerateKeyPair(RsaKey* key, int size, long e)
 }
 #endif /* WOLFSSL_CRYPTOCELL */
 
+#ifdef WOLFSSL_SE050
+/* Use specified hardware key ID with RsaKey operations. Unlike devId,
+ * keyId is a word32 so can handle key IDs larger than an int.
+ *
+ * key    initialized RsaKey struct
+ * keyId  hardware key ID which stores RSA key
+ * flags  optional flags, currently unused
+ *
+ * Return 0 on success, negative on error */
+int wc_RsaUseKeyId(RsaKey* key, word32 keyId, word32 flags)
+{
+    (void)flags;
+
+    if (key == NULL) {
+        return BAD_FUNC_ARG;
+    }
+
+    return se050_rsa_use_key_id(key, keyId);
+}
+
+/* Get hardware key ID associated with this RsaKey structure.
+ *
+ * key    initialized RsaKey struct
+ * keyId  [OUT] output for key ID associated with this structure
+ *
+ * Returns 0 on success, negative on error.
+ */
+int wc_RsaGetKeyId(RsaKey* key, word32* keyId)
+{
+    if (key == NULL || keyId == NULL) {
+        return BAD_FUNC_ARG;
+    }
+
+    return se050_rsa_get_key_id(key, keyId);
+}
+#endif /* WOLFSSL_SE050 */
+
 int wc_FreeRsaKey(RsaKey* key)
 {
     int ret = 0;
@@ -3304,6 +3344,18 @@ static int RsaPublicEncryptEx(const byte* in, word32 inLen, byte* out,
             return cc310_RsaSSL_Sign(in, inLen, out, outLen, key,
                                   cc310_hashModeRSA(hash, 0));
         }
+    #elif defined(WOLFSSL_SE050)
+        if (rsa_type == RSA_PUBLIC_ENCRYPT && pad_value == RSA_BLOCK_TYPE_2) {
+            return se050_rsa_public_encrypt(in, inLen, out, outLen, key,
+                                            rsa_type, pad_value, pad_type, hash,
+                                            mgf, label, labelSz, sz);
+        }
+        else if (rsa_type == RSA_PRIVATE_ENCRYPT &&
+                                              pad_value == RSA_BLOCK_TYPE_1) {
+            return se050_rsa_sign(in, inLen, out, outLen, key, rsa_type,
+                                  pad_value, pad_type, hash, mgf, label,
+                                  labelSz, sz);
+        }
     #endif /* WOLFSSL_CRYPTOCELL */
 
         key->state = RSA_STATE_ENCRYPT_PAD;
@@ -3427,6 +3479,26 @@ static int RsaPrivateDecryptEx(const byte* in, word32 inLen, byte* out,
             return cc310_RsaSSL_Verify(in, inLen, out, key,
                                        cc310_hashModeRSA(hash, 0));
         }
+    #elif defined(WOLFSSL_SE050)
+        if (rsa_type == RSA_PRIVATE_DECRYPT && pad_value == RSA_BLOCK_TYPE_2) {
+            ret = se050_rsa_private_decrypt(in, inLen, out, outLen, key,
+                                            rsa_type, pad_value, pad_type, hash,
+                                            mgf, label, labelSz);
+            if (outPtr != NULL) {
+                *outPtr = out;
+            }
+            return ret;
+        }
+        else if (rsa_type == RSA_PUBLIC_DECRYPT &&
+                                                pad_value == RSA_BLOCK_TYPE_1) {
+            ret = se050_rsa_verify(in, inLen, out, outLen, key, rsa_type,
+                                   pad_value, pad_type, hash, mgf, label,
+                                   labelSz);
+            if (outPtr != NULL) {
+                *outPtr = out;
+            }
+            return ret;
+        }
     #endif /* WOLFSSL_CRYPTOCELL */
 
 
@@ -4625,6 +4697,7 @@ int wc_CheckProbablePrime(const byte* pRaw, word32 pRawSz,
 int wc_MakeRsaKey(RsaKey* key, int size, long e, WC_RNG* rng)
 {
 #ifndef WC_NO_RNG
+#if !defined(WOLFSSL_CRYPTOCELL) && !defined(WOLFSSL_SE050)
 #ifdef WOLFSSL_SMALL_STACK
     mp_int *p = NULL;
     mp_int *q = NULL;
@@ -4637,15 +4710,36 @@ int wc_MakeRsaKey(RsaKey* key, int size, long e, WC_RNG* rng)
     mp_int tmp1_buf, *tmp1 = &tmp1_buf;
     mp_int tmp2_buf, *tmp2 = &tmp2_buf;
     mp_int tmp3_buf, *tmp3 = &tmp3_buf;
-#endif
-    int err, i, failCount, primeSz, isPrime = 0;
+#endif /* WOLFSSL_SMALL_STACK */
+    int i, failCount, primeSz, isPrime = 0;
     byte* buf = NULL;
+#endif /* !WOLFSSL_CRYPTOCELL && !WOLFSSL_SE050 */
+    int err;
 
     if (key == NULL || rng == NULL) {
         err = BAD_FUNC_ARG;
         goto out;
     }
 
+    if (!RsaSizeCheck(size)) {
+        err = BAD_FUNC_ARG;
+        goto out;
+    }
+
+    if (e < 3 || (e & 1) == 0) {
+        err = BAD_FUNC_ARG;
+        goto out;
+    }
+
+#if defined(WOLFSSL_CRYPTOCELL)
+    err = cc310_RSA_GenerateKeyPair(key, size, e);
+    goto out;
+#elif defined(WOLFSSL_SE050)
+    err = se050_rsa_create_key(key, size, e);
+    goto out;
+#else
+    /* software crypto */
+
 #ifdef WOLFSSL_SMALL_STACK
     p = (mp_int *)XMALLOC(sizeof *p, key->heap, DYNAMIC_TYPE_RSA);
     q = (mp_int *)XMALLOC(sizeof *q, key->heap, DYNAMIC_TYPE_RSA);
@@ -4663,23 +4757,6 @@ int wc_MakeRsaKey(RsaKey* key, int size, long e, WC_RNG* rng)
     }
 #endif
 
-    if (!RsaSizeCheck(size)) {
-        err = BAD_FUNC_ARG;
-        goto out;
-    }
-
-    if (e < 3 || (e & 1) == 0) {
-        err = BAD_FUNC_ARG;
-        goto out;
-    }
-
-#if defined(WOLFSSL_CRYPTOCELL)
-
-    err = cc310_RSA_GenerateKeyPair(key, size, e);
-    goto out;
-
-#endif /* WOLFSSL_CRYPTOCELL */
-
 #ifdef WOLF_CRYPTO_CB
     if (key->devId != INVALID_DEVID) {
         err = wc_CryptoCb_MakeRsaKey(key, size, e, rng);
@@ -4979,8 +5056,10 @@ int wc_MakeRsaKey(RsaKey* key, int size, long e, WC_RNG* rng)
 
     err = 0;
 #endif /* WOLF_CRYPTO_CB_ONLY_RSA */
+#endif /* WOLFSSL_CRYPTOCELL / SW only */
   out:
 
+#if !defined(WOLFSSL_CRYPTOCELL) && !defined(WOLFSSL_SE050)
 #ifdef WOLFSSL_SMALL_STACK
     if (p)
         XFREE(p, key->heap, DYNAMIC_TYPE_RSA);
@@ -4998,7 +5077,8 @@ int wc_MakeRsaKey(RsaKey* key, int size, long e, WC_RNG* rng)
     mp_memzero_check(tmp1);
     mp_memzero_check(tmp2);
     mp_memzero_check(tmp3);
-#endif
+#endif /* WOLFSSL_SMALL_STACK */
+#endif /* !WOLFSSL_CRYPTOCELL && !WOLFSSL_SE050 */
 
     return err;
 

+ 3 - 0
wolfcrypt/src/sha.c

@@ -930,6 +930,9 @@ int wc_ShaCopy(wc_Sha* src, wc_Sha* dst)
 #ifdef WOLFSSL_PIC32MZ_HASH
     ret = wc_Pic32HashCopy(&src->cache, &dst->cache);
 #endif
+#if defined(WOLFSSL_SE050) && defined(WOLFSSL_SE050_HASH)
+    ret = se050_hash_copy(&src->se050Ctx, &dst->se050Ctx);
+#endif
 #if defined(WOLFSSL_ESP32WROOM32_CRYPT) && \
     !defined(NO_WOLFSSL_ESP32WROOM32_CRYPT_HASH)
      dst->ctx.mode = src->ctx.mode;

+ 4 - 0
wolfcrypt/src/wc_port.c

@@ -264,6 +264,10 @@ int wolfCrypt_Init(void)
 
     #if defined(WOLFSSL_SE050) && defined(WOLFSSL_SE050_INIT)
         ret = wc_se050_init(NULL);
+        if (ret != 0) {
+            WOLFSSL_MSG("SE050 init failed");
+            return ret;
+        }
     #endif
 
     #ifdef WOLFSSL_ARMASM

+ 50 - 9
wolfcrypt/test/test.c

@@ -1546,7 +1546,7 @@ options: [-s max_relative_stack_bytes] [-m max_relative_heap_memory_bytes]\n\
     {
         int ret;
         func_args args;
-#ifdef WOLFSSL_ESPIDF
+#if defined(WOLFSSL_ESPIDF) || defined(WOLFSSL_SE050)
         /* set dummy wallclock time. */
         struct timeval utctime;
         struct timezone tz;
@@ -2205,6 +2205,7 @@ WOLFSSL_TEST_SUBROUTINE int md5_test(void)
             ERROR_OUT(-1607 - i, exit);
     }
 
+#ifndef NO_LARGE_HASH_TEST
     /* BEGIN LARGE HASH TEST */ {
     byte large_input[1024];
     const char* large_digest =
@@ -2229,6 +2230,7 @@ WOLFSSL_TEST_SUBROUTINE int md5_test(void)
     if (XMEMCMP(hash, large_digest, WC_MD5_DIGEST_SIZE) != 0)
         ERROR_OUT(-1610, exit);
     } /* END LARGE HASH TEST */
+#endif /* NO_LARGE_HASH_TEST */
 
 exit:
 
@@ -2400,9 +2402,11 @@ WOLFSSL_TEST_SUBROUTINE int sha_test(void)
             ERROR_OUT(-1807 - i, exit);
     }
 
+#ifndef NO_LARGE_HASH_TEST
     /* BEGIN LARGE HASH TEST */ {
     byte large_input[1024];
-#if defined(WOLFSSL_RENESAS_TSIP) || defined(WOLFSSL_RENESAS_SCEPROTECT)
+#if defined(WOLFSSL_RENESAS_TSIP) || defined(WOLFSSL_RENESAS_SCEPROTECT) || \
+    defined(HASH_SIZE_LIMIT)
     const char* large_digest =
             "\x1d\x6a\x5a\xf6\xe5\x7c\x86\xce\x7f\x7c\xaf\xd5\xdb\x08\xcd\x59"
             "\x15\x8c\x6d\xb6";
@@ -2414,7 +2418,8 @@ WOLFSSL_TEST_SUBROUTINE int sha_test(void)
     for (i = 0; i < (int)sizeof(large_input); i++) {
         large_input[i] = (byte)(i & 0xFF);
     }
-#if defined(WOLFSSL_RENESAS_TSIP) || defined(WOLFSSL_RENESAS_SCEPROTECT)
+#if defined(WOLFSSL_RENESAS_TSIP) || defined(WOLFSSL_RENESAS_SCEPROTECT) || \
+    defined(HASH_SIZE_LIMIT)
     times = 20;
 #else
     times = 100;
@@ -2434,6 +2439,7 @@ WOLFSSL_TEST_SUBROUTINE int sha_test(void)
     if (XMEMCMP(hash, large_digest, WC_SHA_DIGEST_SIZE) != 0)
         ERROR_OUT(-1810, exit);
     } /* END LARGE HASH TEST */
+#endif /* NO_LARGE_HASH_TEST */
 
 exit:
 
@@ -2790,6 +2796,7 @@ WOLFSSL_TEST_SUBROUTINE int sha256_test(void)
             ERROR_OUT(-2307 - i, exit);
     }
 
+#ifndef NO_LARGE_HASH_TEST
     /* BEGIN LARGE HASH TEST */ {
     byte large_input[1024];
 #ifdef HASH_SIZE_LIMIT
@@ -2824,6 +2831,7 @@ WOLFSSL_TEST_SUBROUTINE int sha256_test(void)
     if (XMEMCMP(hash, large_digest, WC_SHA256_DIGEST_SIZE) != 0)
         ERROR_OUT(-2310, exit);
     } /* END LARGE HASH TEST */
+#endif /* NO_LARGE_HASH_TEST */
 
 exit:
 
@@ -2910,6 +2918,7 @@ WOLFSSL_TEST_SUBROUTINE int sha512_test(void)
             ERROR_OUT(-2407 - i, exit);
     }
 
+#ifndef NO_LARGE_HASH_TEST
     /* BEGIN LARGE HASH TEST */ {
     byte large_input[1024];
 #ifdef HASH_SIZE_LIMIT
@@ -2957,6 +2966,7 @@ WOLFSSL_TEST_SUBROUTINE int sha512_test(void)
     }
 #endif
     } /* END LARGE HASH TEST */
+#endif /* NO_LARGE_HASH_TEST */
 
 exit:
     wc_Sha512Free(&sha);
@@ -3040,6 +3050,7 @@ WOLFSSL_TEST_SUBROUTINE int sha384_test(void)
             ERROR_OUT(-2507 - i, exit);
     }
 
+#ifndef NO_LARGE_HASH_TEST
     /* BEGIN LARGE HASH TEST */ {
     byte large_input[1024];
 #ifdef HASH_SIZE_LIMIT
@@ -3074,6 +3085,7 @@ WOLFSSL_TEST_SUBROUTINE int sha384_test(void)
     if (XMEMCMP(hash, large_digest, WC_SHA384_DIGEST_SIZE) != 0)
         ERROR_OUT(-2510, exit);
     } /* END LARGE HASH TEST */
+#endif /* NO_LARGE_HASH_TEST */
 
 exit:
 
@@ -3141,6 +3153,7 @@ static int sha3_224_test(void)
             ERROR_OUT(-2605 - i, exit);
     }
 
+#ifndef NO_LARGE_HASH_TEST
     /* BEGIN LARGE HASH TEST */ {
     byte large_input[1024];
     const char* large_digest =
@@ -3163,6 +3176,7 @@ static int sha3_224_test(void)
     if (XMEMCMP(hash, large_digest, WC_SHA3_224_DIGEST_SIZE) != 0)
         ERROR_OUT(-2608, exit);
     } /* END LARGE HASH TEST */
+#endif /* NO_LARGE_HASH_TEST */
 
 exit:
     wc_Sha3_224_Free(&sha);
@@ -3242,6 +3256,7 @@ static int sha3_256_test(void)
             ERROR_OUT(-2705 - i, exit);
     }
 
+#ifndef NO_LARGE_HASH_TEST
     /* BEGIN LARGE HASH TEST */ {
     for (i = 0; i < (int)sizeof(large_input); i++) {
         large_input[i] = (byte)(i & 0xFF);
@@ -3259,6 +3274,7 @@ static int sha3_256_test(void)
     if (XMEMCMP(hash, large_digest, WC_SHA3_256_DIGEST_SIZE) != 0)
         ERROR_OUT(-2708, exit);
     } /* END LARGE HASH TEST */
+#endif /* NO_LARGE_HASH_TEST */
 
     /* this is a software only variant of SHA3 not supported by external hardware devices */
 #if defined(WOLFSSL_HASH_FLAGS) && !defined(WOLFSSL_ASYNC_CRYPT)
@@ -3372,6 +3388,7 @@ static int sha3_384_test(void)
     #endif
     }
 
+#ifndef NO_LARGE_HASH_TEST
     /* BEGIN LARGE HASH TEST */ {
     byte large_input[1024];
     const char* large_digest =
@@ -3395,6 +3412,7 @@ static int sha3_384_test(void)
     if (XMEMCMP(hash, large_digest, WC_SHA3_384_DIGEST_SIZE) != 0)
         ERROR_OUT(-2808, exit);
     } /* END LARGE HASH TEST */
+#endif /* NO_LARGE_HASH_TEST */
 
 exit:
     wc_Sha3_384_Free(&sha);
@@ -3468,6 +3486,7 @@ static int sha3_512_test(void)
             ERROR_OUT(-2905 - i, exit);
     }
 
+#ifndef NO_LARGE_HASH_TEST
     /* BEGIN LARGE HASH TEST */ {
     byte large_input[1024];
     const char* large_digest =
@@ -3492,6 +3511,7 @@ static int sha3_512_test(void)
     if (XMEMCMP(hash, large_digest, WC_SHA3_512_DIGEST_SIZE) != 0)
         ERROR_OUT(-2908, exit);
     } /* END LARGE HASH TEST */
+#endif /* NO_LARGE_HASH_TEST */
 
 exit:
     wc_Sha3_512_Free(&sha);
@@ -3680,6 +3700,7 @@ static int shake128_absorb_test(wc_Shake* sha)
             ERROR_OUT(-3103 - i, exit);
     }
 
+#ifndef NO_LARGE_HASH_TEST
     /* BEGIN LARGE HASH TEST */ {
     for (i = 0; i < (int)sizeof(large_input); i++) {
         large_input[i] = (byte)(i & 0xFF);
@@ -3703,6 +3724,7 @@ static int shake128_absorb_test(wc_Shake* sha)
     if (XMEMCMP(hash, large_digest, sizeof(hash)) != 0)
         ERROR_OUT(-3107, exit);
     } /* END LARGE HASH TEST */
+#endif /* NO_LARGE_HASH_TEST */
 
 exit:
     return ret;
@@ -3828,6 +3850,7 @@ WOLFSSL_TEST_SUBROUTINE int shake128_test(void)
             ERROR_OUT(-3103 - i, exit);
     }
 
+#ifndef NO_LARGE_HASH_TEST
     /* BEGIN LARGE HASH TEST */ {
     for (i = 0; i < (int)sizeof(large_input); i++) {
         large_input[i] = (byte)(i & 0xFF);
@@ -3845,6 +3868,7 @@ WOLFSSL_TEST_SUBROUTINE int shake128_test(void)
     if (XMEMCMP(hash, large_digest, 114) != 0)
         ERROR_OUT(-3106, exit);
     } /* END LARGE HASH TEST */
+#endif /* NO_LARGE_HASH_TEST */
 
     ret = shake128_absorb_test(&sha);
 
@@ -3992,6 +4016,7 @@ static int shake256_absorb_test(wc_Shake* sha, byte *large_input_buf,
             ERROR_OUT(-3103 - i, exit);
     }
 
+#ifndef NO_LARGE_HASH_TEST
     /* BEGIN LARGE HASH TEST */ {
     for (i = 0; i < (int)large_input_buf_size; i++) {
         large_input_buf[i] = (byte)(i & 0xFF);
@@ -4015,6 +4040,7 @@ static int shake256_absorb_test(wc_Shake* sha, byte *large_input_buf,
     if (XMEMCMP(hash, large_digest, sizeof(hash)) != 0)
         ERROR_OUT(-3107, exit);
     } /* END LARGE HASH TEST */
+#endif /* NO_LARGE_HASH_TEST */
 
 exit:
     return ret;
@@ -4152,6 +4178,7 @@ WOLFSSL_TEST_SUBROUTINE int shake256_test(void)
         ERROR_OUT(-3107, exit);
 #endif
 
+#ifndef NO_LARGE_HASH_TEST
     /* BEGIN LARGE HASH TEST */ {
     for (i = 0; i < SHAKE256_LARGE_INPUT_BUFSIZ; i++) {
         large_input[i] = (byte)(i & 0xFF);
@@ -4169,6 +4196,7 @@ WOLFSSL_TEST_SUBROUTINE int shake256_test(void)
     if (XMEMCMP(hash, large_digest, 114) != 0)
         ERROR_OUT(-3106, exit);
     } /* END LARGE HASH TEST */
+#endif /* NO_LARGE_HASH_TEST */
 
     ret = shake256_absorb_test(&sha, large_input, SHAKE256_LARGE_INPUT_BUFSIZ);
 exit:
@@ -13978,8 +14006,8 @@ static int rsa_sig_test(RsaKey* key, word32 keyLen, int modLen, WC_RNG* rng)
     if (ret != 0)
 #elif defined(WOLFSSL_RSA_PUBLIC_ONLY) || defined(WOLFSSL_RSA_VERIFY_ONLY)
     if (ret != SIG_TYPE_E)
-#elif defined(WOLFSSL_CRYPTOCELL)
-    /* RNG is handled with the cryptocell */
+#elif defined(WOLFSSL_CRYPTOCELL) || defined(WOLFSSL_SE050)
+    /* RNG is handled by hardware */
     if (ret != 0)
 #else
     if (ret != MISSING_RNG_E)
@@ -14482,7 +14510,9 @@ static int rsa_pss_test(WC_RNG* rng, RsaKey* key)
 #ifdef RSA_PSS_TEST_WRONG_PARAMS
     int              k, l;
 #endif
+#ifndef WOLFSSL_SE050
     int              len;
+#endif
     byte*            plain;
     int              mgf[]   = {
 #ifndef NO_SHA
@@ -14533,7 +14563,12 @@ static int rsa_pss_test(WC_RNG* rng, RsaKey* key)
             ERROR_OUT(-7730, exit_rsa_pss);
         digestSz = wc_HashGetDigestSize(hash[j]);
 
+#ifdef WOLFSSL_SE050
+        /* SE050 only supports MGF matched to same hash type */
+        i = j;
+#else
         for (i = 0; i < (int)(sizeof(mgf)/sizeof(*mgf)); i++) {
+#endif
             outSz = RSA_TEST_BYTES;
             do {
             #if defined(WOLFSSL_ASYNC_CRYPT)
@@ -14605,9 +14640,13 @@ static int rsa_pss_test(WC_RNG* rng, RsaKey* key)
                 }
             }
 #endif
-        }
+#ifndef WOLFSSL_SE050
+        } /* end mgf for loop */
+#endif
     }
 
+/* SE050 generates salts internally only of hash length */
+#ifndef WOLFSSL_SE050
     /* Test that a salt length of zero works. */
     digestSz = wc_HashGetDigestSize(hash[0]);
     outSz = RSA_TEST_BYTES;
@@ -14795,6 +14834,7 @@ static int rsa_pss_test(WC_RNG* rng, RsaKey* key)
         ERROR_OUT(-7745, exit_rsa_pss);
 
     ret = 0;
+#endif /* WOLFSSL_SE050 */
 exit_rsa_pss:
     WC_FREE_VAR(sig, HEAP_HINT);
     WC_FREE_VAR(in, HEAP_HINT);
@@ -15997,8 +16037,9 @@ static int rsa_oaep_padding_test(RsaKey* key, WC_RNG* rng)
 
 /* TODO: investigate why Cavium Nitrox doesn't detect decrypt error here */
 #if !defined(HAVE_CAVIUM) && !defined(WOLFSSL_RSA_PUBLIC_ONLY) && \
-    !defined(WOLFSSL_CRYPTOCELL)
-/* label is unused in cryptocell so it won't detect decrypt error due to label */
+    !defined(WOLFSSL_CRYPTOCELL) && !defined(WOLFSSL_SE050)
+    /* label is unused in cryptocell and SE050 so it won't detect decrypt error
+     * due to label */
     idx = (word32)ret;
     do {
 #if defined(WOLFSSL_ASYNC_CRYPT)
@@ -16072,7 +16113,7 @@ static int rsa_oaep_padding_test(RsaKey* key, WC_RNG* rng)
 
 /* TODO: investigate why Cavium Nitrox doesn't detect decrypt error here */
 #if !defined(HAVE_CAVIUM) && !defined(WOLFSSL_RSA_PUBLIC_ONLY) && \
-    !defined(WOLFSSL_CRYPTOCELL)
+    !defined(WOLFSSL_CRYPTOCELL) && !defined(WOLFSSL_SE050)
         idx = (word32)ret;
         do {
     #if defined(WOLFSSL_ASYNC_CRYPT)

+ 3 - 1
wolfssl/wolfcrypt/aes.h

@@ -202,7 +202,9 @@ struct Aes {
 #ifdef WOLFSSL_SE050
     sss_symmetric_t aes_ctx; /* used as the function context */
     int ctxInitDone;
-    int keyId;
+    word32 keyId;
+    byte   keyIdSet;
+    byte   useSWCrypt; /* Use SW crypt instead of SE050, before SCP03 auth */
 #endif
 #ifdef GCM_TABLE
     /* key-based fast multiplication table. */

+ 3 - 0
wolfssl/wolfcrypt/cmac.h

@@ -68,6 +68,9 @@ struct Cmac {
     word32 used;
     word32 len;
 #endif
+#ifdef WOLFSSL_SE050
+    byte   useSWCrypt; /* Use SW crypt instead of SE050, before SCP03 auth */
+#endif
 };
 
 

+ 2 - 1
wolfssl/wolfcrypt/curve25519.h

@@ -91,7 +91,8 @@ struct curve25519_key {
 #endif
 
 #ifdef WOLFSSL_SE050
-    int keyId;
+    word32 keyId;
+    byte   keyIdSet;
 #endif
 
     /* bit fields */

+ 5 - 0
wolfssl/wolfcrypt/des3.h

@@ -61,6 +61,11 @@ enum {
     #include <wolfssl/wolfcrypt/async.h>
 #endif
 
+#ifdef WOLFSSL_SE050
+    /* SE050 SDK also defines DES_BLOCK_SIZE */
+    #undef DES_BLOCK_SIZE
+#endif
+
 enum {
     DES_ENC_TYPE    = WC_CIPHER_DES,     /* cipher unique type */
     DES3_ENC_TYPE   = WC_CIPHER_DES3,    /* cipher unique type */

+ 10 - 3
wolfssl/wolfcrypt/ecc.h

@@ -177,8 +177,7 @@ enum {
     #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,
+    ECC_MAX_CRYPTO_HW_SIZE = 66,
 #elif defined(WOLFSSL_XILINX_CRYPT_VERSAL)
     ECC_MAX_CRYPTO_HW_SIZE = MAX_ECC_BYTES,
 #endif
@@ -453,7 +452,8 @@ struct ecc_key {
     int    partNum; /* partition number*/
 #endif
 #ifdef WOLFSSL_SE050
-    int keyId;
+    word32 keyId;
+    byte   keyIdSet;
 #endif
 #if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A)
     int  slot;        /* Key Slot Number (-1 unknown) */
@@ -926,6 +926,13 @@ int sp_dsp_ecc_verify_256(remote_handle64 handle, const byte* hash, word32 hashL
     mp_int* pY, mp_int* pZ, mp_int* r, mp_int* sm, int* res, void* heap);
 #endif
 
+#ifdef WOLFSSL_SE050
+WOLFSSL_API
+int wc_ecc_use_key_id(ecc_key* key, word32 keyId, word32 flags);
+WOLFSSL_API
+int wc_ecc_get_key_id(ecc_key* key, word32* keyId);
+#endif
+
 #ifdef WC_ECC_NONBLOCK
     WOLFSSL_API int wc_ecc_set_nonblock(ecc_key *key, ecc_nb_ctx_t* ctx);
 #endif

+ 2 - 1
wolfssl/wolfcrypt/ed25519.h

@@ -93,8 +93,9 @@ struct ed25519_key {
     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;
+    word32 keyId;
     word32 flags;
+    byte   keyIdSet;
 #endif
     word16 privKeySet:1;
     word16 pubKeySet:1;

+ 4 - 1
wolfssl/wolfcrypt/include.am

@@ -83,7 +83,6 @@ 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/xilinx/xil-versal-glue.h \
                          wolfssl/wolfcrypt/port/xilinx/xil-versal-trng.h \
@@ -192,3 +191,7 @@ endif
 if BUILD_PSA
 nobase_include_HEADERS+= wolfssl/wolfcrypt/port/psa/psa.h
 endif
+
+if BUILD_SE050
+nobase_include_HEADERS+= wolfssl/wolfcrypt/port/nxp/se050_port.h
+endif

+ 84 - 17
wolfssl/wolfcrypt/port/nxp/se050_port.h

@@ -33,6 +33,7 @@
 
 #include "fsl_sss_se05x_types.h"
 #include "fsl_sss_se05x_apis.h"
+#include "se05x_APDU.h"
 
 #if (SSS_HAVE_SSS > 1)
 #include "fsl_sss_api.h"
@@ -60,16 +61,24 @@
 #ifndef SE050_KEYSTOREID_ED25519
 #define SE050_KEYSTOREID_ED25519 58
 #endif
+#ifndef SE050_KEYSTOREID_CURVE25519
+#define SE050_KEYSTOREID_CURVE25519 59
+#endif
 #ifndef SE050_KEYSTOREID_ECC
 #define SE050_KEYSTOREID_ECC     60
 #endif
-#ifndef SE050_KEYSTOREID_CURVE25519
-#define SE050_KEYSTOREID_CURVE25519 59
+#ifndef SE050_KEYSTOREID_RSA
+#define SE050_KEYSTOREID_RSA     61
+#endif
+#ifndef SE050_KEYSTOREID_GENERIC
+#define SE050_KEYSTOREID_GENERIC 62
 #endif
 
-enum {
-    SSS_BLOCK_SIZE = 512,
+/* old public API was renamed to add wc_ */
+#define se050_ecc_insert_private_key wc_se050_ecc_insert_private_key
 
+enum {
+    SSS_BLOCK_SIZE   = 512,
     SSS_MAX_ECC_BITS = 521
 };
 
@@ -77,17 +86,20 @@ enum SE050KeyType {
     SE050_ANY_KEY,
     SE050_AES_KEY,
     SE050_ECC_KEY,
+    SE050_RSA_KEY,
     SE050_ED25519_KEY,
     SE050_CURVE25519_KEY
 };
 
 
+#ifdef WOLFSSL_SE050_HASH
 typedef struct {
     void*  heap;
     byte*  msg;
     word32 used;
     word32 len;
 } SE050_HASH_Context;
+#endif
 
 /* Public Functions */
 WOLFSSL_API int wc_se050_set_config(sss_session_t *pSession,
@@ -95,67 +107,122 @@ WOLFSSL_API int wc_se050_set_config(sss_session_t *pSession,
 #ifdef WOLFSSL_SE050_INIT
 WOLFSSL_API int wc_se050_init(const char* portName);
 #endif
-WOLFSSL_API int se050_ecc_insert_private_key(int keyId, const byte* eccDer,
-    word32 eccDerSize);
+WOLFSSL_API int wc_se050_erase_object(word32 keyId);
+
+WOLFSSL_API int wc_se050_ecc_insert_public_key(word32 keyId,
+    const byte* eccDer, word32 eccDerSize);
+WOLFSSL_API int wc_se050_ecc_insert_private_key(word32 keyId,
+    const byte* eccDer, word32 eccDerSize);
+
+WOLFSSL_API int wc_se050_rsa_insert_public_key(word32 keyId,
+    const byte* rsaDer, word32 rsaDerSize);
+WOLFSSL_API int wc_se050_rsa_insert_private_key(word32 keyId,
+    const byte* rsaDer, word32 rsaDerSize);
+
+WOLFSSL_API int wc_se050_insert_binary_object(word32 keyId,
+    const byte* object, word32 objectSz);
+WOLFSSL_API int wc_se050_get_binary_object(word32 keyId,
+    byte* out, word32* outSz);
 
 /* Private Functions */
-WOLFSSL_LOCAL int se050_allocate_key(int keyType);
+WOLFSSL_LOCAL word32 se050_allocate_key(int keyType);
+#if !defined(WC_NO_RNG) && !defined(WOLFSSL_SE050_NO_TRNG)
 WOLFSSL_LOCAL int se050_get_random_number(uint32_t count, uint8_t* rand_out);
+#endif
 
+#ifdef WOLFSSL_SE050_HASH
 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, sss_algorithm_t algo);
+WOLFSSL_LOCAL int se050_hash_copy(SE050_HASH_Context* src,
+    SE050_HASH_Context* dst);
 WOLFSSL_LOCAL void se050_hash_free(SE050_HASH_Context* se050Ctx);
+#endif
 
+#if defined(WOLFSSL_SE050_CRYPT) && !defined(NO_AES)
 struct Aes;
+WOLFSSL_LOCAL int se050_aes_free_key_store_object(struct Aes* 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);
+#endif
 
-
-struct ecc_key;
 struct WC_RNG;
+#ifdef HAVE_ECC
 #if defined(WOLFSSL_SP_MATH) || defined(WOLFSSL_SP_MATH_ALL)
     struct sp_int;
     #define MATH_INT_T struct sp_int
+    typedef struct sp_int mp_int;
 #elif defined(USE_FAST_MATH)
     struct fp_int;
     #define MATH_INT_T struct fp_int
+    typedef struct fp_int mp_int;
 #else
     struct mp_int;
 	#define MATH_INT_T struct mp_int
 #endif
+struct ecc_key;
 
+WOLFSSL_LOCAL int se050_ecc_use_key_id(struct ecc_key* key, word32 keyId);
+WOLFSSL_LOCAL int se050_ecc_get_key_id(struct ecc_key* key, word32* keyId);
 WOLFSSL_LOCAL int se050_ecc_sign_hash_ex(const byte* in, word32 inLen,
-    byte* out, word32 *outLen, struct ecc_key* key);
+    mp_int* r, mp_int* s, byte* out, word32 *outLen, struct ecc_key* key);
 
 WOLFSSL_LOCAL int se050_ecc_verify_hash_ex(const byte* hash, word32 hashlen,
-    byte* sigRS, word32 sigRSLen, struct ecc_key* key, int* res);
+    mp_int* r, mp_int* s, 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_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 void se050_ecc_free_key(struct ecc_key* key);
+#endif /* HAVE_ECC */
+
+#ifndef NO_RSA
+struct RsaKey;
+WOLFSSL_LOCAL int se050_rsa_use_key_id(struct RsaKey* key, word32 keyId);
+WOLFSSL_LOCAL int se050_rsa_get_key_id(struct RsaKey* key, word32* keyId);
+WOLFSSL_LOCAL int se050_rsa_create_key(struct RsaKey* key, int size, long e);
+WOLFSSL_LOCAL void se050_rsa_free_key(struct RsaKey* key);
+WOLFSSL_LOCAL int se050_rsa_sign(const byte* in, word32 inLen, byte* out,
+    word32 outLen, struct RsaKey* key, int rsa_type, byte pad_value,
+    int pad_type, enum wc_HashType hash, int mgf, byte* label, word32 labelSz,
+    int keySz);
+WOLFSSL_LOCAL int se050_rsa_verify(const byte* in, word32 inLen, byte* out,
+    word32 outLen, struct RsaKey* key, int rsa_type, byte pad_value,
+    int pad_type, enum wc_HashType hash, int mgf, byte* label, word32 labelSz);
+WOLFSSL_LOCAL int se050_rsa_public_encrypt(const byte* in, word32 inLen,
+    byte* out, word32 outLen, struct RsaKey* key, int rsa_type, byte pad_value,
+    int pad_type, enum wc_HashType hash, int mgf, byte* label,
+    word32 labelSz, int keySz);
+WOLFSSL_LOCAL int se050_rsa_private_decrypt(const byte* in, word32 inLen,
+    byte* out, word32 outLen, struct RsaKey* key, int rsa_type, byte pad_value,
+    int pad_type, enum wc_HashType hash, int mgf, byte* label, word32 labelSz);
+#endif
 
-
+#ifdef HAVE_ED25519
 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 /* HAVE_ED25519 */
 
+#ifdef HAVE_CURVE25519
 struct curve25519_key;
 struct ECPoint;
-WOLFSSL_LOCAL int se050_curve25519_create_key(struct curve25519_key* key, int keySize);
-WOLFSSL_LOCAL int se050_curve25519_shared_secret(struct curve25519_key* private_key,
-    struct curve25519_key* public_key, struct ECPoint* out);
+WOLFSSL_LOCAL int se050_curve25519_create_key(struct curve25519_key* key,
+    int keySize);
+WOLFSSL_LOCAL int se050_curve25519_shared_secret(
+    struct curve25519_key* private_key, struct curve25519_key* public_key,
+    struct ECPoint* out);
 WOLFSSL_LOCAL void se050_curve25519_free_key(struct curve25519_key* key);
+#endif /* HAVE_CURVE25519 */
 #endif /* _SE050_PORT_H_ */

+ 9 - 1
wolfssl/wolfcrypt/rsa.h

@@ -206,6 +206,10 @@ struct RsaKey {
 #ifdef WC_RSA_BLINDING
     WC_RNG* rng;                              /* for PrivateDecrypt blinding */
 #endif
+#ifdef WOLFSSL_SE050
+    word32 keyId;
+    byte   keyIdSet;
+#endif
 #ifdef WOLF_CRYPTO_CB
     int   devId;
 #endif
@@ -276,6 +280,10 @@ WOLFSSL_API int  wc_CheckRsaKey(RsaKey* key);
 #ifdef WOLFSSL_XILINX_CRYPT
 WOLFSSL_LOCAL int wc_InitRsaHw(RsaKey* key);
 #endif /* WOLFSSL_XILINX_CRYPT */
+#ifdef WOLFSSL_SE050
+WOLFSSL_API int wc_RsaUseKeyId(RsaKey* key, word32 keyId, word32 flags);
+WOLFSSL_API int wc_RsaGetKeyId(RsaKey* key, word32* keyId);
+#endif /* WOLFSSL_SE050 */
 
 WOLFSSL_API int  wc_RsaFunction(const byte* in, word32 inLen, byte* out,
                            word32* outLen, int type, RsaKey* key, WC_RNG* rng);
@@ -349,7 +357,7 @@ WOLFSSL_API int  wc_RsaPublicKeyDecode(const byte* input, word32* inOutIdx,
 WOLFSSL_API int  wc_RsaPublicKeyDecodeRaw(const byte* n, word32 nSz,
                                         const byte* e, word32 eSz, RsaKey* key);
 #if defined(WOLFSSL_KEY_GEN) || defined(OPENSSL_EXTRA) || \
-        defined(WOLFSSL_KCAPI_RSA)
+        defined(WOLFSSL_KCAPI_RSA) || defined(WOLFSSL_SE050)
     WOLFSSL_API int wc_RsaKeyToDer(RsaKey* key, byte* output, word32 inLen);
 #endif
 

Some files were not shown because too many files changed in this diff