diff --git a/configure.ac b/configure.ac index ed7a512a471..56d06a879d2 100644 --- a/configure.ac +++ b/configure.ac @@ -3018,48 +3018,154 @@ AC_ARG_WITH([maxq10xx], ] ) +AC_ARG_ENABLE([microchip], + [AS_HELP_STRING([--enable-microchip],[Enable wolfSSL support for microchip/atmel 508/608/100 (default: disabled)])], + [ ENABLED_ATMEL=$enableval ], + [ ENABLED_ATMEL=no ] + ) + +if test "$ENABLED_ATMEL" != "no" +then + AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_MICROCHIP" + + for v in `echo $ENABLED_ATMEL | tr "," " "` + do + case $v in + 508) + AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_ATECC508A" + ;; + + 608) + AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_ATECC608A" + ;; + + 100) + AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_MICROCHIP_TA100 -DMICROCHIP_DEV_TYPE=TA100" + ;; + esac + done +fi + + # Microchip/Atmel CryptoAuthLib ENABLED_CRYPTOAUTHLIB="no" -trylibatcadir="" AC_ARG_WITH([cryptoauthlib], - [AS_HELP_STRING([--with-cryptoauthlib=PATH],[PATH to CryptoAuthLib install (default /usr/)])], - [ - AC_MSG_CHECKING([for cryptoauthlib]) - CPPFLAGS="$CPPFLAGS -DWOLFSSL_ATECC508A" - LIBS="$LIBS -lcryptoauth" - - AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include ]], [[ atcab_init(0); ]])],[ libatca_linked=yes ],[ libatca_linked=no ]) + [AS_HELP_STRING([--with-cryptoauthlib=PATH], + [PATH to CryptoAuthLib install (default: system paths)])], + [with_cryptoauthlib=$withval], + [with_cryptoauthlib=no]) + +AS_IF([test "x$with_cryptoauthlib" != "xno"], [ + AC_MSG_CHECKING([for CryptoAuthLib]) + + libdir="" + incdir="" + cryptoauthlib_found="no" + + saved_LIBS="$LIBS" + saved_LDFLAGS="$LDFLAGS" + saved_CPPFLAGS="$CPPFLAGS" + saved_CFLAGS="$CFLAGS" + + # Method 1: Try pkg-config first (most reliable) + PKG_CHECK_MODULES([CRYPTOAUTHLIB], [cryptoauthlib], [ + CPPFLAGS="$CRYPTOAUTHLIB_CFLAGS $CPPFLAGS" + CFLAGS="$CRYPTOAUTHLIB_CFLAGS $CFLAGS" + LDFLAGS="$CRYPTOAUTHLIB_LIBS $LDFLAGS" + LIBS="$CRYPTOAUTHLIB_LIBS $LIBS" + cryptoauthlib_found="pkg-config" + ], [ + # Method 2: Manual search + AS_IF([test "x$with_cryptoauthlib" = "xyes"], [ + search_dirs="/usr /usr/local" + ], [ + search_dirs="$with_cryptoauthlib" + ]) - if test "x$libatca_linked" = "xno" ; then - if test "x$withval" != "xno" ; then - trylibatcadir=$withval - fi - if test "x$withval" = "xyes" ; then - trylibatcadir="/usr" + for trylibatcadir in $search_dirs; do + for try_libdir in "$trylibatcadir/lib" "$trylibatcadir/lib64"; do + if test -f "$try_libdir/libcryptoauth.so" || test -f "$try_libdir/libcryptoauth.a"; then + libdir="$try_libdir" + break + fi + done + + if test -z "$libdir"; then + if test -x /usr/bin/dpkg-architecture; then + DEB_HOST_MULTIARCH=`dpkg-architecture -qDEB_HOST_MULTIARCH 2>/dev/null` + if test -n "$DEB_HOST_MULTIARCH"; then + try_libdir="$trylibatcadir/lib/$DEB_HOST_MULTIARCH" + if test -f "$try_libdir/libcryptoauth.so" || test -f "$try_libdir/libcryptoauth.a"; then + libdir="$try_libdir" + fi + fi + fi fi - LDFLAGS="$LDFLAGS -L$trylibatcadir/lib" - CPPFLAGS="$CPPFLAGS -I$trylibatcadir/lib" - - AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include ]], [[ atcab_init(0); ]])],[ libatca_linked=yes ],[ libatca_linked=no ]) + for try_incdir in "$trylibatcadir/include/cryptoauthlib" "$trylibatcadir/include"; do + if test -f "$try_incdir/cryptoauthlib.h"; then + incdir="$try_incdir" + break + fi + done - if test "x$libatca_linked" = "xno" ; then - AC_MSG_ERROR([cryptoauthlib isn't found. - If it's already installed, specify its path using --with-cryptoauthlib=/dir/]) + if test -n "$libdir" && test -n "$incdir"; then + break fi + libdir="" + incdir="" + done - AM_LDFLAGS="$AM_LDFLAGS -L$trylibatcadir/lib" - AM_CFLAGS="$AM_CFLAGS -I$trylibatcadir/lib" - AC_MSG_RESULT([yes]) - else - AC_MSG_RESULT([yes]) + if test -n "$libdir" && test -n "$incdir"; then + CPPFLAGS="-I$incdir $CPPFLAGS" + CFLAGS="-I$incdir $CFLAGS" + LDFLAGS="-L$libdir $LDFLAGS" + LIBS="-lcryptoauth $LIBS" + cryptoauthlib_found="$libdir" fi + ]) - ENABLED_CRYPTOAUTHLIB="yes" - AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_ATECC508A" - ] -) + AS_IF([test "x$cryptoauthlib_found" != "xno"], [ + wolfssl_include="" + AS_IF([test -f "${srcdir}/wolfssl/wolfcrypt/types.h"], [ + wolfssl_include="-I${srcdir}" + ], [test -f "${srcdir}/wolfssl.h"], [ + wolfssl_include="-I${srcdir}" + ]) + + test_CPPFLAGS="$wolfssl_include $CPPFLAGS" + test_CFLAGS="$wolfssl_include $CFLAGS" + + saved_test_CPPFLAGS="$CPPFLAGS" + saved_test_CFLAGS="$CFLAGS" + CPPFLAGS="$test_CPPFLAGS" + CFLAGS="$test_CFLAGS" + + AC_LINK_IFELSE([AC_LANG_PROGRAM( + [[#include ]], + [[atcab_init(0); return 0;]])], + [ + ENABLED_CRYPTOAUTHLIB="yes" + AC_MSG_RESULT([yes ($cryptoauthlib_found)]) + AC_DEFINE([HAVE_CRYPTOAUTHLIB], [1], [CryptoAuthLib support]) + CPPFLAGS="$saved_test_CPPFLAGS" + CFLAGS="$saved_test_CFLAGS" + ], + [ + LIBS="$saved_LIBS" + LDFLAGS="$saved_LDFLAGS" + CPPFLAGS="$saved_CPPFLAGS" + CFLAGS="$saved_CFLAGS" + AC_MSG_RESULT([no - compilation failed]) + AC_MSG_ERROR([CryptoAuthLib found but test compilation failed. Check config.log for details.]) + ]) + ], [ + AC_MSG_RESULT([no - library not found]) + AC_MSG_ERROR([CryptoAuthLib not found. Install it or specify path with --with-cryptoauthlib=/path]) + ]) +]) +AM_CONDITIONAL([BUILD_CRYPTOAUTHLIB], [test "x$ENABLED_CRYPTOAUTHLIB" = "xyes"]) # TropicSquare TROPIC01 # Example: "./configure --with-tropic01=/home/pi/libtropic" diff --git a/src/pk_ec.c b/src/pk_ec.c index 7502030e240..4e43f2fd4c4 100644 --- a/src/pk_ec.c +++ b/src/pk_ec.c @@ -1999,6 +1999,7 @@ int wolfSSL_EC_POINT_set_affine_coordinates_GFp(const WOLFSSL_EC_GROUP* group, } #if !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_ATECC608A) && \ + !defined(WOLFSSL_MICROCHIP_TA100) && \ !defined(HAVE_SELFTEST) && !defined(WOLFSSL_SP_MATH) && \ !defined(WOLF_CRYPTO_CB_ONLY_ECC) /* Add two points on the same together. diff --git a/tests/api/test_ecc.c b/tests/api/test_ecc.c index 69fd8b1e955..439faa668ce 100644 --- a/tests/api/test_ecc.c +++ b/tests/api/test_ecc.c @@ -1369,7 +1369,8 @@ int test_wc_ecc_pointFns(void) EXPECT_DECLS; #if defined(HAVE_ECC) && defined(HAVE_ECC_KEY_EXPORT) && \ !defined(WC_NO_RNG) && !defined(WOLFSSL_ATECC508A) && \ - !defined(WOLFSSL_ATECC608A) && !defined(WOLF_CRYPTO_CB_ONLY_ECC) + !defined(WOLFSSL_ATECC608A) && !defined(WOLF_CRYPTO_CB_ONLY_ECC) && \ + !defined(WOLFSSL_MICROCHIP_TA100) ecc_key key; WC_RNG rng; int ret; @@ -1474,7 +1475,8 @@ int test_wc_ecc_shared_secret_ssh(void) #if defined(HAVE_ECC) && defined(HAVE_ECC_DHE) && \ !defined(WC_NO_RNG) && !defined(WOLFSSL_ATECC508A) && \ !defined(WOLFSSL_ATECC608A) && !defined(PLUTON_CRYPTO_ECC) && \ - !defined(WOLFSSL_CRYPTOCELL) && !defined(WOLF_CRYPTO_CB_ONLY_ECC) + !defined(WOLFSSL_CRYPTOCELL) && !defined(WOLF_CRYPTO_CB_ONLY_ECC) && \ + !defined(WOLFSSL_MICROCHIP_TA100) ecc_key key; ecc_key key2; WC_RNG rng; @@ -1554,7 +1556,8 @@ int test_wc_ecc_verify_hash_ex(void) EXPECT_DECLS; #if defined(HAVE_ECC) && defined(HAVE_ECC_SIGN) && defined(WOLFSSL_PUBLIC_MP) \ && !defined(WC_NO_RNG) && !defined(WOLFSSL_ATECC508A) && \ - !defined(WOLFSSL_ATECC608A) && !defined(WOLFSSL_KCAPI_ECC) + !defined(WOLFSSL_ATECC608A) && !defined(WOLFSSL_KCAPI_ECC) && \ + !defined(WOLFSSL_MICROCHIP_TA100) ecc_key key; WC_RNG rng; int ret; @@ -1648,6 +1651,7 @@ int test_wc_ecc_mulmod(void) EXPECT_DECLS; #if defined(HAVE_ECC) && !defined(WC_NO_RNG) && \ !(defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A) || \ + defined(WOLFSSL_MICROCHIP_TA100) || \ defined(WOLFSSL_VALIDATE_ECC_IMPORT)) && \ !defined(WOLF_CRYPTO_CB_ONLY_ECC) ecc_key key1; @@ -1871,4 +1875,3 @@ int test_wc_EccPrivateKeyToDer(void) #endif return EXPECT_RESULT(); } /* End test_wc_EccPrivateKeyToDer */ - diff --git a/tests/api/test_ossl_ec.c b/tests/api/test_ossl_ec.c index 33c4678a235..d08b8cdba41 100644 --- a/tests/api/test_ossl_ec.c +++ b/tests/api/test_ossl_ec.c @@ -428,6 +428,7 @@ int test_wolfSSL_EC_POINT(void) X, Y, ctx), 0); #if !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_ATECC608A) && \ + !defined(WOLFSSL_MICROCHIP_TA100) && \ !defined(HAVE_SELFTEST) && !defined(WOLFSSL_SP_MATH) && \ !defined(WOLF_CRYPTO_CB_ONLY_ECC) ExpectIntEQ(EC_POINT_add(NULL, NULL, NULL, NULL, ctx), 0); @@ -514,6 +515,7 @@ int test_wolfSSL_EC_POINT(void) ExpectIntEQ(EC_POINT_invert(group, new_point, ctx), 1); #if !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_ATECC608A) && \ + !defined(WOLFSSL_MICROCHIP_TA100) && \ !defined(HAVE_SELFTEST) && !defined(WOLFSSL_SP_MATH) && \ !defined(WOLF_CRYPTO_CB_ONLY_ECC) { @@ -788,6 +790,7 @@ int test_wolfSSL_SPAKE(void) #if defined(OPENSSL_EXTRA) && defined(HAVE_ECC) && !defined(WOLFSSL_ATECC508A) \ && !defined(WOLFSSL_ATECC608A) && !defined(HAVE_SELFTEST) && \ + !defined(WOLFSSL_MICROCHIP_TA100) && \ !defined(WOLFSSL_SP_MATH) && !defined(WOLF_CRYPTO_CB_ONLY_ECC) BIGNUM* x = NULL; /* kdc priv */ BIGNUM* y = NULL; /* client priv */ diff --git a/wolfcrypt/benchmark/benchmark.c b/wolfcrypt/benchmark/benchmark.c index f6e2615e99d..e31fc2e1ebc 100644 --- a/wolfcrypt/benchmark/benchmark.c +++ b/wolfcrypt/benchmark/benchmark.c @@ -818,8 +818,6 @@ static WC_INLINE void bench_append_memory_info(char* buffer, size_t size, #define TEST_STRING "Everyone gets Friday off." #define TEST_STRING_SZ 25 - - /* Bit values for each algorithm that is able to be benchmarked. * Common grouping of algorithms also. * Each algorithm has a unique value for its type e.g. cipher. @@ -2051,6 +2049,9 @@ static const char* bench_result_words2[][6] = { }; #endif #endif +#if defined(WOLFSSL_MICROCHIP_TA100) + #include +#endif #ifdef WOLFSSL_CAAM #include @@ -2078,7 +2079,8 @@ static const char* bench_result_words2[][6] = { static volatile int g_threadCount; #endif -#if defined(WOLFSSL_ASYNC_CRYPT) || defined(WOLFSSL_CAAM) || defined(WC_USE_DEVID) +#if defined(WOLFSSL_ASYNC_CRYPT) || defined(WOLFSSL_CAAM) || defined(WC_USE_DEVID) || \ + defined(WOLFSSL_MICROCHIP_TA100) #ifndef NO_HW_BENCH #define BENCH_DEVID #endif @@ -9987,8 +9989,12 @@ static void bench_rsa_helper(int useDeviceID, 1, ×, ntimes, &pending)) { #if !defined(WOLFSSL_RSA_VERIFY_INLINE) && \ !defined(WOLFSSL_RSA_PUBLIC_ONLY) - ret = wc_RsaSSL_Verify(enc[i], idx, out[i], + #if defined(WOLFSSL_MICROCHIP_TA100) + ret = wc_RsaSSL_Verify(message, len, enc[i], rsaKeySz/8, rsaKey[i]); + #else + ret = wc_RsaSSL_Verify(enc[i], idx, out[i], rsaKeySz/8, rsaKey[i]); + #endif #elif defined(USE_CERT_BUFFERS_2048) XMEMCPY(enc[i], rsa_2048_sig, sizeof(rsa_2048_sig)); idx = sizeof(rsa_2048_sig); @@ -10124,6 +10130,13 @@ void bench_rsa(int useDeviceID) #else /* Note: To benchmark public only define WOLFSSL_PUBLIC_MP */ rsaKeySz = 0; +#endif +#if defined(WOLFSSL_KEY_GEN) && defined(WOLFSSL_MICROCHIP_TA100) + /* Create new keys since you cannot import a private key to TA100 */ + ret = wc_MakeRsaKey(rsaKey[i], rsaKeySz, WC_RSA_EXPONENT, &gRng); + if (ret) { + goto exit; + } #endif } @@ -12146,6 +12159,9 @@ void bench_ecc(int useDeviceID, int curveId) if ((ret = wc_ecc_init_ex(genKey[i], HEAP_HINT, deviceID)) < 0) { goto exit; } +#if defined(WOLFSSL_MICROCHIP_TA100) + genKey[i]->slot = atmel_ecc_alloc(ATMEL_SLOT_ECDHE_ALICE); +#endif ret = wc_ecc_make_key_ex(&gRng, keySize, genKey[i], curveId); #ifdef WOLFSSL_ASYNC_CRYPT ret = wc_AsyncWait(ret, &genKey[i]->asyncDev, WC_ASYNC_FLAG_NONE); @@ -12158,6 +12174,9 @@ void bench_ecc(int useDeviceID, int curveId) if ((ret = wc_ecc_init_ex(genKey2[i], HEAP_HINT, deviceID)) < 0) { goto exit; } +#if defined(WOLFSSL_MICROCHIP_TA100) + genKey2[i]->slot = atmel_ecc_alloc(ATMEL_SLOT_ECDHE_BOB); +#endif if ((ret = wc_ecc_make_key_ex(&gRng, keySize, genKey2[i], curveId)) > 0) { goto exit; @@ -12354,7 +12373,6 @@ void bench_ecc(int useDeviceID, int curveId) WC_FREE_ARRAY(sig, BENCH_MAX_PENDING, HEAP_HINT); WC_FREE_ARRAY(digest, BENCH_MAX_PENDING, HEAP_HINT); #endif - (void)useDeviceID; (void)pending; (void)x; diff --git a/wolfcrypt/src/aes.c b/wolfcrypt/src/aes.c index 7217c7f871b..79e55db50ee 100644 --- a/wolfcrypt/src/aes.c +++ b/wolfcrypt/src/aes.c @@ -69,10 +69,12 @@ block cipher mechanism that uses n-bit binary string parameter key with 128-bits #if defined(WOLFSSL_SE050) && defined(WOLFSSL_SE050_CRYPT) #include #endif - -#if defined(WOLFSSL_AES_SIV) +#ifdef WOLFSSL_MICROCHIP_TA100 + #include +#endif +#ifdef WOLFSSL_AES_SIV #include -#endif /* WOLFSSL_AES_SIV */ +#endif #if defined(WOLFSSL_HAVE_PSA) && !defined(WOLFSSL_PSA_NO_AES) #include @@ -5108,7 +5110,18 @@ static void AesSetKey_C(Aes* aes, const byte* key, word32 keySz, int dir) return ret; } #endif - +#if defined(WOLFSSL_MICROCHIP_TA100) && defined(WOLFSSL_MICROCHIP_AESGCM) + if (keylen == TA_KEY_TYPE_AES128_SIZE) { + ret = wc_Microchip_aes_set_key(aes, userKey, keylen, iv, dir); + if (ret != 0) { + return ret; + } + ret = wc_AesSetIV(aes, iv); + if (ret != 0) { + return ret; + } + } +#endif XMEMCPY(aes->key, userKey, keylen); #ifndef WC_AES_BITSLICED @@ -9895,7 +9908,22 @@ int wc_AesGcmEncrypt(Aes* aes, byte* out, const byte* in, word32 sz, authTag, authTagSz, authIn, authInSz); #endif - +#if defined(WOLFSSL_MICROCHIP_TA100) && defined(WOLFSSL_MICROCHIP_AESGCM) +#ifndef TA_AES_GCM_MAX_DATA_SIZE + #define TA_AES_GCM_MAX_DATA_SIZE 996u +#endif + if (aes != NULL && + aes->keylen == TA_KEY_TYPE_AES128_SIZE && + ivSz == TA_AES_GCM_IV_LENGTH && + authTagSz == TA_AES_GCM_TAG_LENGTH && + (authInSz + sz) <= TA_AES_GCM_MAX_DATA_SIZE) { + return wc_Microchip_AesGcmEncrypt( + aes, out, in, sz, + iv, ivSz, + authTag, authTagSz, + authIn, authInSz); + } +#endif #ifdef STM32_CRYPTO_AES_GCM return wc_AesGcmEncrypt_STM32( aes, out, in, sz, iv, ivSz, @@ -10620,6 +10648,20 @@ int wc_AesGcmDecrypt(Aes* aes, byte* out, const byte* in, word32 sz, authTag, authTagSz, authIn, authInSz); #endif +#if defined(WOLFSSL_MICROCHIP_TA100) && defined(WOLFSSL_MICROCHIP_AESGCM) +#ifndef TA_AES_GCM_MAX_DATA_SIZE + #define TA_AES_GCM_MAX_DATA_SIZE 996u +#endif + if (aes != NULL && + aes->keylen == TA_KEY_TYPE_AES128_SIZE && + ivSz == TA_AES_GCM_IV_LENGTH && + authTagSz == TA_AES_GCM_TAG_LENGTH && + (authInSz + sz) <= TA_AES_GCM_MAX_DATA_SIZE) { + return wc_Microchip_AesGcmDecrypt( + aes, out, in, sz, iv, ivSz, + authTag, authTagSz, authIn, authInSz); + } +#endif #ifdef STM32_CRYPTO_AES_GCM /* The STM standard peripheral library API's doesn't support partial blocks */ @@ -13519,7 +13561,9 @@ void wc_AesFree(Aes* aes) se050_aes_free(aes); } #endif - +#if defined(WOLFSSL_MICROCHIP_TA100) && defined(WOLFSSL_MICROCHIP_AESGCM) + wc_Microchip_aes_free(aes); +#endif #if defined(WOLFSSL_HAVE_PSA) && !defined(WOLFSSL_PSA_NO_AES) wc_psa_aes_free(aes); #endif diff --git a/wolfcrypt/src/ecc.c b/wolfcrypt/src/ecc.c index c34e140d6bc..4149e8b70a6 100644 --- a/wolfcrypt/src/ecc.c +++ b/wolfcrypt/src/ecc.c @@ -230,15 +230,16 @@ ECC Curve Sizes: #endif #if !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_ATECC608A) && \ + !defined(WOLFSSL_MICROCHIP_TA100) && \ !defined(WOLFSSL_CRYPTOCELL) && !defined(WOLFSSL_SILABS_SE_ACCEL) && \ !defined(WOLFSSL_KCAPI_ECC) && !defined(WOLFSSL_SE050) && \ - !defined(WOLFSSL_XILINX_CRYPT_VERSAL) && !defined(WOLFSSL_STM32_PKA) && \ - !defined(WOLFSSL_PSOC6_CRYPTO) + !defined(WOLFSSL_XILINX_CRYPT_VERSAL) #undef HAVE_ECC_VERIFY_HELPER #define HAVE_ECC_VERIFY_HELPER #endif #if !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_ATECC608A) && \ + !defined(WOLFSSL_MICROCHIP_TA100) && \ !defined(WOLFSSL_CRYPTOCELL) && !defined(WOLFSSL_SILABS_SE_ACCEL) && \ !defined(WOLFSSL_KCAPI_ECC) && !defined(NO_ECC_MAKE_PUB) && \ !defined(WOLF_CRYPTO_CB_ONLY_ECC) @@ -251,6 +252,7 @@ ECC Curve Sizes: #if (!defined(NO_ECC_CHECK_PUBKEY_ORDER) && \ !defined(WOLF_CRYPTO_CB_ONLY_ECC) && \ !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_ATECC608A) && \ + !defined(WOLFSSL_MICROCHIP_TA100) && \ !defined(WOLFSSL_CRYPTOCELL) && !defined(WOLFSSL_SILABS_SE_ACCEL) && \ !defined(WOLFSSL_SE050) && !defined(WOLFSSL_STM32_PKA)) || \ defined(WOLFSSL_IMXRT1170_CAAM) || defined(WOLFSSL_QNX_CAAM) @@ -4660,7 +4662,7 @@ int wc_ecc_shared_secret(ecc_key* private_key, ecc_key* public_key, byte* out, int err = 0; #if defined(WOLFSSL_CRYPTOCELL) && !defined(WOLFSSL_ATECC508A) && \ - !defined(WOLFSSL_ATECC608A) + !defined(WOLFSSL_ATECC608A) && !defined(WOLFSSL_MICROCHIP_TA100) CRYS_ECDH_TempData_t tempBuff; #endif @@ -4703,9 +4705,11 @@ int wc_ecc_shared_secret(ecc_key* private_key, ecc_key* public_key, byte* out, return ECC_BAD_ARG_E; } -#if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A) +#if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A) || \ + defined(WOLFSSL_MICROCHIP_TA100) /* For SECP256R1 use hardware */ - if (private_key->dp->id == ECC_SECP256R1) { + if (private_key->dp->id == ECC_SECP256R1 && + private_key->slot != ATECC_INVALID_SLOT) { err = atmel_ecc_create_pms(private_key->slot, public_key->pubkey_raw, out); *outlen = private_key->dp->size; } @@ -4741,6 +4745,7 @@ int wc_ecc_shared_secret(ecc_key* private_key, ecc_key* public_key, byte* out, #if !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_ATECC608A) && \ + !defined(WOLFSSL_MICROCHIP_TA100) && \ !defined(WOLFSSL_CRYPTOCELL) && !defined(WOLFSSL_KCAPI_ECC) && \ !defined(WOLF_CRYPTO_CB_ONLY_ECC) @@ -5253,6 +5258,7 @@ int wc_ecc_point_is_on_curve(ecc_point *p, int curve_idx) #endif /* USE_ECC_B_PARAM */ #if !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_ATECC608A) && \ + !defined(WOLFSSL_MICROCHIP_TA100) && \ !defined(WOLFSSL_CRYPTOCELL) && \ (!defined(WOLF_CRYPTO_CB_ONLY_ECC) || defined(WOLFSSL_QNX_CAAM) || \ defined(WOLFSSL_IMXRT1170_CAAM)) @@ -5611,12 +5617,28 @@ int wc_ecc_make_pub_ex(ecc_key* key, ecc_point* pubOut, WC_RNG* rng) return err; } +#if defined(WOLFSSL_MICROCHIP_TA100) +static WC_INLINE int ta100_curve_id_for_key(const ecc_key* key) +{ + if (key != NULL && key->dp != NULL) { + switch (key->dp->size) { + case 28: return ECC_SECP224R1; + case 32: return ECC_SECP256R1; + case 48: return ECC_SECP384R1; + default: return key->dp->id; + } + } + return ECC_CURVE_DEF; +} +#endif + static int _ecc_make_key_ex(WC_RNG* rng, int keysize, ecc_key* key, int curve_id, int flags) { int err = 0; #if defined(WOLFSSL_CRYPTOCELL) && !defined(WOLFSSL_ATECC508A) && \ + !defined(WOLFSSL_MICROCHIP_TA100) && \ !defined(WOLFSSL_ATECC608A) const CRYS_ECPKI_Domain_t* pDomain; CRYS_ECPKI_KG_TempData_t tempBuff; @@ -5697,11 +5719,26 @@ static int _ecc_make_key_ex(WC_RNG* rng, int keysize, ecc_key* key, } #endif /* WOLFSSL_ASYNC_CRYPT && WC_ASYNC_ENABLE_ECC */ -#if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A) - if (key->dp->id == ECC_SECP256R1) { +#if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A) || \ + defined(WOLFSSL_MICROCHIP_TA100) +#if !defined(WOLFSSL_MICROCHIP_TA100) + if (key->dp->id == ECC_SECP256R1 || + key->dp->id == ECC_SECP224R1 || + key->dp->id == ECC_SECP384R1 || + key->dp->id == ECC_SECP256K1 || + key->dp->id == ECC_BRAINPOOLP256R1) { /* supports more than ECC256R1 curve */ +#else + if (key->dp->id == ECC_SECP256R1 || + key->dp->id == ECC_SECP224R1 || + key->dp->id == ECC_SECP384R1 || + key->dp->id == ECC_SECP256K1 || + key->dp->id == ECC_BRAINPOOLP256R1) { +#endif key->type = ECC_PRIVATEKEY; - key->slot = atmel_ecc_alloc(ATMEL_SLOT_ECDHE); - err = atmel_ecc_create_key(key->slot, key->pubkey_raw); + if (key->slot == ATECC_INVALID_SLOT) + key->slot = atmel_ecc_alloc(ATMEL_SLOT_ECDHE); + err = atmel_ecc_create_key(key->slot, ta100_curve_id_for_key(key), + key->pubkey_raw); /* populate key->pubkey */ if (err == 0 @@ -5710,7 +5747,7 @@ static int _ecc_make_key_ex(WC_RNG* rng, int keysize, ecc_key* key, #endif ) { err = mp_read_unsigned_bin(key->pubkey.x, key->pubkey_raw, - ECC_MAX_CRYPTO_HW_SIZE); + (word32)key->dp->size); } if (err == 0 #ifdef ALT_ECC_SIZE @@ -5718,8 +5755,8 @@ static int _ecc_make_key_ex(WC_RNG* rng, int keysize, ecc_key* key, #endif ) { err = mp_read_unsigned_bin(key->pubkey.y, - key->pubkey_raw + ECC_MAX_CRYPTO_HW_SIZE, - ECC_MAX_CRYPTO_HW_SIZE); + key->pubkey_raw + key->dp->size, + (word32)key->dp->size); } } else { @@ -6191,8 +6228,17 @@ int wc_ecc_init_ex(ecc_key* key, void* heap, int devId) (void)devId; #endif -#if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A) +#if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A) || \ + defined(WOLFSSL_MICROCHIP_TA100) key->slot = ATECC_INVALID_SLOT; +#ifdef WOLFSSL_MICROCHIP_TA100 + /* TA100 needs pubkey initialized to populate after genkey */ + ret = mp_init_multi(key->pubkey.x, key->pubkey.y, key->pubkey.z, + NULL, NULL, NULL); + if (ret != MP_OKAY) { + return MEMORY_E; + } +#endif #else #if defined(WOLFSSL_KCAPI_ECC) key->handle = NULL; @@ -6387,6 +6433,7 @@ static int wc_ecc_get_curve_order_bit_count(const ecc_set_type* dp) #ifdef HAVE_ECC_SIGN #if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A) || \ + defined(WOLFSSL_MICROCHIP_TA100) || \ defined(PLUTON_CRYPTO_ECC) || defined(WOLFSSL_CRYPTOCELL) || \ defined(WOLFSSL_SILABS_SE_ACCEL) || defined(WOLFSSL_KCAPI_ECC) || \ defined(WOLFSSL_SE050) || defined(WOLFSSL_XILINX_CRYPT_VERSAL) @@ -6400,7 +6447,7 @@ static int wc_ecc_sign_hash_hw(const byte* in, word32 inlen, #endif { #if defined(WOLFSSL_CRYPTOCELL) && !defined(WOLFSSL_ATECC508A) && \ - !defined(WOLFSSL_ATECC608A) + !defined(WOLFSSL_ATECC608A) && !defined(WOLFSSL_MICROCHIP_TA100) CRYS_ECDSA_SignUserContext_t sigCtxTemp; word32 raw_sig_size = *outlen; word32 msgLenInBytes = inlen; @@ -6431,9 +6478,25 @@ static int wc_ecc_sign_hash_hw(const byte* in, word32 inlen, } #endif - #if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A) + #if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A) || \ + defined(WOLFSSL_MICROCHIP_TA100) +#if defined(WOLFSSL_MICROCHIP_TA100) + if (ta100_curve_id_for_key(key) == ECC_SECP256R1) { + (void)inlen; + /* Sign: Result is 32-bytes of R then 32-bytes of S */ + err = atmel_ecc_sign(key->slot, in, out); + } + else { + /* Sign: Result is raw R||S */ + err = atmel_ecc_sign_ex(key->slot, ta100_curve_id_for_key(key), + in, inlen, out); + } +#else + (void)inlen; /* Sign: Result is 32-bytes of R then 32-bytes of S */ err = atmel_ecc_sign(key->slot, in, out); +#endif + if (err != 0) { return err; } @@ -6781,6 +6844,7 @@ int wc_ecc_sign_hash(const byte* in, word32 inlen, byte* out, word32 *outlen, /* hardware crypto */ #if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A) || \ + defined(WOLFSSL_MICROCHIP_TA100) || \ defined(PLUTON_CRYPTO_ECC) || defined(WOLFSSL_CRYPTOCELL) || \ defined(WOLFSSL_SILABS_SE_ACCEL) || defined(WOLFSSL_KCAPI_ECC) || \ defined(WOLFSSL_SE050) || defined(WOLFSSL_XILINX_CRYPT_VERSAL) @@ -6902,6 +6966,7 @@ int wc_ecc_sign_hash_ex(const byte* in, word32 inlen, WC_RNG* rng, return stm32_ecc_sign_hash_ex(in, inlen, rng, key, r, s); } #elif !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_ATECC608A) && \ + !defined(WOLFSSL_MICROCHIP_TA100) && \ !defined(WOLFSSL_CRYPTOCELL) && !defined(WOLFSSL_KCAPI_ECC) #ifndef WOLFSSL_SP_MATH static int ecc_sign_hash_sw(ecc_key* key, ecc_key* pubkey, WC_RNG* rng, @@ -7928,7 +7993,8 @@ int wc_ecc_free(ecc_key* key) se050_ecc_free_key(key); #endif -#if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A) +#if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A) || \ + defined(WOLFSSL_MICROCHIP_TA100) atmel_ecc_free(key->slot); key->slot = ATECC_INVALID_SLOT; #endif /* WOLFSSL_ATECC508A */ @@ -7982,7 +8048,6 @@ int wc_ecc_free(ecc_key* key) !defined(WOLFSSL_CRYPTOCELL) && !defined(WOLFSSL_SP_MATH) && \ (!defined(WOLF_CRYPTO_CB_ONLY_ECC) || defined(WOLFSSL_QNX_CAAM) || \ defined(WOLFSSL_IMXRT1170_CAAM)) - /* Handles add failure cases: * * Before add: @@ -8103,7 +8168,8 @@ int ecc_projective_dbl_point_safe(ecc_point *P, ecc_point *R, mp_int* a, */ #if !defined(WOLFSSL_SP_MATH) && !defined(WOLFSSL_ATECC508A) && \ - !defined(WOLFSSL_ATECC608A) && !defined(WOLFSSL_CRYPTOCELL) && \ + !defined(WOLFSSL_ATECC608A) && !defined(WOLFSSL_MICROCHIP_TA100) && \ + !defined(WOLFSSL_CRYPTOCELL) && \ !defined(WOLFSSL_KCAPI_ECC) && !defined(WOLF_CRYPTO_CB_ONLY_ECC) #ifdef ECC_SHAMIR @@ -8696,7 +8762,7 @@ static int wc_ecc_check_r_s_range(ecc_key* key, mp_int* r, mp_int* s) } #endif /* !WOLFSSL_STM32_PKA && !WOLFSSL_PSOC6_CRYPTO */ -#ifdef HAVE_ECC_VERIFY_HELPER +#if defined(HAVE_ECC_VERIFY_HELPER) && !defined(WOLFSSL_MICROCHIP) static int ecc_verify_hash_sp(mp_int *r, mp_int *s, const byte* hash, word32 hashlen, int* res, ecc_key* key) { @@ -8854,7 +8920,7 @@ static int ecc_verify_hash_sp(mp_int *r, mp_int *s, const byte* hash, return NOT_COMPILED_IN; } -#if !defined(WOLFSSL_SP_MATH) || defined(FREESCALE_LTC_ECC) +#if !defined(WOLFSSL_MICROCHIP) && (!defined(WOLFSSL_SP_MATH) || defined(FREESCALE_LTC_ECC)) static int ecc_verify_hash(mp_int *r, mp_int *s, const byte* hash, word32 hashlen, int* res, ecc_key* key, ecc_curve_spec* curve) { @@ -9187,7 +9253,8 @@ int wc_ecc_verify_hash_ex(mp_int *r, mp_int *s, const byte* hash, #else int err; word32 keySz = 0; -#if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A) +#if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A) || \ + defined(WOLFSSL_MICROCHIP_TA100) byte sigRS[ATECC_KEY_SIZE*2]; #elif defined(WOLFSSL_CRYPTOCELL) byte sigRS[ECC_MAX_CRYPTO_HW_SIZE*2]; @@ -9259,7 +9326,22 @@ int wc_ecc_verify_hash_ex(mp_int *r, mp_int *s, const byte* hash, } #endif /* WOLFSSL_SE050 */ -#if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A) +#if defined(WOLFSSL_MICROCHIP_TA100) + if (ta100_curve_id_for_key(key) == ECC_SECP256R1) { + err = atmel_ecc_verify(hash, sigRS, key->pubkey_raw, res); + if (err != 0) { + return err; + } + (void)hashlen; + } + else { + err = atmel_ecc_verify_ex(hash, hashlen, sigRS, key->pubkey_raw, + keySz * 2, ta100_curve_id_for_key(key), res); + if (err != 0) { + return err; + } + } +#elif defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A) err = atmel_ecc_verify(hash, sigRS, key->pubkey_raw, res); if (err != 0) { return err; @@ -10213,14 +10295,16 @@ static int ecc_check_privkey_gen(ecc_key* key, mp_int* a, mp_int* prime) static int ecc_check_privkey_gen_helper(ecc_key* key) { int err; -#if !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_ATECC608A) +#if !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_ATECC608A) && \ + !defined(WOLFSSL_MICROCHIP_TA100) DECLARE_CURVE_SPECS(2); #endif if (key == NULL) return BAD_FUNC_ARG; -#if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A) +#if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A) || \ + defined(WOLFSSL_MICROCHIP_TA100) /* Hardware based private key, so this operation is not supported */ err = MP_OKAY; /* just report success */ #elif defined(WOLFSSL_SILABS_SE_ACCEL) @@ -10431,7 +10515,7 @@ int wc_ecc_get_generator(ecc_point* ecp, int curve_idx) static int _ecc_validate_public_key(ecc_key* key, int partial, int priv) { int err = MP_OKAY; -#if defined(HAVE_ECC_CHECK_PUBKEY_ORDER) && !defined(WOLFSSL_SP_MATH) +#if defined(HAVE_ECC_CHECK_PUBKEY_ORDER) && !defined(WOLFSSL_SP_MATH) mp_int* b = NULL; #ifdef USE_ECC_B_PARAM DECLARE_CURVE_SPECS(4); @@ -10712,7 +10796,8 @@ int wc_ecc_import_x963_ex(const byte* in, word32 inLen, ecc_key* key, inLen -= 1; in += 1; -#if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A) +#if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A) || \ + defined(WOLFSSL_MICROCHIP_TA100) /* For SECP256R1 only save raw public key for hardware */ if (curve_id == ECC_SECP256R1 && inLen <= (word32)sizeof(key->pubkey_raw)) { #ifdef HAVE_COMP_KEY @@ -10974,7 +11059,8 @@ int wc_ecc_export_ex(ecc_key* key, byte* qx, word32* qxLen, (key->type != ECC_PRIVATEKEY && key->type != ECC_PRIVATEKEY_ONLY)) return BAD_FUNC_ARG; - #if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A) + #if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A) || \ + defined(WOLFSSL_MICROCHIP_TA100) /* Hardware cannot export private portion */ return NOT_COMPILED_IN; #else @@ -11417,14 +11503,14 @@ static int wc_ecc_import_raw_private(ecc_key* key, const char* qx, { int err = MP_OKAY; #if defined(WOLFSSL_CRYPTOCELL) && !defined(WOLFSSL_ATECC508A) && \ - !defined(WOLFSSL_ATECC608A) + !defined(WOLFSSL_ATECC608A) && !defined(WOLFSSL_MICROCHIP_TA100) const CRYS_ECPKI_Domain_t* pDomain; CRYS_ECPKI_BUILD_TempData_t tempBuff; byte keyRaw[ECC_MAX_CRYPTO_HW_SIZE*2 + 1]; #endif #if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A) || \ - defined(WOLFSSL_CRYPTOCELL) + defined(WOLFSSL_MICROCHIP_TA100) || defined(WOLFSSL_CRYPTOCELL) word32 keySz = 0; #endif @@ -11519,7 +11605,8 @@ static int wc_ecc_import_raw_private(ecc_key* key, const char* qx, if (err == MP_OKAY) err = mp_set(key->pubkey.z, 1); -#if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A) +#if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A) || \ + defined(WOLFSSL_MICROCHIP_TA100) /* For SECP256R1 only save raw public key for hardware */ if (err == MP_OKAY && curve_id == ECC_SECP256R1) { keySz = key->dp->size; @@ -11604,7 +11691,8 @@ static int wc_ecc_import_raw_private(ecc_key* key, const char* qx, /* import private key */ if (err == MP_OKAY) { if (d != NULL) { - #if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A) + #if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A) || \ + defined(WOLFSSL_MICROCHIP_TA100) /* Hardware doesn't support loading private key */ err = NOT_COMPILED_IN; @@ -11672,9 +11760,11 @@ static int wc_ecc_import_raw_private(ecc_key* key, const char* qx, #endif #endif /* #else-case of custom HW-specific implementations */ - if (mp_iszero(key->k) || mp_isneg(key->k)) { - WOLFSSL_MSG("Invalid private key"); - err = BAD_FUNC_ARG; + if (err == MP_OKAY) { + if (mp_iszero(key->k) || mp_isneg(key->k)) { + WOLFSSL_MSG("Invalid private key"); + err = BAD_FUNC_ARG; + } } } else { key->type = ECC_PUBLICKEY; @@ -14866,6 +14956,7 @@ int wc_ecc_decrypt(ecc_key* privKey, ecc_key* pubKey, const byte* msg, #ifdef HAVE_COMP_KEY #if !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_ATECC608A) && \ + !defined(WOLFSSL_MICROCHIP_TA100) && \ !defined(WOLFSSL_CRYPTOCELL) #ifndef WOLFSSL_SP_MATH diff --git a/wolfcrypt/src/port/atmel/README.md b/wolfcrypt/src/port/atmel/README.md index 01b11a040dc..5418e116b2b 100644 --- a/wolfcrypt/src/port/atmel/README.md +++ b/wolfcrypt/src/port/atmel/README.md @@ -96,5 +96,105 @@ ATECC508A HW accelerated implementation: `EC-DSA sign time 293.400 milliseconds, avg over 5 iterations, 17.065 ops/sec` `EC-DSA verify time 208.400 milliseconds, avg over 5 iterations, 24.038 ops/sec` +### Microchip Trust Anchor TA100 ECC/RSA + +## TA100 Support Notes + +The TA100 integration uses Microchip CryptoAuthLib TALIB APIs and supports +ECC P-256 and RSA (2048 or 3072 depending on build options). This port is +built against CryptoAuthLib v3.6.0. TA100 uses +device handles rather than ATECC slot addresses; wolfSSL maps ECC slots to +TA100 handles internally and uses a dedicated symmetric key handle for AES-GCM. + +Key points: +* TA100 support is enabled via `WOLFSSL_MICROCHIP_TA100` and CryptoAuthLib + must be built with TA100 support enabled (`ATCA_TA100_SUPPORT`). +* RSA key size selection uses `WOLFSSL_SP_NO_2048` / `WOLFSSL_SP_NO_3072` + to choose `WOLFSSL_TA_KEY_TYPE_RSA` and `WOLFSSL_TA_KEY_TYPE_RSA_SIZE`. +* AES-GCM support requires `WOLFSSL_MICROCHIP_AESGCM` and CryptoAuthLib + TA100 AES-GCM support (`ATCA_TA100_AES_AUTH_SUPPORT`). + +### TA100 Auto-Lock Option + +By default, wolfSSL does **not** lock the TA100 setup/data zone when setting +an AES key. If you want to lock the setup/data zone automatically after the +AES key is loaded, define: + +`WOLFSSL_TA100_AUTO_LOCK=1` + +This gates the call to `talib_lock_setup()` inside +`wc_Microchip_aes_set_key()` in `wolfcrypt/src/port/atmel/atmel.c`. +Because locking is a one-way operation on real hardware, this option is +disabled by default and should only be enabled in a controlled provisioning +flow. + +rm -rf build-shared +cmake -S . -B build-shared \ + -DCMAKE_BUILD_TYPE=Debug \ + -DATCA_BUILD_SHARED_LIBS=ON \ + -DATCA_HAL_SPI=ON \ + -DATCA_PRINTF=ON \ + -DATCA_TA100_SUPPORT=ON \ + -DATCA_TA100_AES_AUTH_SUPPORT=ON \ + -DATCA_TA100_FCE_SUPPORT=ON \ + -DATCA_WOLFSSL=ON \ + -DBUILD_TESTS=ON +cmake --build build-shared -j +sudo cmake --install build-shared +sudo ldconfig + +`./configure CFLAGS="-DWOLFSSL_CMAC -DHAVE_PK_CALLBACKS -DWOLFSSL_ATECC508A_NOIDLE -DECC_USER_CURVES -DWOLFSSL_ATECC_NO_ECDH_ENC -DWOLFSSL_ATECC_DEBUG" --enable-cmac --enable-microchip=100 --with-cryptoauthlib` + +Supported Features: +RSA 2048 keygen/sign/verify +ECC-P256 keygen/sign/verify/shared secret + +WOLFSSL_MICROCHIP_AESGCM can be used to enable AES-GCM but +AESGCM support is not yet available for TA100 in both +cryptauthlib-v3.3.3_397871.zip and cryptauthlib-v3.6.0_443271.zip. + + +``` + $ lscpu -e +CPU SOCKET CORE L1d:L1i:L2 ONLINE MAXMHZ MINMHZ + 0 0 0 0:0:0 yes 1800.0000 600.0000 + 1 0 1 1:1:0 yes 1800.0000 600.0000 + 2 0 2 2:2:0 yes 1800.0000 600.0000 + 3 0 3 3:3:0 yes 1800.0000 600.0000 + +$ uname -a +Linux raspberrypi 6.1.21-v8+ #1642 SMP PREEMPT Mon Apr 3 17:24:16 BST 2023 aarch64 GNU/Linux + +Software: +------------------------------------------------------------------------------ + wolfSSL version 5.6.0 +------------------------------------------------------------------------------ +Math: Multi-Precision: Wolf(SP) word-size=64 bits=4096 sp_int.c +wolfCrypt Benchmark (block bytes 1048576, min 1.0 sec each) +Benchmarks: + +RSA 2048 key gen 2 ops took 1.113 sec, avg 556.332 ms, 1.797 ops/sec +RSA 2048 sign 200 ops took 1.891 sec, avg 9.455 ms, 105.766 ops/sec +RSA 2048 verify 6900 ops took 1.011 sec, avg 0.147 ms, 6824.614 ops/sec + +ECC [ SECP256R1] 256 key gen 700 ops took 1.065 sec, avg 1.522 ms, 657.067 ops/sec +ECDHE [ SECP256R1] 256 agree 700 ops took 1.016 sec, avg 1.451 ms, 689.240 ops/sec +ECDSA [ SECP256R1] 256 sign 700 ops took 1.049 sec, avg 1.499 ms, 667.097 ops/sec +ECDSA [ SECP256R1] 256 verify 1000 ops took 1.001 sec, avg 1.001 ms, 998.930 ops/sec + + +Hardware Microchip TA100 with SPI: + +Benchmarks: +RSA 2048 key gen HW 1 ops took 12.190 sec, avg 12190.346 ms, 0.082 ops/sec +RSA 2048 sign HW 100 ops took 14.006 sec, avg 140.062 ms, 7.140 ops/sec +RSA 2048 verify HW 100 ops took 13.168 sec, avg 131.679 ms, 7.594 ops/sec + +ECC [ SECP256R1] 256 key gen 100 ops took 6.790 sec, avg 67.898 ms, 14.728 ops/sec +ECDHE [ SECP256R1] 256 agree 100 ops took 2.413 sec, avg 24.126 ms, 41.449 ops/sec +ECDSA [ SECP256R1] 256 sign 100 ops took 1.832 sec, avg 18.317 ms, 54.594 ops/sec +ECDSA [ SECP256R1] 256 verify 100 ops took 2.120 sec, avg 21.198 ms, 47.175 ops/sec + +``` For details see our [wolfSSL Atmel ATECC508/608A](https://wolfssl.com/wolfSSL/wolfssl-atmel.html) page. diff --git a/wolfcrypt/src/port/atmel/atmel.c b/wolfcrypt/src/port/atmel/atmel.c index 386a8f49837..204fdd05a43 100644 --- a/wolfcrypt/src/port/atmel/atmel.c +++ b/wolfcrypt/src/port/atmel/atmel.c @@ -25,8 +25,16 @@ #include +/* + * WOLFSSL_MANUALLY_SELECT_DEVICE_CONFIG default: off (not defined) + You can define this in a user_settings.h file to specify your custom + configuration of a device + * WOLFSSL_ATCA_DEVICE_NO use first device in the list default: 0 + */ + #if defined(WOLFSSL_ATMEL) || defined(WOLFSSL_ATECC508A) || \ - defined(WOLFSSL_ATECC608A) || defined(WOLFSSL_ATECC_PKCB) + defined(WOLFSSL_ATECC608A) || defined(WOLFSSL_ATECC_PKCB) || \ + defined(WOLFSSL_MICROCHIP_TA100) #include #include @@ -61,7 +69,8 @@ #include -#if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A) +#if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A) || \ + defined(WOLFSSL_MICROCHIP_TA100) #ifdef WOLFSSL_ATECC508A_TLS extern ATCA_STATUS device_init_default(void); @@ -88,15 +97,165 @@ static wolfSSL_Mutex mSlotMutex; #ifndef ATECC_I2C_BUS #define ATECC_I2C_BUS 1 #endif -#ifndef ATECC_DEV_TYPE +#ifdef ATECC_DEV_TYPE /* for backward compatibility */ + #define MICROCHIP_DEV_TYPE ATECC_DEV_TYPE +#endif +#ifndef MICROCHIP_DEV_TYPE #ifdef WOLFSSL_ATECC508A - #define ATECC_DEV_TYPE ATECC508A - #else - #define ATECC_DEV_TYPE ATECC608A + #define MICROCHIP_DEV_TYPE ATECC508A + #elif defined(WOLFSSL_ATECC608A) + #define MICROCHIP_DEV_TYPE ATECC608A + #elif defined(WOLFSSL_MICROCHIP_TA100) + #define MICROCHIP_DEV_TYPE TA100 #endif #endif static int ateccx08a_cfg_initialized = 0; -static ATCAIfaceCfg cfg_ateccx08a_i2c_pi; + +#if defined(WOLFSSL_ATECC608A) && defined(MICROCHIP_MPLAB_HARMONY_3) + /* Harmony3 will generate configuration based on user inputs */ + extern ATCAIfaceCfg atecc608_0_init_data; +#endif + +#ifndef WOLFSSL_ATCA_DEVICE_NO + /* Default to first device in the list*/ + #define WOLFSSL_ATCA_DEVICE_NO 0 +#endif + static ATCAIfaceCfg config_atmel_device[] = { + /* Enable and Select user configuration of device and parameters. */ +#if defined(WOLFSSL_MANUALLY_SELECT_DEVICE_CONFIG) + WOLFSSL_MANUALLY_SELECT_DEVICE_CONFIG, + /* Try detecting all available device configs */ +#elif defined(WOLFSSL_ATECC608A) && defined(MICROCHIP_MPLAB_HARMONY_3) + atecc608_0_init_data, +#endif +#ifdef ATCA_HAL_SPI + { + .iface_type = ATCA_SPI_IFACE, + .devtype = MICROCHIP_DEV_TYPE, + .atcaspi = { + .bus = 0, + .select_pin = 0, + .baud = 16000000, + }, + .wake_delay = 1500, + .rx_retries = 20, + }, +#endif +#ifdef ATCA_HAL_I2C + { + .iface_type = ATCA_I2C_IFACE, + .devtype = MICROCHIP_DEV_TYPE, + .atcai2c = { + #ifdef ATCA_ENABLE_DEPRECATED + .slave_addressus = 1, + #else + .address = ATECC_I2C_ADDR, + #endif + .baud = 400000, + }, + .wake_delay = 1500, + .rx_retries = 20, + }, +#endif +}; +static ATCAIfaceCfg* gCfg = &config_atmel_device[WOLFSSL_ATCA_DEVICE_NO]; + +#if defined(WOLFSSL_MICROCHIP_TA100) + + + /* TA100 device expects little-endian data for the property field. + * On big-endian hosts, we need to byte-swap the uint16_t property value. + * Use ATCA_UINT16_HOST_TO_LE if available from cryptoauthlib, otherwise + * define our own based on wolfSSL's endianness detection. + */ + #ifndef ATCA_UINT16_HOST_TO_LE + #ifdef BIG_ENDIAN_ORDER + #define ATCA_UINT16_HOST_TO_LE(x) \ + ((uint16_t)(((x) >> 8) | (((x) & 0xFF) << 8))) + #else + #define ATCA_UINT16_HOST_TO_LE(x) (x) + #endif + #endif + + /* Helper function to fix property field endianness after talib_handle_init_* + * functions populate the ta_element_attributes_t structure. + * The talib functions build the property value in host byte order, but + * the TA100 device expects little-endian format. + */ + static WC_INLINE void ta100_fix_property_endian(ta_element_attributes_t* attr) + { + #ifdef BIG_ENDIAN_ORDER + if (attr != NULL) { + attr->property = ATCA_UINT16_HOST_TO_LE(attr->property); + } + #else + (void)attr; /* Suppress unused warning on little-endian */ + #endif + } + + /* The sharedData_attr property values need to be in LE format. + * On little-endian: 0x1600 stays as 0x1600 (bytes: 00 16) + * On big-endian: 0x1600 becomes 0x0016 (bytes: 00 16) + * + * Since we cannot use function calls in static initializers, + * we define the values directly for each endianness: + */ + #ifdef BIG_ENDIAN_ORDER + /* Big-endian: swap bytes so wire format is correct */ + #define TA100_PROP_SHARED_DATA 0x0016 + #else + /* Little-endian: use value as-is */ + #define TA100_PROP_SHARED_DATA 0x1600 + #endif + #ifndef SHARED_DATA_ADDR + #define SHARED_DATA_ADDR 0x8006 + #endif + /* ECC key handles must not overlap shared-data handles. */ + #ifndef TA100_ECC_HANDLE_BASE + #define TA100_ECC_HANDLE_BASE 0x9000 + #endif + #define MAP_TO_HANDLE(value) (TA100_ECC_HANDLE_BASE + (value)) + /* TA100 uses separate handle range for symmetric keys (AES/HMAC) */ + #ifndef TA100_AES_HANDLE + #define TA100_AES_HANDLE 0x8106 + #endif +#else + #define MAP_TO_HANDLE(value) value +#endif + +#if defined(WOLFSSL_MICROCHIP_TA100) +/* +TA_ElementAttributes contains data element attributes of the handle +which is of 8 byte + +typedef struct +{ + uint8_t element_CKA; //!< contains class, key_type & Algorithm mode + uint16_t property; //!< properties of the element + uint8_t usage_key; //!< usage key + uint8_t write_key; //!< write key + uint8_t read_key; //!< read key + uint8_t permission; //!< permission of the element usage|write|read| + //delete perm + uint8_t byte7_settings; //!< Byte 7 attributes use_count|exportable| + // lockable|access_limit +} ATCA_PACKED ta_element_attributes_t; + +See Shared Data Element Attributes in the programming specifications +*/ +static ta_element_attributes_t sharedData_attr[ATECC_MAX_SLOT] = { + {0x81, TA100_PROP_SHARED_DATA, 0x00, 0x00, 0x00, 0x41, 0x10}, + {0x81, TA100_PROP_SHARED_DATA, 0x00, 0x00, 0x00, 0x41, 0x10}, + {0x81, TA100_PROP_SHARED_DATA, 0x00, 0x00, 0x00, 0x41, 0x10}, + {0x81, TA100_PROP_SHARED_DATA, 0x00, 0x00, 0x00, 0x41, 0x10}, + {0x81, TA100_PROP_SHARED_DATA, 0x00, 0x00, 0x00, 0x41, 0x10}, + {0x81, TA100_PROP_SHARED_DATA, 0x00, 0x00, 0x00, 0x41, 0x10}, + {0x81, TA100_PROP_SHARED_DATA, 0x00, 0x00, 0x00, 0x41, 0x10}, + {0x81, TA100_PROP_SHARED_DATA, 0x00, 0x00, 0x00, 0x41, 0x10}, +}; +static ta_element_attributes_t* gSharedDataAttr = sharedData_attr; + +#endif /* WOLFSSL_MICROCHIP_TA100 */ #endif /* WOLFSSL_ATECC508A */ /** @@ -105,7 +264,8 @@ static ATCAIfaceCfg cfg_ateccx08a_i2c_pi; int atmel_get_random_number(uint32_t count, uint8_t* rand_out) { int ret = 0; -#if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A) +#if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A) || \ + defined(WOLFSSL_MICROCHIP_TA100) uint8_t i = 0; uint32_t copy_count = 0; uint8_t rng_buffer[RANDOM_NUM_SIZE]; @@ -180,8 +340,28 @@ long atmel_get_curr_time_and_date(long* tm) } #endif +#if defined(WOLFSSL_MICROCHIP_TA100) +/* Set the Shared Data configuration for wolfSSL to use. + * + * Return 0 on success, negative upon error */ +int wc_Microchip_SetSharedDataConfig(ta_element_attributes_t* cfg) +{ + WOLFSSL_MSG("Setting Shared Data configuration"); + if (cfg == NULL) { + return -1; + } + /* copy configuration into our local struct */ + (void)XMEMMOVE(gSharedDataAttr, cfg, + sizeof(ta_element_attributes_t)*ATECC_MAX_SLOT); -#if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A) + ateccx08a_cfg_initialized = 0; + + return 0; +} + +#endif +#if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A) || \ + defined(WOLFSSL_MICROCHIP_TA100) /* Set the ATECC configuration for wolfSSL to use. * @@ -192,23 +372,10 @@ int wolfCrypt_ATECC_SetConfig(ATCAIfaceCfg* cfg) if (cfg == NULL) { return -1; } - /* copy configuration into our local struct */ - XMEMSET(&cfg_ateccx08a_i2c_pi, 0, sizeof(cfg_ateccx08a_i2c_pi)); - cfg_ateccx08a_i2c_pi.iface_type = cfg->iface_type; - cfg_ateccx08a_i2c_pi.devtype = cfg->devtype; -#ifdef ATCA_ENABLE_DEPRECATED - cfg_ateccx08a_i2c_pi.atcai2c.slave_address = cfg->atcai2c.slave_address; -#else - cfg_ateccx08a_i2c_pi.atcai2c.address = cfg->atcai2c.address; -#endif - cfg_ateccx08a_i2c_pi.atcai2c.bus = cfg->atcai2c.bus; - cfg_ateccx08a_i2c_pi.atcai2c.baud = cfg->atcai2c.baud; - cfg_ateccx08a_i2c_pi.wake_delay = cfg->wake_delay; - cfg_ateccx08a_i2c_pi.rx_retries = cfg->rx_retries; - cfg_ateccx08a_i2c_pi.cfg_data = cfg->cfg_data; + (void)XMEMMOVE(gCfg, cfg, sizeof(ATCAIfaceCfg)); - ateccx08a_cfg_initialized = 1; + ateccx08a_cfg_initialized = 0; return 0; } @@ -284,6 +451,14 @@ int atmel_ecc_alloc(int slotType) #else break; #endif + case ATMEL_SLOT_ECDHE_ALICE: + /* not reserved in mSlotList, so return */ + slotId = ATECC_SLOT_ECDHE_PRIV_ALICE; + goto exit; + case ATMEL_SLOT_ECDHE_BOB: + /* not reserved in mSlotList, so return */ + slotId = ATECC_SLOT_ECDHE_PRIV_BOB; + goto exit; case ATMEL_SLOT_ANY: for (i=0; i < ATECC_MAX_SLOT; i++) { /* Find free slotId */ @@ -296,7 +471,8 @@ int atmel_ecc_alloc(int slotType) } /* is slot available */ - if (mSlotList[slotId] != ATECC_INVALID_SLOT) { + if (mSlotList[slotId] != ATECC_INVALID_SLOT && + mSlotList[slotId] != slotId ) { slotId = ATECC_INVALID_SLOT; } else { @@ -395,6 +571,15 @@ static int atmel_init_enc_key(void) int atmel_get_rev_info(word32* revision) { int ret; +#ifdef WOLFSSL_ATECC_DEBUG + WOLFSSL_MSG("Waking device..."); +#endif + ret = atcab_wakeup(); +#ifdef WOLFSSL_ATECC_DEBUG + if (ret != 0) { + WOLFSSL_MSG("atcab_wakeup failed"); + } +#endif ret = atcab_info((uint8_t*)revision); ret = atmel_ecc_translate_err(ret); return ret; @@ -409,10 +594,12 @@ void atmel_show_rev_info(void) #endif } +#ifdef HAVE_ECC int atmel_ecc_create_pms(int slotId, const uint8_t* peerKey, uint8_t* pms) { int ret; uint8_t read_key[ATECC_KEY_SIZE]; + #ifdef WOLFSSL_ATECC_ECDH_ENC int slotIdEnc; @@ -425,13 +612,20 @@ int atmel_ecc_create_pms(int slotId, const uint8_t* peerKey, uint8_t* pms) ATECC_GET_ENC_KEY(read_key, sizeof(read_key)); #ifdef WOLFSSL_ATECC_ECDH_ENC - /* send the encrypted version of the ECDH command */ - ret = atcab_ecdh_enc(slotId, peerKey, pms, read_key, slotIdEnc); + #ifdef WOLFSSL_MICROCHIP_TA100 + (void)slotId; + ret = talib_ecdh_compat(atcab_get_device(), MAP_TO_HANDLE(slotIdEnc), + peerKey, pms); + #else + /* send the encrypted version of the ECDH command */ + ret = atcab_ecdh_enc(MAP_TO_HANDLE(slotId), peerKey, pms, read_key, + MAP_TO_HANDLE(slotIdEnc)); + #endif #elif defined(WOLFSSL_ATECC_ECDH_IOENC) /* encrypted ECDH command, using I/O protection key */ - ret = atcab_ecdh_ioenc(slotId, peerKey, pms, read_key); + ret = atcab_ecdh_ioenc(MAP_TO_HANDLE(slotId), peerKey, pms, read_key); #else - ret = atcab_ecdh(slotId, peerKey, pms); + ret = atcab_ecdh(MAP_TO_HANDLE(slotId), peerKey, pms); #endif ret = atmel_ecc_translate_err(ret); @@ -440,30 +634,112 @@ int atmel_ecc_create_pms(int slotId, const uint8_t* peerKey, uint8_t* pms) /* free the ECDHE slot */ atmel_ecc_free(slotIdEnc); #endif - return ret; } +#ifdef WOLFSSL_MICROCHIP_TA100 +static uint8_t getCurveType(int curve_id) +{ + switch(curve_id) + { + case ECC_SECP256R1: return TA_KEY_TYPE_ECCP256; + case ECC_SECP224R1: return TA_KEY_TYPE_ECCP224; + case ECC_SECP384R1: return TA_KEY_TYPE_ECCP384; + case ECC_SECP256K1: return TA_KEY_TYPE_SECP256K1; + case ECC_BRAINPOOLP256R1: return TA_KEY_TYPE_ECCBP256R1; + case ECC_CURVE_DEF: return TA_KEY_TYPE_ECCP256; /* default */ + default: WOLFSSL_MSG("Curve not identified"); + return MICROCHIP_INVALID_ECC; + } +} +#endif /* WOLFSSL_MICROCHIP_TA100 */ -int atmel_ecc_create_key(int slotId, byte* peerKey) +#ifdef WOLFSSL_MICROCHIP_TA100 +static int getCurveSizeBytes(int curve_id) +{ + switch (curve_id) { + case ECC_SECP224R1: return 28; + case ECC_SECP256R1: return 32; + case ECC_SECP384R1: return 48; + case ECC_SECP256K1: return 32; + case ECC_BRAINPOOLP256R1: return 32; + case ECC_CURVE_DEF: return 32; + default: return -1; + } +} +#endif /* WOLFSSL_MICROCHIP_TA100 */ +int atmel_ecc_create_key(int slotId, int curve_id, byte* peerKey) { int ret; - +#ifndef WOLFSSL_MICROCHIP_TA100 + (void)curve_id; +#endif /* verify provided slotId */ if (slotId == ATECC_INVALID_SLOT) { return WC_HW_WAIT_E; } +#ifdef WOLFSSL_MICROCHIP_TA100 + + if (getCurveType(curve_id) == MICROCHIP_INVALID_ECC) + return NOT_COMPILED_IN; +#endif /* generate new ephemeral key on device */ - ret = atcab_genkey(slotId, peerKey); - ret = atmel_ecc_translate_err(ret); - return ret; +#ifdef WOLFSSL_MICROCHIP_TA100 + #if defined(TA100_ECC_TRACE) + printf("[TA100] atmel_ecc_create_key: slot=%d curve_id=%d curve_size=%d curve_type=%d\r\n", + slotId, curve_id, getCurveSizeBytes(curve_id), getCurveType(curve_id)); +#endif + { + ATCA_STATUS status; + ta_element_attributes_t key_attr; + uint8_t is_valid = 0; + int curve_size = getCurveSizeBytes(curve_id); + int curve_type = getCurveType(curve_id); + size_t pubkey_len = (size_t)(curve_size * 2); + + if (curve_size <= 0 || curve_type == MICROCHIP_INVALID_ECC) + return NOT_COMPILED_IN; + + status = talib_is_handle_valid(atcab_get_device(), + (uint32_t)MAP_TO_HANDLE(slotId), &is_valid); + if (status == ATCA_SUCCESS && is_valid == 0x01) { + status = talib_delete_handle(atcab_get_device(), + (uint32_t)MAP_TO_HANDLE(slotId)); + } + if (status != ATCA_SUCCESS) + return atmel_ecc_translate_err(status); + + status = talib_handle_init_private_key(&key_attr, + (uint8_t)curve_type, TA_ALG_MODE_ECC_ECDSA, + TA_PROP_SIGN_INT_EXT_DIGEST, TA_PROP_KEY_AGREEMENT_OUT_BUFF); + if (status != ATCA_SUCCESS) + return atmel_ecc_translate_err(status); + + ta100_fix_property_endian(&key_attr); + status = talib_create_element_with_handle(atcab_get_device(), + (uint32_t)MAP_TO_HANDLE(slotId), &key_attr); + if (status != ATCA_SUCCESS) + return atmel_ecc_translate_err(status); + + status = talib_genkey_base(atcab_get_device(), TA_KEYGEN_MODE_NEWKEY, + (uint32_t)MAP_TO_HANDLE(slotId), peerKey, &pubkey_len); + #if defined(TA100_ECC_TRACE) + printf("[TA100] atmel_ecc_create_key: genkey status=%d pubkey_len=%u\r\n", + status, (unsigned)pubkey_len); +#endif + return atmel_ecc_translate_err(status); + } +#endif + + ret = atcab_genkey(MAP_TO_HANDLE(slotId), peerKey); + return atmel_ecc_translate_err(ret); } int atmel_ecc_sign(int slotId, const byte* message, byte* signature) { int ret; - ret = atcab_sign(slotId, message, signature); + ret = atcab_sign(MAP_TO_HANDLE(slotId), message, signature); ret = atmel_ecc_translate_err(ret); return ret; } @@ -481,15 +757,436 @@ int atmel_ecc_verify(const byte* message, const byte* signature, return ret; } -#endif /* WOLFSSL_ATECC508A */ +#ifdef WOLFSSL_MICROCHIP_TA100 +int atmel_ecc_sign_ex(int slotId, int curve_id, const byte* message, + word32 message_len, byte* signature) +{ + int ret; + int curve_size = getCurveSizeBytes(curve_id); + int curve_type = getCurveType(curve_id); + uint16_t sign_size; + const byte* msg = message; + uint16_t msg_len; + byte tmp_msg[TA_SIGN_P384_MSG_SIZE]; + byte tmp_sig[TA_SIGN_P384_SIG_SIZE]; + + if (curve_size <= 0 || curve_type == MICROCHIP_INVALID_ECC) + return NOT_COMPILED_IN; + + sign_size = (uint16_t)(curve_size * 2); + if (sign_size > sizeof(tmp_sig)) + return BAD_FUNC_ARG; + msg_len = (uint16_t)message_len; + if (msg_len != (uint16_t)curve_size) { + if (msg_len > (uint16_t)curve_size) { + msg_len = (uint16_t)curve_size; + } else { + XMEMSET(tmp_msg, 0, (word32)curve_size); + XMEMCPY(tmp_msg + (curve_size - msg_len), message, msg_len); + msg = tmp_msg; + msg_len = (uint16_t)curve_size; + } + } + #if defined(TA100_ECC_TRACE) + printf("[TA100] atmel_ecc_sign_ex: curve_size=%d msg_len=%u\r\n", + curve_size, (unsigned)msg_len); + #endif + ret = talib_sign_external(atcab_get_device(), (uint8_t)curve_type, + MAP_TO_HANDLE(slotId), TA_HANDLE_INPUT_BUFFER, msg, + msg_len, tmp_sig, &sign_size); + + if (ret != ATCA_SUCCESS) + return atmel_ecc_translate_err(ret); + + /* Always return raw R||S, each padded to curve size */ + XMEMSET(signature, 0, (word32)(curve_size * 2)); + if (sign_size == (uint16_t)(curve_size * 2)) { + XMEMCPY(signature, tmp_sig, sign_size); + } + else if ((sign_size % 2) == 0 && sign_size < (uint16_t)(curve_size * 2)) { + uint16_t half = (uint16_t)(sign_size / 2); + if (half > (uint16_t)curve_size) + return BAD_FUNC_ARG; + XMEMCPY(signature + (curve_size - half), tmp_sig, half); + XMEMCPY(signature + curve_size + (curve_size - half), + tmp_sig + half, half); + } + else { + return ASN_PARSE_E; + } + + return 0; +} + +int atmel_ecc_verify_ex(const byte* message, word32 message_len, + const byte* signature, const byte* pubkey, word32 pubkey_len, + int curve_id, int* pVerified) +{ + int ret; + int curve_size = getCurveSizeBytes(curve_id); + int curve_type = getCurveType(curve_id); + uint16_t sig_len; + const byte* msg = message; + uint16_t msg_len; + byte tmp_msg[TA_VERIFY_P384_MSG_SIZE]; + bool verified = false; + + if (curve_size <= 0 || curve_type == MICROCHIP_INVALID_ECC) + return NOT_COMPILED_IN; + + sig_len = (uint16_t)(curve_size * 2); + msg_len = (uint16_t)message_len; + if (msg_len != (uint16_t)curve_size) { + if (msg_len > (uint16_t)curve_size) { + msg_len = (uint16_t)curve_size; + } else { + XMEMSET(tmp_msg, 0, (word32)curve_size); + XMEMCPY(tmp_msg + (curve_size - msg_len), message, msg_len); + msg = tmp_msg; + msg_len = (uint16_t)curve_size; + } + } + #if defined(TA100_ECC_TRACE) + printf("[TA100] atmel_ecc_verify_ex: curve_size=%d msg_len=%u\r\n", + curve_size, (unsigned)msg_len); + #endif + ret = talib_verify(atcab_get_device(), (uint8_t)curve_type, + TA_HANDLE_INPUT_BUFFER, TA_HANDLE_INPUT_BUFFER, signature, sig_len, + msg, msg_len, pubkey, (uint16_t)pubkey_len, + &verified); + + ret = atmel_ecc_translate_err(ret); + if (pVerified) + *pVerified = (int)verified; + return ret; +} +#endif /* WOLFSSL_MICROCHIP_TA100 */ + +#endif /* HAVE_ECC */ +#endif /* WOLFSSL_ATECC508A || WOLFSSL_ATECC608A || WOLFSSL_MICROCHIP_TA100 */ + +#ifdef WOLFSSL_MICROCHIP_TA100 + +#ifndef NO_RSA +/* + * TA100 RSA Support - Sign/Verify AND Encrypt/Decrypt + * +*/ + +int wc_Microchip_rsa_create_key(struct RsaKey* key, int size, long e) +{ + ATCA_STATUS ret; + ta_element_attributes_t rKeyA, uKeyA; + size_t uKey_len = TA_KEY_TYPE_RSA2048_SIZE; + + (void)size; + (void)e; + + /* Private key for signing AND decryption */ + ret = talib_handle_init_private_key(&rKeyA, TA_KEY_TYPE_RSA2048, + TA_ALG_MODE_RSA_SSA_PSS, TA_PROP_SIGN_INT_EXT_DIGEST, + TA_PROP_KEY_AGREEMENT_OUT_BUFF); + if (ret != ATCA_SUCCESS) + return WC_HW_E; + + ta100_fix_property_endian(&rKeyA); + + ret = talib_create_element(atcab_get_device(), &rKeyA, &key->rKeyH); + if (ret != ATCA_SUCCESS) + return WC_HW_E; + + /* Public key - use 0, 0 for encryption support! */ + ret = talib_handle_init_public_key(&uKeyA, TA_KEY_TYPE_RSA2048, + TA_ALG_MODE_RSA_SSA_PSS, 0, 0); + if (ret != ATCA_SUCCESS) + return WC_HW_E; + + ta100_fix_property_endian(&uKeyA); + + ret = talib_create_element(atcab_get_device(), &uKeyA, &key->uKeyH); + if (ret != ATCA_SUCCESS) + return WC_HW_E; + + ret = talib_genkey_base(atcab_get_device(), TA_KEYGEN_MODE_NEWKEY, + (uint32_t)key->rKeyH, key->uKey, &uKey_len); + if (ret != ATCA_SUCCESS) + return WC_HW_E; + + /* Use talib_write_element, not talib_write_pub_key */ + ret = talib_write_element(atcab_get_device(), key->uKeyH, + (uint16_t)uKey_len, key->uKey); + + return atmel_ecc_translate_err(ret); +} + +int wc_Microchip_rsa_encrypt(const byte* in, word32 inLen, byte* out, + word32 outLen, RsaKey* key) +{ + int ret; + +#ifdef WOLFSSL_ATECC_DEBUG + printf("WOLFSSL_TA_KEY_TYPE_RSA = %d\n", WOLFSSL_TA_KEY_TYPE_RSA); + printf("TA_KEY_TYPE_RSA2048 = %d\n", TA_KEY_TYPE_RSA2048); + printf("=== talib_rsaenc_encrypt debug ===\n"); + printf("device: %p\n", atcab_get_device()); + printf("uKeyH: 0x%08X (%u)\n", key->uKeyH, key->uKeyH); + printf("inLen: %u\n", inLen); + printf("in: %p\n", in); + printf("outLen: %u\n", outLen); + printf("out: %p\n", out); +#endif + /* Use the 2048-specific function */ + ret = talib_rsaenc_encrypt2048(atcab_get_device(), key->uKeyH, + (uint16_t)inLen, in, + (uint16_t)outLen, out); + + return atmel_ecc_translate_err(ret); +} + +int wc_Microchip_rsa_decrypt(const byte* in, word32 inLen, byte* out, + word32 outLen, RsaKey* key) +{ + int ret; + + + ret = talib_rsaenc_decrypt2048(atcab_get_device(), key->rKeyH, + (uint16_t)inLen, in, + (uint16_t)outLen, out); + + return atmel_ecc_translate_err(ret); +} + + +int wc_Microchip_rsa_sign(const byte* in, word32 inLen, byte* out, word32 outLen, + RsaKey* key) +{ + int ret; + uint16_t sign_size = (uint16_t)outLen; + + if (in == NULL || out == NULL || key == NULL) { + return BAD_FUNC_ARG; + } + + /* TA100 expects a digest for RSA sign. */ + if (inLen != WC_SHA256_DIGEST_SIZE) { + return BAD_FUNC_ARG; + } + + /* Sign using the signing private key handle */ + ret = talib_sign_external(atcab_get_device(), + (uint8_t)(TA_SIGN_MODE_EXTERNAL_MSG | + WOLFSSL_TA_KEY_TYPE_RSA), + key->rKeyH, TA_HANDLE_INPUT_BUFFER, in, + (uint16_t)inLen, out, &sign_size); + + ret = atmel_ecc_translate_err(ret); + if (ret == 0) { + return (int)sign_size; + } + return ret; +} + + +int wc_Microchip_rsa_verify(const byte* in, word32 inLen, byte* sig, word32 sigLen, + RsaKey* key, int* pVerified) +{ + int ret; + bool verified = false; + + if (in == NULL || sig == NULL || key == NULL) { + return BAD_FUNC_ARG; + } + + /* TA100 expects a digest for RSA verify. */ + if (inLen != WC_SHA256_DIGEST_SIZE) { + return BAD_FUNC_ARG; + } + + /* Verify using the verification public key handle */ + ret = talib_verify(atcab_get_device(), WOLFSSL_TA_KEY_TYPE_RSA, + TA_HANDLE_INPUT_BUFFER, key->uKeyH, sig, + sigLen, in, (uint16_t)inLen, NULL, + sigLen, &verified); + + ret = atmel_ecc_translate_err(ret); + + if (pVerified != NULL) { + *pVerified = (int)verified; + } + + return ret; +} +void wc_Microchip_rsa_free(struct RsaKey* key) +{ + if (key == NULL) { + return; + } + + /* Free signing/encryption key handles */ + if (key->rKeyH) { + (void)talib_delete_handle(atcab_get_device(), (uint32_t)key->rKeyH); + key->rKeyH = 0; + } + if (key->uKeyH) { + (void)talib_delete_handle(atcab_get_device(), (uint32_t)key->uKeyH); + key->uKeyH = 0; + } +} + +#endif /* NO_RSA */ + +#ifdef WOLFSSL_ATECC_DEBUG +static void atmel_print_info(ta_element_attributes_t attr) +{ + printf("{0x%02x, 0x%04x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x},\n", + attr.element_CKA, attr.property, attr.usage_key, attr.write_key, + attr.read_key, attr.permission , attr.byte7_settings); +} + +static void atmel_Handle_Attributes(void) +{ + ATCA_STATUS status; + ta_element_attributes_t attributes; + (void) status; + + printf("Symmetric key AES \n" + "Symmetric key HMAC \n" + "Public key ECC \n" + "Public key RSA \n" + "Private key ECC - sign \n" + "Private key ECC - keygen \n"); + status = talib_handle_init_symmetric_key(&attributes, TA_KEY_TYPE_AES128, + TA_PROP_SYMM_KEY_USAGE_ANY); + + /* Symmetric key AES */ + atmel_print_info(attributes); + + status = talib_handle_init_symmetric_key(&attributes, TA_KEY_TYPE_HMAC, + TA_PROP_SYMM_KEY_USAGE_MAC); + /* Symmetric key HMAC */ + atmel_print_info(attributes); + + status = talib_handle_init_public_key(&attributes, TA_KEY_TYPE_ECCP256, + TA_ALG_MODE_ECC_ECDSA, TA_PROP_VAL_NO_SECURE_BOOT_SIGN, + TA_PROP_ROOT_PUB_KEY_VERIFY); + + /* Public key ECC */ + atmel_print_info(attributes); + + status = talib_handle_init_public_key(&attributes, WOLFSSL_TA_KEY_TYPE_RSA, + TA_ALG_MODE_RSA_SSA_PSS, TA_PROP_VAL_NO_SECURE_BOOT_SIGN, + TA_PROP_ROOT_PUB_KEY_VERIFY); + /* Public key RSA */ + atmel_print_info(attributes); + + status = talib_handle_init_private_key(&attributes, TA_KEY_TYPE_ECCP256, + TA_ALG_MODE_ECC_ECDH, TA_PROP_SIGN_INT_EXT_DIGEST, + TA_PROP_KEY_AGREEMENT_OUT_BUFF); + + /* Private key ECC - sign */ + atmel_print_info(attributes); + + /* Byte 0 Element Attribute */ + attributes.element_CKA = TA_CLASS_PRIVATE_KEY | + (uint8_t)(TA_KEY_TYPE_ECCP256 << TA_HANDLE_INFO_KEY_TYPE_SHIFT) | + (uint8_t)(TA_ALG_MODE_ECC_ECDSA << TA_HANDLE_INFO_ALG_MODE_SHIFT); + + attributes.property = (uint16_t)0x00 /*Public Key Handle*/ | + (uint16_t)(0x00 << TA_PROP_SESSION_KEY_SHIFT) | + (uint16_t)(0x00 << TA_PROP_KEY_GEN_SHIFT) | + (uint16_t)(TA_PROP_SIGN_INT_EXT_DIGEST << TA_PROP_SIGN_USE_SHIFT) | + (uint16_t)(TA_PROP_NO_KEY_AGREEMENT << TA_PROP_KEY_AGREEMENT_SHIFT); + + /* Byte 3 Element Attribute */ + attributes.usage_key = 0x00; + + /* Byte 4 Element Attribute */ + attributes.write_key = 0x00; + + /* Byte 5 Element Attribute */ + attributes.read_key = 0x00; + + /* Byte 6 Element Attribute */ + attributes.permission = TA_PERM_USAGE(TA_PERM_ALWAYS) | + TA_PERM_WRITE(TA_PERM_ALWAYS)| TA_PERM_READ(TA_PERM_ALWAYS) | + TA_PERM_DELETE(TA_PERM_ALWAYS); + + /* Byte 7 Element Attribute */ + attributes.byte7_settings = ((0x00 & 0x03) << 0) /*Use Count*/ | + TA_NOT_EXPORTABLE_FROM_CHIP_MASK | TA_PERMANENTLY_NOT_LOCKABLE_MASK | + TA_ACCESS_LIMIT_ALWAYS_MASK | (0 << 7) /*Intrusion Detection (N/A here)*/; + + /* Private key ECC - keygen */ + atmel_print_info(attributes); + +} +#endif + +#ifdef WOLFSSL_ATECC_DEBUG + #define CHECK_STATUS(s) \ + if ((s) != ATCA_SUCCESS) { \ + WOLFSSL_MSG("TA100 Error"); \ + printf("Error: Line %d in File %s\r\n", __LINE__, __FILE__); \ + printf("STATUS = %X\r\n", (unsigned int)(s)); \ + return atmel_ecc_translate_err(s); \ + } +#else + #define CHECK_STATUS(s) \ + if ((s) != ATCA_SUCCESS) { \ + return atmel_ecc_translate_err(s); \ + } +#endif +static int atmel_createHandles(void) +{ + ATCA_STATUS status; + uint8_t is_handle_valid = 0; + uint16_t shared_handle = SHARED_DATA_ADDR; + int i; +#ifdef WOLFSSL_ATECC_DEBUG + atmel_Handle_Attributes(); + WOLFSSL_MSG("atmel_Handle_Attributes() finished"); + WOLFSSL_MSG("createHandles starting"); +#endif + for (i = 0; i < ATECC_MAX_SLOT; i++ ) { + + status = talib_is_handle_valid(atcab_get_device(), + (uint32_t)shared_handle, &is_handle_valid); + CHECK_STATUS(status); +#ifdef WOLFSSL_ATECC_DEBUG + atmel_print_info(gSharedDataAttr[i]); +#endif + if(is_handle_valid == 0x01) { + /* Handle already Exists */; +#ifndef WOLFSSL_NO_DEL_HANDLE + status = talib_delete_handle(atcab_get_device(), + (uint32_t)shared_handle); + CHECK_STATUS(status); +#else + shared_handle += 1; + continue; +#endif + } + + status = talib_create_element_with_handle(atcab_get_device(), + shared_handle, &gSharedDataAttr[i]); + CHECK_STATUS(status); + shared_handle += 1; + } +#ifdef WOLFSSL_ATECC_DEBUG + WOLFSSL_MSG("createHandles done"); +#endif + return 0; +} +#endif /* WOLFSSL_MICROCHIP_TA100 */ int atmel_init(void) { int ret = 0; -#if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A) +#if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A) || \ + defined(WOLFSSL_MICROCHIP_TA100) #if defined(WOLFSSL_ATECC608A) /*Harmony3 will generate configuration based on user inputs*/ @@ -523,31 +1220,23 @@ int atmel_init(void) #ifdef MICROCHIP_MPLAB_HARMONY_3 atcab_release(); atcab_wakeup(); - #ifdef WOLFSSL_ATECC608A - wolfCrypt_ATECC_SetConfig(&atecc608_0_init_data); - #endif #endif if (ateccx08a_cfg_initialized == 0) { /* Setup the hardware interface using defaults */ - XMEMSET(&cfg_ateccx08a_i2c_pi, 0, sizeof(cfg_ateccx08a_i2c_pi)); - cfg_ateccx08a_i2c_pi.iface_type = ATCA_I2C_IFACE; - cfg_ateccx08a_i2c_pi.devtype = ATECC_DEV_TYPE; - #ifdef ATCA_ENABLE_DEPRECATED - cfg_ateccx08a_i2c_pi.atcai2c.slave_address = ATECC_I2C_ADDR; - #else - cfg_ateccx08a_i2c_pi.atcai2c.address = ATECC_I2C_ADDR; - #endif - cfg_ateccx08a_i2c_pi.atcai2c.bus = ATECC_I2C_BUS; - cfg_ateccx08a_i2c_pi.atcai2c.baud = 400000; - cfg_ateccx08a_i2c_pi.wake_delay = 1500; - cfg_ateccx08a_i2c_pi.rx_retries = 20; - } - - /* Initialize the CryptoAuthLib to communicate with ATECC508A */ - status = atcab_init(&cfg_ateccx08a_i2c_pi); - if (status != ATCA_SUCCESS) { - WOLFSSL_MSG("Failed to initialize atcab"); - return WC_HW_E; + status = atcab_init(gCfg); + /* Initialize the CryptoAuthLib to communicate with */ + if (status != ATCA_SUCCESS) { + WOLFSSL_MSG("Failed to initialize atcab"); + return WC_HW_E; + } + #ifdef WOLFSSL_MICROCHIP_TA100 + /* create handles for TA100 */ + status = atmel_createHandles(); + if (status != ATCA_SUCCESS) { + WOLFSSL_MSG("Failed to create TA100 handles"); + return WC_HW_E; + } + #endif } /* show revision information */ @@ -577,7 +1266,8 @@ int atmel_init(void) void atmel_finish(void) { -#if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A) +#if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A) || \ + defined(WOLFSSL_MICROCHIP_TA100) if (mAtcaInitDone) { atcab_release(); @@ -616,7 +1306,7 @@ int atcatls_create_key_cb(WOLFSSL* ssl, ecc_key* key, unsigned int keySz, return WC_HW_WAIT_E; /* generate new ephemeral key on device */ - ret = atmel_ecc_create_key(slotId, peerKey); + ret = atmel_ecc_create_key(MAP_TO_HANDLE(slotId), ecc_curve, peerKey); /* load generated ECC508A public key into key, used by wolfSSL */ if (ret == 0) { @@ -691,7 +1381,7 @@ int atcatls_create_pms_cb(WOLFSSL* ssl, ecc_key* otherKey, tmpKey.slot = slotId; /* generate new ephemeral key on device */ - ret = atmel_ecc_create_key(slotId, peerKey); + ret = atmel_ecc_create_key(slotId, otherKey->dp->id, peerKey); if (ret != ATCA_SUCCESS) { goto exit; } @@ -731,7 +1421,7 @@ int atcatls_create_pms_cb(WOLFSSL* ssl, ecc_key* otherKey, ret = atmel_ecc_create_pms(tmpKey.slot, peerKey, out); *outlen = ATECC_KEY_SIZE; - #ifndef WOLFSSL_ATECC508A_NOIDLE + #if !defined(WOLFSSL_ATECC508A_NOIDLE) && !defined(WOLFSSL_MICROCHIP_TA100) /* put chip into idle to prevent watchdog situation on chip */ atcab_idle(); #endif @@ -820,12 +1510,16 @@ int atcatls_sign_certificate_cb(WOLFSSL* ssl, const byte* in, unsigned int inSz, return WC_HW_WAIT_E; /* We can only sign with P-256 */ - ret = atmel_ecc_sign(slotId, in, sigRs); +#ifdef WOLFSSL_MICROCHIP_TA100 + ret = atmel_ecc_sign_ex(slotId, ECC_SECP256R1, in, inSz, sigRs); +#else + ret = atmel_ecc_sign(MAP_TO_HANDLE(slotId), in, sigRs); +#endif if (ret != ATCA_SUCCESS) { ret = WC_HW_E; goto exit; } -#ifndef WOLFSSL_ATECC508A_NOIDLE +#if !defined(WOLFSSL_ATECC508A_NOIDLE) && !defined(WOLFSSL_MICROCHIP_TA100) /* put chip into idle to prevent watchdog situation on chip */ atcab_idle(); #endif @@ -909,7 +1603,7 @@ int atcatls_verify_signature_cb(WOLFSSL* ssl, const byte* sig, ret = WC_HW_E; goto exit; } - #ifndef WOLFSSL_ATECC508A_NOIDLE +#if !defined(WOLFSSL_ATECC508A_NOIDLE) && !defined(WOLFSSL_MICROCHIP_TA100) /* put chip into idle to prevent watchdog situation on chip */ atcab_idle(); #endif @@ -940,6 +1634,7 @@ int atcatls_verify_signature_cb(WOLFSSL* ssl, const byte* sig, return ret; } +#ifdef ATCA_TFLEX_SUPPORT static int atcatls_set_certificates(WOLFSSL_CTX *ctx) { #ifndef ATCATLS_SIGNER_CERT_MAX_SIZE @@ -957,7 +1652,6 @@ static int atcatls_set_certificates(WOLFSSL_CTX *ctx) #endif int ret = 0; - ATCA_STATUS status; size_t signerCertSize = ATCATLS_SIGNER_CERT_MAX_SIZE; size_t deviceCertSize = ATCATLS_DEVICE_CERT_MAX_SIZE; uint8_t certBuffer[ATCATLS_CERT_BUFF_MAX_SIZE]; @@ -967,6 +1661,7 @@ static int atcatls_set_certificates(WOLFSSL_CTX *ctx) #endif #ifdef WOLFSSL_ATECC_TNGTLS + ATCA_STATUS status; ret = tng_atcacert_max_signer_cert_size(&signerCertSize); if (ret != ATCACERT_E_SUCCESS) { #ifdef WOLFSSL_ATECC_DEBUG @@ -1003,8 +1698,7 @@ static int atcatls_set_certificates(WOLFSSL_CTX *ctx) #endif return -1; } -#endif - +#endif /* WOLFSSL_ATECC_TNGTLS */ #ifdef WOLFSSL_ATECC_TFLXTLS /* MAKE SURE TO COPY YOUR CUSTOM CERTIFICATE FILES UNDER CAL/tng * Verify variable names, here below the code uses typical tflxtls @@ -1069,6 +1763,8 @@ static int atcatls_set_certificates(WOLFSSL_CTX *ctx) return ret; } +#endif /* ATCA_TFLEX_SUPPORT */ +#endif /* ATCA_TFLEX_SUPPORT */ int atcatls_set_callbacks(WOLFSSL_CTX* ctx) { @@ -1077,6 +1773,8 @@ int atcatls_set_callbacks(WOLFSSL_CTX* ctx) wolfSSL_CTX_SetEccVerifyCb(ctx, atcatls_verify_signature_cb); wolfSSL_CTX_SetEccSignCb(ctx, atcatls_sign_certificate_cb); wolfSSL_CTX_SetEccSharedSecretCb(ctx, atcatls_create_pms_cb); + +#ifdef ATCA_TFLEX_SUPPORT #if defined(WOLFSSL_ATECC_TNGTLS) || defined(WOLFSSL_ATECC_TFLXTLS) ret = atcatls_set_certificates(ctx); if (ret != 0) { @@ -1085,6 +1783,7 @@ int atcatls_set_callbacks(WOLFSSL_CTX* ctx) #endif } #endif +#endif /* ATCA_TFLEX_SUPPORT */ return ret; } @@ -1100,4 +1799,206 @@ int atcatls_set_callback_ctx(WOLFSSL* ssl, void* user_ctx) #endif /* HAVE_PK_CALLBACKS */ -#endif /* WOLFSSL_ATMEL || WOLFSSL_ATECC508A || WOLFSSL_ATECC_PKCB */ +#if defined(WOLFSSL_MICROCHIP_TA100) && !defined(NO_AES) && \ + defined(HAVE_AESGCM) && defined(WOLFSSL_MICROCHIP_AESGCM) + +/* AES key element attributes for TA100: class=0x62, prop=0x0600, perm=0x55 */ +static int ta100_aes_handle_created = 0; +static uint16_t ta100_aes_handle = TA100_AES_HANDLE; + +/* Optional runtime override for AES handle. */ +int wc_Microchip_SetAesGcmHandle(uint16_t handle) +{ + ta100_aes_handle = handle; + ta100_aes_handle_created = 0; + return 0; +} + +static int ta100_is_aes_handle(uint16_t handle) +{ + uint8_t info[TA_HANDLE_INFO_SIZE] = { 0 }; + ATCA_STATUS status; + uint8_t handle_class; + uint8_t key_type; + + status = talib_info_get_handle_info(atcab_get_device(), handle, info); + if (status != ATCA_SUCCESS) { + return 0; + } + + handle_class = info[0] & TA_HANDLE_INFO_CLASS_MASK; + key_type = (info[0] & TA_HANDLE_INFO_KEY_TYPE_MASK) >> TA_HANDLE_INFO_KEY_TYPE_SHIFT; + + return (handle_class == TA_CLASS_SYMMETRIC_KEY && key_type == TA_KEY_TYPE_AES128); +} + +int wc_Microchip_aes_set_key(Aes* aes, const byte* key, word32 keylen, + const byte* iv, int dir) +{ + ATCA_STATUS status; + bool is_locked = false; + uint8_t is_handle_valid = 0; + ta_element_attributes_t attr; + + (void)dir; + (void)iv; + + if (aes == NULL) { + return BAD_FUNC_ARG; + } + /* TA100 uses dedicated symmetric key handle, not ECC slot mapping */ + aes->key_id = ta100_aes_handle; + + aes->keylen = keylen; + aes->rounds = keylen/4 + 6; + XMEMCPY(aes->key, key, keylen); + + /* Create AES handle if not already created */ + if (!ta100_aes_handle_created) { + status = talib_is_handle_valid(atcab_get_device(), (uint32_t)aes->key_id, + &is_handle_valid); + if (status != ATCA_SUCCESS) { + return WC_HW_E; + } + + if (is_handle_valid == 0) { + status = talib_handle_init_symmetric_key(&attr, TA_KEY_TYPE_AES128, + TA_PROP_SYMM_KEY_USAGE_ANY); + if (status != ATCA_SUCCESS) { + return WC_HW_E; + } + (void)talib_handle_set_permissions(&attr, TA_PERM_ALWAYS, TA_PERM_ALWAYS, + TA_PERM_ALWAYS, TA_PERM_ALWAYS); + ta100_fix_property_endian(&attr); + + status = talib_create_element_with_handle(atcab_get_device(), + aes->key_id, &attr); + /* Ignore "already exists" error (0xA3), fail on other errors */ + if (!(status == ATCA_SUCCESS || status == 0xA3)) { + return WC_HW_E; + } + } else if (!ta100_is_aes_handle(aes->key_id)) { + return WC_HW_E; + } + + ta100_aes_handle_created = 1; + } + + status = talib_is_handle_locked(atcab_get_device(), aes->key_id, &is_locked); + if (status == ATCA_SUCCESS && is_locked) { + return WC_HW_E; + } + + /* Write AES key to the symmetric key handle */ + status = talib_write_element(atcab_get_device(), aes->key_id, + TA_KEY_TYPE_AES128_SIZE, (const uint8_t*)key); + CHECK_STATUS(status); + + /* key_block=0 for AES-128 (single 16-byte block) */ + status = talib_aes_gcm_keyload(atcab_get_device(), aes->key_id, 0); + CHECK_STATUS(status); + +#if WOLFSSL_TA100_AUTO_LOCK + /* Test if data zone is locked */ + status = talib_is_setup_locked(atcab_get_device(), &is_locked); + if (!is_locked) { + status = talib_lock_setup(atcab_get_device()); + CHECK_STATUS(status); + } +#endif + + return atmel_ecc_translate_err(status); +} + +void wc_Microchip_aes_free(Aes* aes) +{ + (void)aes; +} + + +static int wc_Microchip_AesGcmCommon(Aes* aes, byte* out, const byte* in, + word32 sz, const byte* iv, word32 ivSz, byte* authTag, word32 authTagSz, + const byte* authIn, word32 authInSz, int dir) +{ + ATCA_STATUS status; + byte tag_buf[TA_AES_GCM_TAG_LENGTH]; + word32 copy_sz; + + (void)aes; + + if (aes == NULL) { + return BAD_FUNC_ARG; + } + if (dir != AES_ENCRYPTION && dir != AES_DECRYPTION) { + return BAD_FUNC_ARG; + } + if (ivSz != TA_AES_GCM_IV_LENGTH) { + return BAD_FUNC_ARG; + } + if (authTag == NULL || authTagSz == 0 || authTagSz > TA_AES_GCM_TAG_LENGTH) { + return BAD_FUNC_ARG; + } + + if (dir == AES_ENCRYPTION) { + /* Note: talib API takes non-const iv */ + if (authTagSz != TA_AES_GCM_TAG_LENGTH) { + status = talib_aes_gcm_encrypt(atcab_get_device(), authIn, + authInSz, (uint8_t*)iv, in, sz, out, tag_buf); + if (status == ATCA_SUCCESS) { + copy_sz = authTagSz; + XMEMCPY(authTag, tag_buf, copy_sz); + } + } + else { + status = talib_aes_gcm_encrypt(atcab_get_device(), authIn, + authInSz, (uint8_t*)iv, in, sz, out, authTag); + } + } + else { + if (authTagSz != TA_AES_GCM_TAG_LENGTH) { + if (sz != 0) { + return NOT_COMPILED_IN; + } + status = talib_aes_gcm_encrypt(atcab_get_device(), authIn, + authInSz, (uint8_t*)iv, in, sz, out, tag_buf); + if (status == ATCA_SUCCESS) { + copy_sz = authTagSz; + if (XMEMCMP(tag_buf, authTag, copy_sz) != 0) { + return AES_GCM_AUTH_E; + } + } + } + else { + status = talib_aes_gcm_decrypt(atcab_get_device(), authIn, + authInSz, (uint8_t*)iv, authTag, in, sz, out); + } + } + + if (status != ATCA_SUCCESS) { + if (status == TA_CALCULATION && dir == AES_DECRYPTION) { + return AES_GCM_AUTH_E; + } + return atmel_ecc_translate_err(status); + } + + return 0; +} + +int wc_Microchip_AesGcmEncrypt(Aes* aes, byte* out, const byte* in, word32 sz, + const byte* iv, word32 ivSz, + byte* authTag, word32 authTagSz, + const byte* authIn, word32 authInSz) +{ + return wc_Microchip_AesGcmCommon(aes, out, in, sz, iv, ivSz, authTag, + authTagSz, authIn, authInSz, AES_ENCRYPTION); +} + +int wc_Microchip_AesGcmDecrypt(Aes* aes, byte* out, const byte* in, word32 sz, + const byte* iv, word32 ivSz, + const byte* authTag, word32 authTagSz, + const byte* authIn, word32 authInSz) +{ + return wc_Microchip_AesGcmCommon(aes, out, in, sz, iv, ivSz, (byte*)authTag, + authTagSz, authIn, authInSz, AES_DECRYPTION); +} +#endif /* WOLFSSL_MICROCHIP_TA100 && !NO_AES && HAVE_AESGCM */ diff --git a/wolfcrypt/src/rsa.c b/wolfcrypt/src/rsa.c index 269b39d2799..4a7cafb4428 100644 --- a/wolfcrypt/src/rsa.c +++ b/wolfcrypt/src/rsa.c @@ -619,7 +619,9 @@ int wc_FreeRsaKey(RsaKey* key) #if defined(WOLFSSL_RENESAS_FSPSM_CRYPTONLY) wc_fspsm_RsaKeyFree(key); #endif - +#ifdef WOLFSSL_MICROCHIP_TA100 + wc_Microchip_rsa_free(key); +#endif return ret; } @@ -3388,6 +3390,24 @@ 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_MICROCHIP_TA100) + if (rsa_type == RSA_PUBLIC_ENCRYPT && + pad_value == RSA_BLOCK_TYPE_2) { + if (key->uKeyH != 0) { + return wc_Microchip_rsa_encrypt(in, inLen, out, outLen, key); + } + return WC_HW_E; + } + else if (rsa_type == RSA_PRIVATE_ENCRYPT && + pad_value == RSA_BLOCK_TYPE_1) { + if (key->rKeyH != 0) { + if (pad_type != WC_RSA_PSS_PAD) { + return WC_HW_E; + } + return wc_Microchip_rsa_sign(in, inLen, out, outLen, key); + } + return WC_HW_E; + } #elif defined(WOLFSSL_SE050) && !defined(WOLFSSL_SE050_NO_RSA) if (rsa_type == RSA_PUBLIC_ENCRYPT && pad_value == RSA_BLOCK_TYPE_2) { return se050_rsa_public_encrypt(in, inLen, out, outLen, key, @@ -3550,6 +3570,25 @@ 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_MICROCHIP_TA100) + if (rsa_type == RSA_PRIVATE_DECRYPT && + pad_value == RSA_BLOCK_TYPE_2) { + if (key->rKeyH != 0) { + return wc_Microchip_rsa_decrypt(in, inLen, out, outLen, key); + } + return WC_HW_E; + } + else if (rsa_type == RSA_PUBLIC_DECRYPT && + pad_value == RSA_BLOCK_TYPE_1) { + if (key->uKeyH != 0) { + if (pad_type != WC_RSA_PSS_PAD) { + return WC_HW_E; + } + int tmp; + return wc_Microchip_rsa_verify(in, inLen, out, outLen, key, &tmp); + } + return WC_HW_E; + } #elif defined(WOLFSSL_SE050) && !defined(WOLFSSL_SE050_NO_RSA) if (rsa_type == RSA_PRIVATE_DECRYPT && pad_value == RSA_BLOCK_TYPE_2) { ret = se050_rsa_private_decrypt(in, inLen, out, outLen, key, @@ -4244,6 +4283,17 @@ int wc_RsaPSS_VerifyCheckInline(byte* in, word32 inLen, byte** out, enum wc_HashType hash, int mgf, RsaKey* key) { int ret = 0, verify, saltLen, hLen, bits = 0; +#ifdef WOLFSSL_MICROCHIP_TA100 + if (key != NULL && key->uKeyH != 0) { + int verified = 0; + ret = wc_Microchip_rsa_verify(digest, digestLen, in, inLen, key, + &verified); + if (ret != 0) { + return ret; + } + return verified ? (int)inLen : SIG_VERIFY_E; + } +#endif hLen = wc_HashGetDigestSize(hash); if (hLen < 0) @@ -4293,6 +4343,17 @@ int wc_RsaPSS_VerifyCheck(const byte* in, word32 inLen, byte* out, word32 outLen RsaKey* key) { int ret = 0, verify, saltLen, hLen, bits = 0; +#ifdef WOLFSSL_MICROCHIP_TA100 + if (key != NULL && key->uKeyH != 0) { + int verified = 0; + ret = wc_Microchip_rsa_verify(digest, digestLen, (byte*)in, inLen, + key, &verified); + if (ret != 0) { + return ret; + } + return verified ? (int)inLen : SIG_VERIFY_E; + } +#endif hLen = wc_HashGetDigestSize(hash); if (hLen < 0) @@ -4400,6 +4461,12 @@ int wc_RsaEncryptSize(const RsaKey* key) ret = mp_unsigned_bin_size(&key->n); +#if defined(WOLFSSL_MICROCHIP_TA100) + if (ret == 0 && (key->rKeyH != 0 || key->uKeyH != 0)) { + ret = WOLFSSL_TA_KEY_TYPE_RSA_SIZE; + } +#endif + #ifdef WOLF_CRYPTO_CB if (ret == 0 && key->devId != INVALID_DEVID) { if (wc_CryptoCb_RsaGetSize(key, &ret) == WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE)) { @@ -4851,7 +4918,8 @@ int wc_MakeRsaKey(RsaKey* key, int size, long e, WC_RNG* rng) #ifndef WC_NO_RNG #if !defined(WOLFSSL_CRYPTOCELL) && \ (!defined(WOLFSSL_SE050) || defined(WOLFSSL_SE050_NO_RSA)) && \ - !defined(WOLF_CRYPTO_CB_ONLY_RSA) + !defined(WOLF_CRYPTO_CB_ONLY_RSA) && \ + !defined(WOLFSSL_MICROCHIP_TA100) #ifdef WOLFSSL_SMALL_STACK mp_int *p = NULL; mp_int *q = NULL; @@ -4894,6 +4962,9 @@ int wc_MakeRsaKey(RsaKey* key, int size, long e, WC_RNG* rng) #if defined(WOLFSSL_CRYPTOCELL) err = cc310_RSA_GenerateKeyPair(key, size, e); goto out; +#elif defined(WOLFSSL_MICROCHIP_TA100) + err = wc_Microchip_rsa_create_key(key, size, e); + goto out; #elif defined(WOLFSSL_SE050) && !defined(WOLFSSL_SE050_NO_RSA) err = se050_rsa_create_key(key, size, e); goto out; diff --git a/wolfcrypt/src/signature.c b/wolfcrypt/src/signature.c index 4a403c8b7b2..26f4878e689 100644 --- a/wolfcrypt/src/signature.c +++ b/wolfcrypt/src/signature.c @@ -111,6 +111,15 @@ int wc_SignatureGetSize(enum wc_SignatureType sig_type, /* Sanity check that void* key is at least RsaKey in size */ if (key_len >= sizeof(RsaKey)) { sig_len = wc_RsaEncryptSize((RsaKey*)key); +#if defined(WOLFSSL_MICROCHIP_TA100) + if (sig_len <= 0) { + const RsaKey* r = (const RsaKey*)key; + /* TA100 handles imply a hardware RSA key. */ + if (r->rKeyH != 0 || r->uKeyH != 0) { + sig_len = WOLFSSL_TA_KEY_TYPE_RSA_SIZE; + } + } +#endif } else { WOLFSSL_MSG("wc_SignatureGetSize: Invalid RsaKey key size"); diff --git a/wolfcrypt/src/wc_port.c b/wolfcrypt/src/wc_port.c index 4bc487e75ff..e25220877b4 100644 --- a/wolfcrypt/src/wc_port.c +++ b/wolfcrypt/src/wc_port.c @@ -56,7 +56,8 @@ #endif #if defined(WOLFSSL_ATMEL) || defined(WOLFSSL_ATECC508A) || \ - defined(WOLFSSL_ATECC608A) + defined(WOLFSSL_ATECC608A) || \ + defined(WOLFSSL_MICROCHIP_TA100) #include #endif #if defined(WOLFSSL_RENESAS_TSIP) @@ -288,7 +289,7 @@ int wolfCrypt_Init(void) #endif #if defined(WOLFSSL_ATMEL) || defined(WOLFSSL_ATECC508A) || \ - defined(WOLFSSL_ATECC608A) + defined(WOLFSSL_ATECC608A) || defined(WOLFSSL_MICROCHIP_TA100) ret = atmel_init(); if (ret != 0) { WOLFSSL_MSG("CryptoAuthLib init failed"); diff --git a/wolfcrypt/test/test.c b/wolfcrypt/test/test.c index 6c1dbbeba58..fc49ad899a7 100644 --- a/wolfcrypt/test/test.c +++ b/wolfcrypt/test/test.c @@ -441,6 +441,10 @@ static const byte const_byte_array[] = "A+Gd\0\0\0"; #if defined(OPENSSL_EXTRA) || defined(DEBUG_WOLFSSL_VERBOSE) #include #endif +#if defined(WOLFSSL_MICROCHIP_TA100) + #include +#endif + #ifdef WOLFSSL_CAAM #include #endif @@ -724,7 +728,8 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t scrypt_test(void); WOLFSSL_TEST_SUBROUTINE wc_test_ret_t ecc_encrypt_test(void); #endif #if defined(USE_CERT_BUFFERS_256) && !defined(WOLFSSL_ATECC508A) && \ - !defined(WOLFSSL_ATECC608A) && !defined(NO_ECC256) && \ + !defined(WOLFSSL_ATECC608A) && !defined(WOLFSSL_MICROCHIP_TA100) && \ + !defined(NO_ECC256) && \ defined(HAVE_ECC_VERIFY) && defined(HAVE_ECC_SIGN) && \ !defined(WOLF_CRYPTO_CB_ONLY_ECC) && !defined(NO_ECC_SECP) /* skip for ATECC508/608A, cannot import private key buffers */ @@ -2699,7 +2704,8 @@ options: [-s max_relative_stack_bytes] [-m max_relative_heap_memory_bytes]\n\ TEST_PASS("ECC Enc test passed!\n"); #endif #if defined(USE_CERT_BUFFERS_256) && !defined(WOLFSSL_ATECC508A) && \ - !defined(WOLFSSL_ATECC608A) && !defined(NO_ECC256) && \ + !defined(WOLFSSL_ATECC608A) && !defined(WOLFSSL_MICROCHIP_TA100) && \ + !defined(NO_ECC256) && \ defined(HAVE_ECC_VERIFY) && defined(HAVE_ECC_SIGN) && \ !defined(WOLF_CRYPTO_CB_ONLY_ECC) && !defined(NO_ECC_SECP) /* skip for ATECC508/608A, cannot import private key buffers */ @@ -21490,7 +21496,7 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t memory_test(void) #endif /* !NO_RSA */ #if !defined(NO_RSA) || !defined(NO_DSA) - #if defined(WOLFSSL_KEY_GEN) && !defined(WOLFSSL_RSA_PUBLIC_ONLY) + #if defined(WOLFSSL_KEY_GEN) && !defined(WOLFSSL_RSA_PUBLIC_ONLY) && !defined(WOLFSSL_MICROCHIP) static const char* keyDerFile = CERT_WRITE_TEMP_DIR "key.der"; static const char* keyPemFile = CERT_WRITE_TEMP_DIR "key.pem"; #endif @@ -22205,6 +22211,13 @@ static wc_test_ret_t rsa_flatten_test(RsaKey* key) word32 eSz = sizeof(e); word32 nSz = sizeof(n); +#ifdef WOLFSSL_MICROCHIP_TA100 + /* TA100 keys are hardware-only; flattening isn't supported. */ + if (key != NULL && (key->rKeyH != 0 || key->uKeyH != 0)) { + return 0; + } +#endif + /* Parameter Validation testing. */ ret = wc_RsaFlattenPublicKey(NULL, e, &eSz, n, &nSz); if (ret != WC_NO_ERR_TRACE(BAD_FUNC_ARG)) @@ -22262,6 +22275,13 @@ static wc_test_ret_t rsa_export_key_test(RsaKey* key) word32 qSz = sizeof(q); word32 zero = 0; +#ifdef WOLFSSL_MICROCHIP_TA100 + /* TA100 keys are hardware-only; exporting components is not supported. */ + if (key != NULL && (key->rKeyH != 0 || key->uKeyH != 0)) { + return 0; + } +#endif + ret = wc_RsaExportKey(NULL, e, &eSz, n, &nSz, d, &dSz, p, &pSz, q, &qSz); if (ret != WC_NO_ERR_TRACE(BAD_FUNC_ARG)) return WC_TEST_RET_ENC_EC(ret); @@ -22390,8 +22410,13 @@ static wc_test_ret_t rsa_sig_test(RsaKey* key, word32 keyLen, int modLen, WC_RNG #if defined(WOLF_CRYPTO_CB_ONLY_RSA) if (ret != WC_NO_ERR_TRACE(NO_VALID_DEVID)) #else + #if defined(WOLFSSL_MICROCHIP_TA100) + if (ret != 0 && ret != WC_NO_ERR_TRACE(MISSING_RNG_E) && + ret != WC_NO_ERR_TRACE(BAD_FUNC_ARG)) + #else if (ret != 0 && ret != WC_NO_ERR_TRACE(MISSING_RNG_E)) #endif + #endif #elif defined(HAVE_FIPS) || !defined(WC_RSA_BLINDING) /* FIPS140 implementation does not do blinding */ if (ret != 0) @@ -22400,6 +22425,9 @@ static wc_test_ret_t rsa_sig_test(RsaKey* key, word32 keyLen, int modLen, WC_RNG #elif defined(WOLFSSL_CRYPTOCELL) || defined(WOLFSSL_SE050) /* RNG is handled by hardware */ if (ret != 0) +#elif defined(WOLFSSL_MICROCHIP_TA100) + /* TA100 path doesn't require RNG, but may report BAD_FUNC_ARG on NULL RNG. */ + if (ret != 0 && ret != WC_NO_ERR_TRACE(BAD_FUNC_ARG)) #else if (ret != WC_NO_ERR_TRACE(MISSING_RNG_E)) #endif @@ -22924,6 +22952,9 @@ static wc_test_ret_t rsa_pss_test(WC_RNG* rng, RsaKey* key) const char inStr[] = TEST_STRING; word32 inLen = (word32)TEST_STRING_SZ; word32 outSz; +#ifdef WOLFSSL_MICROCHIP_TA100 + word32 sigSz; +#endif word32 plainSz; word32 digestSz; int i, j; @@ -22934,6 +22965,10 @@ static wc_test_ret_t rsa_pss_test(WC_RNG* rng, RsaKey* key) int len; #endif byte* plain; +#ifdef WOLFSSL_MICROCHIP_TA100 + int mgf[] = { WC_MGF1SHA256 }; + enum wc_HashType hash[] = { WC_HASH_TYPE_SHA256 }; +#else int mgf[] = { #ifndef NO_SHA WC_MGF1SHA1, @@ -22968,6 +23003,7 @@ static wc_test_ret_t rsa_pss_test(WC_RNG* rng, RsaKey* key) WC_HASH_TYPE_SHA512, #endif }; +#endif /* WOLFSSL_MICROCHIP_TA100 */ WC_DECLARE_VAR(in, byte, RSA_TEST_BYTES, HEAP_HINT); WC_DECLARE_VAR(out, byte, RSA_TEST_BYTES, HEAP_HINT); @@ -23011,11 +23047,31 @@ static wc_test_ret_t rsa_pss_test(WC_RNG* rng, RsaKey* key) if (ret <= 0) ERROR_OUT(WC_TEST_RET_ENC_EC(ret), exit_rsa_pss); outSz = (word32)ret; +#ifdef WOLFSSL_MICROCHIP_TA100 + /* Preserve signature length for TA100 verify. */ + sigSz = outSz; +#endif XMEMCPY(sig, out, outSz); plain = NULL; TEST_SLEEP(); +#if defined(WOLFSSL_MICROCHIP_TA100) + do { + #if defined(WOLFSSL_ASYNC_CRYPT) + ret = wc_AsyncWait(ret, &key->asyncDev, + WC_ASYNC_FLAG_CALL_AGAIN); + #endif + if (ret >= 0) { + ret = wc_RsaPSS_VerifyCheck(sig, sigSz, out, outSz, + digest, digestSz, hash[j], mgf[i], key); + } + } while (ret == WC_NO_ERR_TRACE(WC_PENDING_E)); + if (ret <= 0) + ERROR_OUT(WC_TEST_RET_ENC_EC(ret), exit_rsa_pss); + /* TA100 PSS verify done; skip remaining software-only variants. */ + return 0; +#else do { #if defined(WOLFSSL_ASYNC_CRYPT) ret = wc_AsyncWait(ret, &key->asyncDev, @@ -23044,6 +23100,7 @@ static wc_test_ret_t rsa_pss_test(WC_RNG* rng, RsaKey* key) #endif if (ret != 0) ERROR_OUT(WC_TEST_RET_ENC_EC(ret), exit_rsa_pss); +#endif /* WOLFSSL_MICROCHIP_TA100 */ #ifdef RSA_PSS_TEST_WRONG_PARAMS for (k = 0; k < (int)(sizeof(mgf)/sizeof(*mgf)); k++) { @@ -24249,7 +24306,8 @@ static wc_test_ret_t rsa_ecc_certgen_test(WC_RNG* rng, byte* tmp) } #endif /* !NO_RSA && HAVE_ECC && WOLFSSL_CERT_GEN */ -#if defined(WOLFSSL_KEY_GEN) && !defined(WOLFSSL_RSA_PUBLIC_ONLY) +#if defined(WOLFSSL_KEY_GEN) && !defined(WOLFSSL_RSA_PUBLIC_ONLY) && \ + !defined(WOLFSSL_MICROCHIP_TA100) static wc_test_ret_t rsa_keygen_test(WC_RNG* rng) { #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_NO_MALLOC) @@ -24263,7 +24321,7 @@ static wc_test_ret_t rsa_keygen_test(WC_RNG* rng) #else byte der[1280]; #endif -#ifndef WOLFSSL_CRYPTOCELL +#if !defined(WOLFSSL_CRYPTOCELL) && !defined(WOLFSSL_MICROCHIP) word32 idx = 0; #endif int derSz = 0; @@ -24324,7 +24382,9 @@ static wc_test_ret_t rsa_keygen_test(WC_RNG* rng) #else derSz = sizeof(der); #endif +#ifndef WOLFSSL_MICROCHIP derSz = wc_RsaKeyToDer(genKey, der, derSz); +#endif if (derSz < 0) { ERROR_OUT(WC_TEST_RET_ENC_EC(derSz), exit_rsa); } @@ -24339,7 +24399,6 @@ static wc_test_ret_t rsa_keygen_test(WC_RNG* rng) ret = wc_InitRsaKey(genKey, HEAP_HINT); if (ret != 0) ERROR_OUT(WC_TEST_RET_ENC_EC(ret), exit_rsa); - #ifndef WOLFSSL_CRYPTOCELL idx = 0; /* The private key part of the key gen pairs from cryptocell can't be exported */ @@ -24347,7 +24406,6 @@ static wc_test_ret_t rsa_keygen_test(WC_RNG* rng) if (ret != 0) ERROR_OUT(WC_TEST_RET_ENC_EC(ret), exit_rsa); #endif /* WOLFSSL_CRYPTOCELL */ - exit_rsa: #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_NO_MALLOC) @@ -24892,11 +24950,38 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t rsa_test(void) ERROR_OUT(WC_TEST_RET_ENC_EC(ret), exit_rsa); #endif +#if defined(WOLFSSL_KEY_GEN) && defined(WOLFSSL_MICROCHIP_TA100) + /* Use TA100-generated key handles for RSA HW tests. */ + wc_FreeRsaKey(key); + ret = wc_InitRsaKey_ex(key, HEAP_HINT, devId); + if (ret != 0) + ERROR_OUT(WC_TEST_RET_ENC_EC(ret), exit_rsa); + ret = wc_MakeRsaKey(key, 2048, WC_RSA_EXPONENT, &rng); + if (ret != 0) + ERROR_OUT(WC_TEST_RET_ENC_EC(ret), exit_rsa); +#ifndef NO_SIG_WRAPPER + modLen = wc_RsaEncryptSize(key); +#if defined(WOLFSSL_MICROCHIP_TA100) + if (modLen <= 0 && (key->rKeyH != 0 || key->uKeyH != 0)) { + modLen = 256; + } +#endif +#endif +#ifdef WOLFSSL_MICROCHIP_TA100 + /* TA100 RSA tests are limited to PSS verify/sign with HW keys. */ + goto ta100_rsa_pss_only; +#endif +#endif /* WOLFSSL_KEY_GEN && WOLFSSL_MICROCHIP_TA100 */ + #ifndef NO_SIG_WRAPPER #ifndef NO_SHA256 + #if !defined(WOLFSSL_MICROCHIP_TA100) ret = rsa_sig_test(key, sizeof *key, modLen, &rng); if (ret != 0) goto exit_rsa; + #else + (void)modLen; + #endif /* !WOLFSSL_MICROCHIP_TA100 */ #else /* NO_SHA256 */ (void)modLen; #endif /* NO_SHA256 */ @@ -24910,12 +24995,23 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t rsa_test(void) #if !defined(WOLFSSL_RSA_VERIFY_ONLY) && !defined(WOLFSSL_RSA_PUBLIC_ONLY) && \ !defined(WC_NO_RNG) && !defined(WOLF_CRYPTO_CB_ONLY_RSA) +#ifndef WOLFSSL_MICROCHIP_TA100 do { #if defined(WOLFSSL_ASYNC_CRYPT) ret = wc_AsyncWait(ret, &key->asyncDev, WC_ASYNC_FLAG_CALL_AGAIN); #endif if (ret >= 0) { - ret = wc_RsaPublicEncrypt(in, inLen, out, outSz, key, &rng); +#if defined(WOLFSSL_KEY_GEN) && defined(WOLFSSL_MICROCHIP_TA100) + /* Create new keys for TA100 */ + ret = wc_MakeRsaKey(key, 2048, WC_RSA_EXPONENT, &rng); + if (ret) { + goto exit_rsa; + } + ret = wc_RsaPublicEncrypt(in, inLen, out, 256, key, &rng); +#else + ret = wc_RsaPublicEncrypt(in, inLen, out, outSz, key, &rng); + +#endif } } while (ret == WC_NO_ERR_TRACE(WC_PENDING_E)); if (ret < 0) @@ -24978,6 +25074,7 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t rsa_test(void) if (ret < 0) ERROR_OUT(WC_TEST_RET_ENC_EC(ret), exit_rsa); TEST_SLEEP(); +#endif /* !WOLFSSL_MICROCHIP_TA100 */ #elif defined(WOLFSSL_PUBLIC_MP) { @@ -25190,7 +25287,8 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t rsa_test(void) ERROR_OUT(WC_TEST_RET_ENC_EC(ret), exit_rsa); #endif /* WOLFSSL_CERT_EXT */ -#if defined(WOLFSSL_KEY_GEN) && !defined(WOLFSSL_RSA_PUBLIC_ONLY) +#if defined(WOLFSSL_KEY_GEN) && !defined(WOLFSSL_RSA_PUBLIC_ONLY) && \ + !defined(WOLFSSL_MICROCHIP_TA100) ret = rsa_keygen_test(&rng); if (ret != 0) goto exit_rsa; @@ -25321,6 +25419,10 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t rsa_test(void) #endif /* WOLFSSL_CERT_REQ */ #endif /* WOLFSSL_CERT_GEN */ +#ifdef WOLFSSL_MICROCHIP_TA100 +ta100_rsa_pss_only: +#endif + #if defined(WC_RSA_PSS) && \ (!defined(HAVE_FIPS) || FIPS_VERSION_GE(5,0)) && \ !defined(WC_NO_RNG) @@ -33940,7 +34042,8 @@ static wc_test_ret_t ecc_test_curve_size(WC_RNG* rng, int keySize, int testVerif int curve_id, const ecc_set_type* dp) { #if defined(HAVE_ECC_DHE) && !defined(WC_NO_RNG) && \ - !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_ATECC608A) + !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_ATECC608A) && \ + !defined(WOLFSSL_MICROCHIP_TA100) WC_DECLARE_VAR(sharedA, byte, ECC_SHARED_SIZE, HEAP_HINT); WC_DECLARE_VAR(sharedB, byte, ECC_SHARED_SIZE, HEAP_HINT); word32 y; @@ -33975,7 +34078,8 @@ static wc_test_ret_t ecc_test_curve_size(WC_RNG* rng, int keySize, int testVerif #endif #if defined(HAVE_ECC_DHE) && !defined(WC_NO_RNG) && \ - !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_ATECC608A) + !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_ATECC608A) && \ + !defined(WOLFSSL_MICROCHIP_TA100) WC_ALLOC_VAR(sharedA, byte, ECC_SHARED_SIZE, HEAP_HINT); WC_ALLOC_VAR(sharedB, byte, ECC_SHARED_SIZE, HEAP_HINT); #endif @@ -33991,7 +34095,8 @@ static wc_test_ret_t ecc_test_curve_size(WC_RNG* rng, int keySize, int testVerif #ifdef WC_DECLARE_VAR_IS_HEAP_ALLOC #if (defined(HAVE_ECC_DHE) || defined(HAVE_ECC_CDH)) && !defined(WC_NO_RNG) && \ - !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_ATECC608A) + !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_ATECC608A) && \ + !defined(WOLFSSL_MICROCHIP_TA100) if (sharedA == NULL || sharedB == NULL) ERROR_OUT(WC_TEST_RET_ENC_ERRNO, done); #endif @@ -34046,6 +34151,9 @@ static wc_test_ret_t ecc_test_curve_size(WC_RNG* rng, int keySize, int testVerif #endif #ifndef WC_NO_RNG +#if defined(WOLFSSL_MICROCHIP_TA100) + userA->slot = atmel_ecc_alloc(ATMEL_SLOT_ECDHE_ALICE); +#endif ret = wc_ecc_make_key_ex(rng, keySize, userA, curve_id); #if defined(WOLFSSL_ASYNC_CRYPT) ret = wc_AsyncWait(ret, &userA->asyncDev, WC_ASYNC_FLAG_NONE); @@ -34073,9 +34181,13 @@ static wc_test_ret_t ecc_test_curve_size(WC_RNG* rng, int keySize, int testVerif ERROR_OUT(WC_TEST_RET_ENC_EC(ret), done); TEST_SLEEP(); -/* ATECC508/608 configuration may not support more than one ECDH key */ -#if !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_ATECC608A) +#if defined(WOLFSSL_MICROCHIP_TA100) + userB->slot = atmel_ecc_alloc(ATMEL_SLOT_ECDHE_BOB); +#endif +/* ATECC508/608 configuration may not support more than one ECDH key */ +#if !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_ATECC608A) && \ + !defined(WOLFSSL_MICROCHIP_TA100) ret = wc_ecc_make_key_ex(rng, keySize, userB, curve_id); #if defined(WOLFSSL_ASYNC_CRYPT) ret = wc_AsyncWait(ret, &userB->asyncDev, WC_ASYNC_FLAG_NONE); @@ -34191,7 +34303,8 @@ static wc_test_ret_t ecc_test_curve_size(WC_RNG* rng, int keySize, int testVerif if (ret != 0) ERROR_OUT(WC_TEST_RET_ENC_EC(ret), done); -#if !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_ATECC608A) +#if !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_ATECC608A) && \ + !defined(WOLFSSL_MICROCHIP_TA100) #ifdef HAVE_ECC_DHE y = ECC_SHARED_SIZE; do { @@ -34339,7 +34452,7 @@ static wc_test_ret_t ecc_test_curve_size(WC_RNG* rng, int keySize, int testVerif #if defined(HAVE_ECC_KEY_EXPORT) && !defined(WC_NO_RNG) && \ !defined(WOLFSSL_ATECC508) && !defined(WOLFSSL_ATECC608A) && \ - !defined(WOLFSSL_KCAPI_ECC) + !defined(WOLFSSL_KCAPI_ECC) && !defined(WOLFSSL_MICROCHIP_TA100) x = ECC_KEY_EXPORT_BUF_SIZE; ret = wc_ecc_export_private_only(userA, exportBuf, &x); if (ret != 0) @@ -34380,7 +34493,6 @@ static wc_test_ret_t ecc_test_curve_size(WC_RNG* rng, int keySize, int testVerif WC_FREE_VAR(sig, HEAP_HINT); WC_FREE_VAR(digest, HEAP_HINT); #endif - (void)keySize; (void)curve_id; (void)rng; @@ -34418,7 +34530,7 @@ static wc_test_ret_t ecc_test_curve(WC_RNG* rng, int keySize, int curve_id) return ret; } } -#ifndef WOLF_CRYPTO_CB_ONLY_ECC +#if !defined(WOLF_CRYPTO_CB_ONLY_ECC) && !defined(WOLFSSL_MICROCHIP_TA100) #if FIPS_VERSION3_GE(6,0,0) skip_A: #endif @@ -34471,6 +34583,7 @@ static wc_test_ret_t ecc_test_curve(WC_RNG* rng, int keySize, int curve_id) #if (!defined(NO_ECC256) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 256 #if !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_ATECC608A) && \ + !defined(WOLFSSL_MICROCHIP_TA100) && \ defined(HAVE_ECC_KEY_IMPORT) && defined(HAVE_ECC_KEY_EXPORT) && \ !defined(WOLFSSL_NO_MALLOC) && !defined(WOLF_CRYPTO_CB_ONLY_ECC) static wc_test_ret_t ecc_point_test(void) @@ -34760,7 +34873,7 @@ static wc_test_ret_t ecc_sig_test(WC_RNG* rng, ecc_key* key) #endif #if defined(HAVE_ECC_KEY_IMPORT) && defined(HAVE_ECC_KEY_EXPORT) && \ - !defined(WOLF_CRYPTO_CB_ONLY_ECC) + !defined(WOLF_CRYPTO_CB_ONLY_ECC) && !defined(WOLFSSL_MICROCHIP_TA100) static wc_test_ret_t ecc_exp_imp_test(ecc_key* key) { @@ -34873,8 +34986,9 @@ static wc_test_ret_t ecc_exp_imp_test(ecc_key* key) #endif /* HAVE_ECC_KEY_IMPORT && HAVE_ECC_KEY_EXPORT */ #if defined(HAVE_ECC_KEY_IMPORT) && !defined(WOLFSSL_VALIDATE_ECC_IMPORT) && \ - !defined(WOLFSSL_CRYPTOCELL) && !defined(WOLF_CRYPTO_CB_ONLY_ECC) -static wc_test_ret_t ecc_mulmod_test(ecc_key* key1) + !defined(WOLFSSL_CRYPTOCELL) && !defined(WOLF_CRYPTO_CB_ONLY_ECC) && \ + !defined(WOLFSSL_MICROCHIP) +static int ecc_mulmod_test(ecc_key* key1) { wc_test_ret_t ret; #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_NO_MALLOC) @@ -34957,10 +35071,11 @@ static wc_test_ret_t ecc_mulmod_test(ecc_key* key1) } #endif -#if defined(HAVE_ECC_DHE) && !defined(WC_NO_RNG) && \ +#if !defined(WOLFSSL_MICROCHIP) && \ + defined(HAVE_ECC_DHE) && !defined(WC_NO_RNG) && \ !defined(WOLF_CRYPTO_CB_ONLY_ECC) && !defined(WOLFSSL_ATECC508A) && \ !defined(WOLFSSL_ATECC608A) && !defined(PLUTON_CRYPTO_ECC) && \ - !defined(WOLFSSL_CRYPTOCELL) + !defined(WOLFSSL_CRYPTOCELL) && !defined(WOLFSSL_MICROCHIP_TA100) static wc_test_ret_t ecc_ssh_test(ecc_key* key, WC_RNG* rng) { wc_test_ret_t ret; @@ -35055,7 +35170,8 @@ static wc_test_ret_t ecc_def_curve_test(WC_RNG *rng) #endif TEST_SLEEP(); - #if defined(HAVE_ECC_DHE) && !defined(WOLFSSL_CRYPTOCELL) && \ + #if !defined(WOLFSSL_MICROCHIP) &&\ + defined(HAVE_ECC_DHE) && !defined(WOLFSSL_CRYPTOCELL) && \ !defined(WOLF_CRYPTO_CB_ONLY_ECC) ret = ecc_ssh_test(key, rng); if (ret < 0) @@ -35101,13 +35217,16 @@ static wc_test_ret_t ecc_def_curve_test(WC_RNG *rng) goto done; } -#if defined(HAVE_ECC_KEY_IMPORT) && defined(HAVE_ECC_KEY_EXPORT) +#if defined(HAVE_ECC_KEY_IMPORT) && defined(HAVE_ECC_KEY_EXPORT) && \ + !defined(WOLF_CRYPTO_CB_ONLY_ECC) && !defined(WOLFSSL_MICROCHIP_TA100) + ret = ecc_exp_imp_test(key); if (ret < 0) goto done; #endif #if defined(HAVE_ECC_KEY_IMPORT) && !defined(WOLFSSL_VALIDATE_ECC_IMPORT) && \ - !defined(WOLFSSL_CRYPTOCELL) + !defined(WOLFSSL_CRYPTOCELL) && !defined(WOLF_CRYPTO_CB_ONLY_ECC) && \ + !defined(WOLFSSL_MICROCHIP) ret = ecc_mulmod_test(key); if (ret < 0) goto done; @@ -36930,6 +37049,7 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t ecc_test(void) goto done; } #if !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_ATECC608A) && \ + !defined(WOLFSSL_MICROCHIP_TA100) && \ defined(HAVE_ECC_KEY_IMPORT) && defined(HAVE_ECC_KEY_EXPORT) && \ !defined(WOLFSSL_NO_MALLOC) && !defined(WOLF_CRYPTO_CB_ONLY_ECC) ret = ecc_point_test(); @@ -37063,8 +37183,9 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t ecc_test(void) } #endif #if !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_ATECC608A) && \ - !defined(WOLFSSL_STM32_PKA) && !defined(WOLFSSL_SILABS_SE_ACCEL) && \ - !defined(WOLF_CRYPTO_CB_ONLY_ECC) && !defined(NO_ECC_SECP) + !defined(WOLFSSL_MICROCHIP_TA100) && \ + !defined(WOLFSSL_STM32_PKA) && !defined(WOLFSSL_SILABS_SE_ACCEL) && \ + !defined(WOLF_CRYPTO_CB_ONLY_ECC) && !defined(NO_ECC_SECP) ret = ecc_test_make_pub(&rng); if (ret != 0) { printf("ecc_test_make_pub failed!\n"); @@ -37922,7 +38043,8 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t ecc_encrypt_test(void) #endif /* HAVE_ECC_ENCRYPT && HAVE_AES_CBC && WOLFSSL_AES_128 */ #if defined(USE_CERT_BUFFERS_256) && !defined(WOLFSSL_ATECC508A) && \ - !defined(WOLFSSL_ATECC608A) && !defined(NO_ECC256) && \ + !defined(WOLFSSL_ATECC608A) && !defined(WOLFSSL_MICROCHIP_TA100) && \ + !defined(NO_ECC256) && \ defined(HAVE_ECC_VERIFY) && defined(HAVE_ECC_SIGN) && \ !defined(WOLF_CRYPTO_CB_ONLY_ECC) && !defined(NO_ECC_SECP) WOLFSSL_TEST_SUBROUTINE wc_test_ret_t ecc_test_buffers(void) diff --git a/wolfssl/wolfcrypt/aes.h b/wolfssl/wolfcrypt/aes.h index 85d5b71fa0e..06a235a92c8 100644 --- a/wolfssl/wolfcrypt/aes.h +++ b/wolfssl/wolfcrypt/aes.h @@ -306,6 +306,9 @@ struct Aes { byte keyIdSet; byte useSWCrypt; /* Use SW crypt instead of SE050, before SCP03 auth */ #endif +#ifdef WOLFSSL_MICROCHIP_TA100 + word16 key_id; /* use word16 instead of uint16_t for mplabx */ +#endif #ifdef HAVE_CAVIUM_OCTEON_SYNC word32 y0; #endif diff --git a/wolfssl/wolfcrypt/ecc.h b/wolfssl/wolfcrypt/ecc.h index 9089b876ef8..7cdf0972afa 100644 --- a/wolfssl/wolfcrypt/ecc.h +++ b/wolfssl/wolfcrypt/ecc.h @@ -49,7 +49,8 @@ #endif #endif -#if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A) +#if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A) || \ + defined(WOLFSSL_MICROCHIP_TA100) #include #endif /* WOLFSSL_ATECC508A */ @@ -175,7 +176,11 @@ enum { ECC_MAX_SIG_SIZE= ((MAX_ECC_BYTES * 2) + ECC_MAX_PAD_SZ + SIG_HEADER_SZ), /* max crypto hardware size */ -#if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A) +#if defined(WOLFSSL_MICROCHIP_TA100) + /* TA100 supports up to P-384 */ + ECC_MAX_CRYPTO_HW_SIZE = 48, + ECC_MAX_CRYPTO_HW_PUBKEY_SIZE = (ECC_MAX_CRYPTO_HW_SIZE*2), +#elif defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A) ECC_MAX_CRYPTO_HW_SIZE = ATECC_KEY_SIZE, /* from port/atmel/atmel.h */ ECC_MAX_CRYPTO_HW_PUBKEY_SIZE = (ATECC_KEY_SIZE*2), #elif defined(PLUTON_CRYPTO_ECC) @@ -541,7 +546,8 @@ struct ecc_key { word32 keyId; byte keyIdSet; #endif -#if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A) +#if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A) || \ + defined(WOLFSSL_MICROCHIP_TA100) int slot; /* Key Slot Number (-1 unknown) */ byte pubkey_raw[ECC_MAX_CRYPTO_HW_PUBKEY_SIZE]; #endif @@ -718,8 +724,11 @@ WOLFSSL_LOCAL int wc_ecc_shared_secret_gen_sync(ecc_key* private_key, ecc_point* point, byte* out, word32* outlen); -#if !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_ATECC608A) && \ - !defined(PLUTON_CRYPTO_ECC) && !defined(WOLFSSL_CRYPTOCELL) +#if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A) || \ + defined(WOLFSSL_MICROCHIP_TA100) || \ + defined(PLUTON_CRYPTO_ECC) || defined(WOLFSSL_CRYPTOCELL) +#define wc_ecc_shared_secret_ssh wc_ecc_shared_secret +#else #define wc_ecc_shared_secret_ssh wc_ecc_shared_secret_ex /* For backwards compat */ #endif diff --git a/wolfssl/wolfcrypt/port/atmel/atmel.h b/wolfssl/wolfcrypt/port/atmel/atmel.h index 515c5f46f4a..27715ab44ca 100644 --- a/wolfssl/wolfcrypt/port/atmel/atmel.h +++ b/wolfssl/wolfcrypt/port/atmel/atmel.h @@ -27,20 +27,25 @@ #include #include -#if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A) || \ - defined(WOLFSSL_ATECC_PKCB) - #undef SHA_BLOCK_SIZE - #include -#endif - /* ATECC508A/608A only supports ECC P-256 */ #define ATECC_KEY_SIZE (32) #define ATECC_PUBKEY_SIZE (ATECC_KEY_SIZE*2) /* X and Y */ #define ATECC_SIG_SIZE (ATECC_KEY_SIZE*2) /* R and S */ + +#if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A) || \ + defined(WOLFSSL_ATECC_PKCB) || defined(WOLFSSL_MICROCHIP_TA100) + #undef SHA_BLOCK_SIZE + #include + #include +#endif +#if defined(WOLFSSL_MICROCHIP_TA100) && defined(HAVE_AESGCM) + #include +#endif #ifndef ATECC_MAX_SLOT #define ATECC_MAX_SLOT (0x8) /* Only use 0-7 */ #endif #define ATECC_INVALID_SLOT (0xFF) +#define MICROCHIP_INVALID_ECC (0xFF) /* Device Key for signing */ #ifndef ATECC_SLOT_AUTH_PRIV @@ -66,6 +71,12 @@ #define ATECC_SLOT_ENC_PARENT (0x7) #endif #endif +#ifndef ATECC_SLOT_ECDHE_PRIV_ALICE + #define ATECC_SLOT_ECDHE_PRIV_ALICE (0x1) +#endif +#ifndef ATECC_SLOT_ECDHE_PRIV_BOB + #define ATECC_SLOT_ECDHE_PRIV_BOB (0x3) +#endif /* ATECC_KEY_SIZE required for ecc.h */ #include @@ -85,7 +96,8 @@ int atmel_get_random_number(uint32_t count, uint8_t* rand_out); #endif long atmel_get_curr_time_and_date(long* tm); -#if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A) +#if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A) || \ + defined(WOLFSSL_MICROCHIP_TA100) enum atmelSlotType { ATMEL_SLOT_ANY, @@ -93,10 +105,12 @@ enum atmelSlotType { ATMEL_SLOT_DEVICE, ATMEL_SLOT_ECDHE, ATMEL_SLOT_ECDHE_ENC, + ATMEL_SLOT_ECDHE_ALICE, + ATMEL_SLOT_ECDHE_BOB, }; -int atmel_ecc_alloc(int slotType); -void atmel_ecc_free(int slotId); +WOLFSSL_API int atmel_ecc_alloc(int slotType); +WOLFSSL_API void atmel_ecc_free(int slotId); typedef int (*atmel_slot_alloc_cb)(int); typedef void (*atmel_slot_dealloc_cb)(int); @@ -108,21 +122,83 @@ int atmel_get_rev_info(word32* revision); void atmel_show_rev_info(void); WOLFSSL_API int wolfCrypt_ATECC_SetConfig(ATCAIfaceCfg* cfg); - +#if defined(WOLFSSL_MICROCHIP_TA100) +WOLFSSL_API int wc_Microchip_SetSharedDataConfig(ta_element_attributes_t* cfg); +#endif /* The macro ATECC_GET_ENC_KEY can be set to override the default encryption key with your own at build-time */ #ifndef ATECC_GET_ENC_KEY #define ATECC_GET_ENC_KEY(enckey, keysize) atmel_get_enc_key_default((enckey), (keysize)) #endif int atmel_get_enc_key_default(byte* enckey, word16 keysize); +#ifdef HAVE_ECC int atmel_ecc_create_pms(int slotId, const uint8_t* peerKey, uint8_t* pms); -int atmel_ecc_create_key(int slotId, byte* peerKey); +int atmel_ecc_create_key(int slotId, int curve_id, byte* peerKey); int atmel_ecc_sign(int slotId, const byte* message, byte* signature); int atmel_ecc_verify(const byte* message, const byte* signature, const byte* pubkey, int* pVerified); - +#if defined(WOLFSSL_MICROCHIP_TA100) +int atmel_ecc_sign_ex(int slotId, int curve_id, const byte* message, + word32 message_len, byte* signature); +int atmel_ecc_verify_ex(const byte* message, word32 message_len, + const byte* signature, const byte* pubkey, word32 pubkey_len, + int curve_id, int* pVerified); +#endif +#endif /* HAVE_ECC */ #endif /* WOLFSSL_ATECC508A */ +#if defined(WOLFSSL_MICROCHIP_TA100) + +#ifndef WOLFSSL_TA100_AUTO_LOCK + #define WOLFSSL_TA100_AUTO_LOCK 0 +#endif + +#if !defined(NO_AES) && defined(HAVE_AESGCM) && \ + defined(WOLFSSL_MICROCHIP_AESGCM) +#include + +WOLFSSL_API int wc_Microchip_SetAesGcmHandle(uint16_t handle); +WOLFSSL_LOCAL int wc_Microchip_AesGcmEncrypt(Aes* aes, byte* out, + const byte* in, word32 sz, + const byte* iv, word32 ivSz, + byte* authTag, word32 authTagSz, + const byte* authIn, word32 authInSz); +WOLFSSL_LOCAL int wc_Microchip_AesGcmDecrypt(Aes* aes, byte* out, + const byte* in, word32 sz, + const byte* iv, word32 ivSz, + const byte* authTag, word32 authTagSz, + const byte* authIn, word32 authInSz); +WOLFSSL_LOCAL int wc_Microchip_aes_set_key(Aes* aes, const byte* key, + word32 len, const byte* iv, int dir); +WOLFSSL_LOCAL void wc_Microchip_aes_free(Aes* aes); +#endif /* !NO_AES && HAVE_AESGCM */ +#ifndef NO_RSA +typedef struct RsaKey RsaKey; +WOLFSSL_LOCAL int wc_Microchip_rsa_create_key(RsaKey* key, int size, long e); +WOLFSSL_LOCAL void wc_Microchip_rsa_free(RsaKey* key); +WOLFSSL_LOCAL int wc_Microchip_rsa_sign(const byte* in, word32 inLen, byte* out, + word32 outLen, RsaKey* key); +WOLFSSL_LOCAL int wc_Microchip_rsa_verify(const byte* in, word32 inLen, + byte* sig, word32 sigLen, RsaKey* key, + int* pVerified); +WOLFSSL_LOCAL int wc_Microchip_rsa_encrypt(const byte* in, word32 inLen, + byte* out, word32 outLen, RsaKey* key); +WOLFSSL_LOCAL int wc_Microchip_rsa_decrypt(const byte* in, word32 inLen, + byte* out, word32 outLen, RsaKey* key); + +#ifndef WOLFSSL_SP_NO_2048 + #define WOLFSSL_TA_KEY_TYPE_RSA TA_KEY_TYPE_RSA2048 + #define WOLFSSL_TA_KEY_TYPE_RSA_SIZE TA_KEY_TYPE_RSA2048_SIZE +#elif !defined(WOLFSSL_SP_NO_3072) + #define WOLFSSL_TA_KEY_TYPE_RSA TA_KEY_TYPE_RSA3072 + #define WOLFSSL_TA_KEY_TYPE_RSA_SIZE TA_KEY_TYPE_RSA3072_SIZE +#else + #error Microchip requires enabling 2048 or 3072 RSA. +#endif + +#endif /* NO_RSA */ +#endif /* WOLFSSL_MICROCHIP_TA100 */ + #ifdef HAVE_PK_CALLBACKS int atcatls_create_key_cb(struct WOLFSSL* ssl, struct ecc_key* key, unsigned int keySz, int ecc_curve, void* ctx); diff --git a/wolfssl/wolfcrypt/rsa.h b/wolfssl/wolfcrypt/rsa.h index e1447cf8479..047ded43594 100644 --- a/wolfssl/wolfcrypt/rsa.h +++ b/wolfssl/wolfcrypt/rsa.h @@ -144,6 +144,9 @@ RSA keys can be used to encrypt, decrypt, sign and verify data. #include #endif #endif +#if defined(WOLFSSL_MICROCHIP_TA100) + #include +#endif /* WOLFSSL_MICROCHIP_TA100 */ #if FIPS_VERSION3_GE(6,0,0) #define WC_RSA_FIPS_GEN_MIN 2048 @@ -223,6 +226,11 @@ struct RsaKey { word32 keyId; byte keyIdSet; #endif +#if defined(WOLFSSL_MICROCHIP_TA100) + uint16_t rKeyH; /* private key handle */ + uint16_t uKeyH; /* public key handle */ + byte uKey[WOLFSSL_TA_KEY_TYPE_RSA_SIZE]; /* public key */ +#endif #ifdef WOLF_CRYPTO_CB void* devCtx; int devId; @@ -497,4 +505,3 @@ WOLFSSL_API int wc_RsaPrivateKeyDecodeRaw(const byte* n, word32 nSz, #endif /* NO_RSA */ #endif /* WOLF_CRYPT_RSA_H */ - diff --git a/wolfssl/wolfcrypt/settings.h b/wolfssl/wolfcrypt/settings.h index 49301a4d3af..0aced1d9dd3 100644 --- a/wolfssl/wolfcrypt/settings.h +++ b/wolfssl/wolfcrypt/settings.h @@ -1190,7 +1190,9 @@ #endif #endif -#ifdef WOLFSSL_ATECC508A +/*#ifdef WOLFSSL_ATECC508A*/ +#if defined(WOLFSSL_ATECC508A) || \ + defined(WOLFSSL_MICROCHIP_TA100) /* backwards compatibility */ #ifndef WOLFSSL_ATECC_NO_ECDH_ENC #define WOLFSSL_ATECC_ECDH_ENC @@ -3107,6 +3109,7 @@ extern void uITRON4_free(void *p) ; #if (defined(OPENSSL_EXTRA) || defined(OPENSSL_ALL)) && defined(HAVE_ECC) && \ !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_ATECC608A) && \ + !defined(WOLFSSL_MICROCHIP_TA100) && \ !defined(WOLFSSL_CRYPTOCELL) && !defined(WOLFSSL_SE050) && \ !defined(WOLF_CRYPTO_CB_ONLY_ECC) && !defined(WOLFSSL_STM32_PKA) #undef USE_ECC_B_PARAM