diff --git a/configure.ac b/configure.ac index 788b29a8118..deb1773d403 100644 --- a/configure.ac +++ b/configure.ac @@ -2986,48 +2986,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.c b/src/pk.c index 8f07a679c10..5dac69df6c3 100644 --- a/src/pk.c +++ b/src/pk.c @@ -10901,6 +10901,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.c b/tests/api.c index f2e3401e0f4..f88cbd4864c 100644 --- a/tests/api.c +++ b/tests/api.c @@ -20948,6 +20948,1756 @@ static int test_wolfSSL_PEM_read(void) return EXPECT_RESULT(); } +static int test_wolfssl_EVP_aes_gcm_AAD_2_parts(void) +{ + EXPECT_DECLS; +#if defined(OPENSSL_EXTRA) && !defined(NO_AES) && defined(HAVE_AESGCM) && \ + !defined(HAVE_SELFTEST) && !defined(HAVE_FIPS) + const byte iv[12] = { 0 }; + const byte key[16] = { 0 }; + const byte cleartext[16] = { 0 }; + const byte aad[] = { + 0x01, 0x10, 0x00, 0x2a, 0x08, 0x00, 0x04, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, + 0x00, 0x00, 0xdc, 0x4d, 0xad, 0x6b, 0x06, 0x93, + 0x4f + }; + byte out1Part[16]; + byte outTag1Part[16]; + byte out2Part[16]; + byte outTag2Part[16]; + byte decryptBuf[16]; + int len = 0; + int tlen; + EVP_CIPHER_CTX* ctx = NULL; + + /* ENCRYPT */ + /* Send AAD and data in 1 part */ + ExpectNotNull(ctx = EVP_CIPHER_CTX_new()); + tlen = 0; + ExpectIntEQ(EVP_EncryptInit_ex(ctx, EVP_aes_128_gcm(), NULL, NULL, NULL), + 1); + ExpectIntEQ(EVP_EncryptInit_ex(ctx, NULL, NULL, key, iv), 1); + ExpectIntEQ(EVP_EncryptUpdate(ctx, NULL, &len, aad, sizeof(aad)), 1); + ExpectIntEQ(EVP_EncryptUpdate(ctx, out1Part, &len, cleartext, + sizeof(cleartext)), 1); + tlen += len; + ExpectIntEQ(EVP_EncryptFinal_ex(ctx, out1Part, &len), 1); + tlen += len; + ExpectIntEQ(tlen, sizeof(cleartext)); + ExpectIntEQ(EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_GET_TAG, 16, + outTag1Part), 1); + EVP_CIPHER_CTX_free(ctx); + ctx = NULL; + + /* DECRYPT */ + /* Send AAD and data in 1 part */ + ExpectNotNull(ctx = EVP_CIPHER_CTX_new()); + tlen = 0; + ExpectIntEQ(EVP_DecryptInit_ex(ctx, EVP_aes_128_gcm(), NULL, NULL, NULL), + 1); + ExpectIntEQ(EVP_DecryptInit_ex(ctx, NULL, NULL, key, iv), 1); + ExpectIntEQ(EVP_DecryptUpdate(ctx, NULL, &len, aad, sizeof(aad)), 1); + ExpectIntEQ(EVP_DecryptUpdate(ctx, decryptBuf, &len, out1Part, + sizeof(cleartext)), 1); + tlen += len; + ExpectIntEQ(EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG, 16, + outTag1Part), 1); + ExpectIntEQ(EVP_DecryptFinal_ex(ctx, decryptBuf, &len), 1); + tlen += len; + ExpectIntEQ(tlen, sizeof(cleartext)); + EVP_CIPHER_CTX_free(ctx); + ctx = NULL; + + ExpectIntEQ(XMEMCMP(decryptBuf, cleartext, len), 0); + + /* ENCRYPT */ + /* Send AAD and data in 2 parts */ + ExpectNotNull(ctx = EVP_CIPHER_CTX_new()); + tlen = 0; + ExpectIntEQ(EVP_EncryptInit_ex(ctx, EVP_aes_128_gcm(), NULL, NULL, NULL), + 1); + ExpectIntEQ(EVP_EncryptInit_ex(ctx, NULL, NULL, key, iv), 1); + ExpectIntEQ(EVP_EncryptUpdate(ctx, NULL, &len, aad, 1), 1); + ExpectIntEQ(EVP_EncryptUpdate(ctx, NULL, &len, aad + 1, sizeof(aad) - 1), + 1); + ExpectIntEQ(EVP_EncryptUpdate(ctx, out2Part, &len, cleartext, 1), 1); + tlen += len; + ExpectIntEQ(EVP_EncryptUpdate(ctx, out2Part + tlen, &len, cleartext + 1, + sizeof(cleartext) - 1), 1); + tlen += len; + ExpectIntEQ(EVP_EncryptFinal_ex(ctx, out2Part + tlen, &len), 1); + tlen += len; + ExpectIntEQ(tlen, sizeof(cleartext)); + ExpectIntEQ(EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_GET_TAG, 16, + outTag2Part), 1); + + ExpectIntEQ(XMEMCMP(out1Part, out2Part, sizeof(out1Part)), 0); + ExpectIntEQ(XMEMCMP(outTag1Part, outTag2Part, sizeof(outTag1Part)), 0); + EVP_CIPHER_CTX_free(ctx); + ctx = NULL; + + /* DECRYPT */ + /* Send AAD and data in 2 parts */ + ExpectNotNull(ctx = EVP_CIPHER_CTX_new()); + tlen = 0; + ExpectIntEQ(EVP_DecryptInit_ex(ctx, EVP_aes_128_gcm(), NULL, NULL, NULL), + 1); + ExpectIntEQ(EVP_DecryptInit_ex(ctx, NULL, NULL, key, iv), 1); + ExpectIntEQ(EVP_DecryptUpdate(ctx, NULL, &len, aad, 1), 1); + ExpectIntEQ(EVP_DecryptUpdate(ctx, NULL, &len, aad + 1, sizeof(aad) - 1), + 1); + ExpectIntEQ(EVP_DecryptUpdate(ctx, decryptBuf, &len, out1Part, 1), 1); + tlen += len; + ExpectIntEQ(EVP_DecryptUpdate(ctx, decryptBuf + tlen, &len, out1Part + 1, + sizeof(cleartext) - 1), 1); + tlen += len; + ExpectIntEQ(EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG, 16, + outTag1Part), 1); + ExpectIntEQ(EVP_DecryptFinal_ex(ctx, decryptBuf + tlen, &len), 1); + tlen += len; + ExpectIntEQ(tlen, sizeof(cleartext)); + + ExpectIntEQ(XMEMCMP(decryptBuf, cleartext, len), 0); + + /* Test AAD reuse */ + EVP_CIPHER_CTX_free(ctx); +#endif + return EXPECT_RESULT(); +} + +static int test_wolfssl_EVP_aes_gcm_zeroLen(void) +{ + EXPECT_DECLS; +#if defined(OPENSSL_EXTRA) && !defined(NO_AES) && defined(HAVE_AESGCM) && \ + !defined(HAVE_SELFTEST) && !defined(HAVE_FIPS) && defined(WOLFSSL_AES_256) + /* Zero length plain text */ + byte key[] = { + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 + }; /* align */ + byte iv[] = { + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 + }; /* align */ + byte plaintxt[1]; + int ivSz = 12; + int plaintxtSz = 0; + unsigned char tag[16]; + unsigned char tag_kat[] = { + 0x53,0x0f,0x8a,0xfb,0xc7,0x45,0x36,0xb9, + 0xa9,0x63,0xb4,0xf1,0xc4,0xcb,0x73,0x8b + }; + + byte ciphertxt[AES_BLOCK_SIZE * 4] = {0}; + byte decryptedtxt[AES_BLOCK_SIZE * 4] = {0}; + int ciphertxtSz = 0; + int decryptedtxtSz = 0; + int len = 0; + + EVP_CIPHER_CTX *en = EVP_CIPHER_CTX_new(); + EVP_CIPHER_CTX *de = EVP_CIPHER_CTX_new(); + + ExpectIntEQ(1, EVP_EncryptInit_ex(en, EVP_aes_256_gcm(), NULL, key, iv)); + ExpectIntEQ(1, EVP_CIPHER_CTX_ctrl(en, EVP_CTRL_GCM_SET_IVLEN, ivSz, NULL)); + ExpectIntEQ(1, EVP_EncryptUpdate(en, ciphertxt, &ciphertxtSz , plaintxt, + plaintxtSz)); + ExpectIntEQ(1, EVP_EncryptFinal_ex(en, ciphertxt, &len)); + ciphertxtSz += len; + ExpectIntEQ(1, EVP_CIPHER_CTX_ctrl(en, EVP_CTRL_GCM_GET_TAG, 16, tag)); + ExpectIntEQ(1, EVP_CIPHER_CTX_cleanup(en)); + + ExpectIntEQ(0, ciphertxtSz); + ExpectIntEQ(0, XMEMCMP(tag, tag_kat, sizeof(tag))); + + EVP_CIPHER_CTX_init(de); + ExpectIntEQ(1, EVP_DecryptInit_ex(de, EVP_aes_256_gcm(), NULL, key, iv)); + ExpectIntEQ(1, EVP_CIPHER_CTX_ctrl(de, EVP_CTRL_GCM_SET_IVLEN, ivSz, NULL)); + ExpectIntEQ(1, EVP_DecryptUpdate(de, NULL, &len, ciphertxt, len)); + decryptedtxtSz = len; + ExpectIntEQ(1, EVP_CIPHER_CTX_ctrl(de, EVP_CTRL_GCM_SET_TAG, 16, tag)); + ExpectIntEQ(1, EVP_DecryptFinal_ex(de, decryptedtxt, &len)); + decryptedtxtSz += len; + ExpectIntEQ(0, decryptedtxtSz); + + EVP_CIPHER_CTX_free(en); + EVP_CIPHER_CTX_free(de); +#endif + return EXPECT_RESULT(); +} + +static int test_wolfssl_EVP_aes_gcm(void) +{ + EXPECT_DECLS; +#if defined(OPENSSL_EXTRA) && !defined(NO_AES) && defined(HAVE_AESGCM) && \ + !defined(HAVE_SELFTEST) && !defined(HAVE_FIPS) + /* A 256 bit key, AES_128 will use the first 128 bit*/ + byte *key = (byte*)"01234567890123456789012345678901"; + /* A 128 bit IV */ + byte *iv = (byte*)"0123456789012345"; + int ivSz = AES_BLOCK_SIZE; + /* Message to be encrypted */ + byte *plaintxt = (byte*)"for things to change you have to change"; + /* Additional non-confidential data */ + byte *aad = (byte*)"Don't spend major time on minor things."; + + unsigned char tag[AES_BLOCK_SIZE] = {0}; + int plaintxtSz = (int)XSTRLEN((char*)plaintxt); + int aadSz = (int)XSTRLEN((char*)aad); + byte ciphertxt[AES_BLOCK_SIZE * 4] = {0}; + byte decryptedtxt[AES_BLOCK_SIZE * 4] = {0}; + int ciphertxtSz = 0; + int decryptedtxtSz = 0; + int len = 0; + int i = 0; + EVP_CIPHER_CTX en[2]; + EVP_CIPHER_CTX de[2]; + + for (i = 0; i < 2; i++) { + EVP_CIPHER_CTX_init(&en[i]); + if (i == 0) { + /* Default uses 96-bits IV length */ +#ifdef WOLFSSL_AES_128 + ExpectIntEQ(1, EVP_EncryptInit_ex(&en[i], EVP_aes_128_gcm(), NULL, + key, iv)); +#elif defined(WOLFSSL_AES_192) + ExpectIntEQ(1, EVP_EncryptInit_ex(&en[i], EVP_aes_192_gcm(), NULL, + key, iv)); +#elif defined(WOLFSSL_AES_256) + ExpectIntEQ(1, EVP_EncryptInit_ex(&en[i], EVP_aes_256_gcm(), NULL, + key, iv)); +#endif + } + else { +#ifdef WOLFSSL_AES_128 + ExpectIntEQ(1, EVP_EncryptInit_ex(&en[i], EVP_aes_128_gcm(), NULL, + NULL, NULL)); +#elif defined(WOLFSSL_AES_192) + ExpectIntEQ(1, EVP_EncryptInit_ex(&en[i], EVP_aes_192_gcm(), NULL, + NULL, NULL)); +#elif defined(WOLFSSL_AES_256) + ExpectIntEQ(1, EVP_EncryptInit_ex(&en[i], EVP_aes_256_gcm(), NULL, + NULL, NULL)); +#endif + /* non-default must to set the IV length first */ + ExpectIntEQ(1, EVP_CIPHER_CTX_ctrl(&en[i], EVP_CTRL_GCM_SET_IVLEN, + ivSz, NULL)); + ExpectIntEQ(1, EVP_EncryptInit_ex(&en[i], NULL, NULL, key, iv)); + } + ExpectIntEQ(1, EVP_EncryptUpdate(&en[i], NULL, &len, aad, aadSz)); + ExpectIntEQ(1, EVP_EncryptUpdate(&en[i], ciphertxt, &len, plaintxt, + plaintxtSz)); + ciphertxtSz = len; + ExpectIntEQ(1, EVP_EncryptFinal_ex(&en[i], ciphertxt, &len)); + ciphertxtSz += len; + ExpectIntEQ(1, EVP_CIPHER_CTX_ctrl(&en[i], EVP_CTRL_GCM_GET_TAG, + AES_BLOCK_SIZE, tag)); + wolfSSL_EVP_CIPHER_CTX_cleanup(&en[i]); + + EVP_CIPHER_CTX_init(&de[i]); + if (i == 0) { + /* Default uses 96-bits IV length */ +#ifdef WOLFSSL_AES_128 + ExpectIntEQ(1, EVP_DecryptInit_ex(&de[i], EVP_aes_128_gcm(), NULL, + key, iv)); +#elif defined(WOLFSSL_AES_192) + ExpectIntEQ(1, EVP_DecryptInit_ex(&de[i], EVP_aes_192_gcm(), NULL, + key, iv)); +#elif defined(WOLFSSL_AES_256) + ExpectIntEQ(1, EVP_DecryptInit_ex(&de[i], EVP_aes_256_gcm(), NULL, + key, iv)); +#endif + } + else { +#ifdef WOLFSSL_AES_128 + ExpectIntEQ(1, EVP_DecryptInit_ex(&de[i], EVP_aes_128_gcm(), NULL, + NULL, NULL)); +#elif defined(WOLFSSL_AES_192) + ExpectIntEQ(1, EVP_DecryptInit_ex(&de[i], EVP_aes_192_gcm(), NULL, + NULL, NULL)); +#elif defined(WOLFSSL_AES_256) + ExpectIntEQ(1, EVP_DecryptInit_ex(&de[i], EVP_aes_256_gcm(), NULL, + NULL, NULL)); +#endif + /* non-default must to set the IV length first */ + ExpectIntEQ(1, EVP_CIPHER_CTX_ctrl(&de[i], EVP_CTRL_GCM_SET_IVLEN, + ivSz, NULL)); + ExpectIntEQ(1, EVP_DecryptInit_ex(&de[i], NULL, NULL, key, iv)); + + } + ExpectIntEQ(1, EVP_DecryptUpdate(&de[i], NULL, &len, aad, aadSz)); + ExpectIntEQ(1, EVP_DecryptUpdate(&de[i], decryptedtxt, &len, ciphertxt, + ciphertxtSz)); + decryptedtxtSz = len; + ExpectIntEQ(1, EVP_CIPHER_CTX_ctrl(&de[i], EVP_CTRL_GCM_SET_TAG, + AES_BLOCK_SIZE, tag)); + ExpectIntEQ(1, EVP_DecryptFinal_ex(&de[i], decryptedtxt, &len)); + decryptedtxtSz += len; + ExpectIntEQ(ciphertxtSz, decryptedtxtSz); + ExpectIntEQ(0, XMEMCMP(plaintxt, decryptedtxt, decryptedtxtSz)); + + /* modify tag*/ + if (i == 0) { + /* Default uses 96-bits IV length */ +#ifdef WOLFSSL_AES_128 + ExpectIntEQ(1, EVP_DecryptInit_ex(&de[i], EVP_aes_128_gcm(), NULL, + key, iv)); +#elif defined(WOLFSSL_AES_192) + ExpectIntEQ(1, EVP_DecryptInit_ex(&de[i], EVP_aes_192_gcm(), NULL, + key, iv)); +#elif defined(WOLFSSL_AES_256) + ExpectIntEQ(1, EVP_DecryptInit_ex(&de[i], EVP_aes_256_gcm(), NULL, + key, iv)); +#endif + } + else { +#ifdef WOLFSSL_AES_128 + ExpectIntEQ(1, EVP_DecryptInit_ex(&de[i], EVP_aes_128_gcm(), NULL, + NULL, NULL)); +#elif defined(WOLFSSL_AES_192) + ExpectIntEQ(1, EVP_DecryptInit_ex(&de[i], EVP_aes_192_gcm(), NULL, + NULL, NULL)); +#elif defined(WOLFSSL_AES_256) + ExpectIntEQ(1, EVP_DecryptInit_ex(&de[i], EVP_aes_256_gcm(), NULL, + NULL, NULL)); +#endif + /* non-default must to set the IV length first */ + ExpectIntEQ(1, EVP_CIPHER_CTX_ctrl(&de[i], EVP_CTRL_GCM_SET_IVLEN, + ivSz, NULL)); + ExpectIntEQ(1, EVP_DecryptInit_ex(&de[i], NULL, NULL, key, iv)); + + } + tag[AES_BLOCK_SIZE-1]+=0xBB; + ExpectIntEQ(1, EVP_DecryptUpdate(&de[i], NULL, &len, aad, aadSz)); + ExpectIntEQ(1, EVP_CIPHER_CTX_ctrl(&de[i], EVP_CTRL_GCM_SET_TAG, + AES_BLOCK_SIZE, tag)); + /* fail due to wrong tag */ + ExpectIntEQ(1, EVP_DecryptUpdate(&de[i], decryptedtxt, &len, ciphertxt, + ciphertxtSz)); + ExpectIntEQ(0, EVP_DecryptFinal_ex(&de[i], decryptedtxt, &len)); + ExpectIntEQ(0, len); + + wolfSSL_EVP_CIPHER_CTX_cleanup(&de[i]); + } +#endif /* OPENSSL_EXTRA && !NO_AES && HAVE_AESGCM */ + return EXPECT_RESULT(); +} + +static int test_wolfssl_EVP_aria_gcm(void) +{ + int res = TEST_SKIPPED; +#if defined(OPENSSL_EXTRA) && defined(HAVE_ARIA) && \ + !defined(HAVE_SELFTEST) && !defined(HAVE_FIPS) + + /* A 256 bit key, AES_128 will use the first 128 bit*/ + byte *key = (byte*)"01234567890123456789012345678901"; + /* A 128 bit IV */ + byte *iv = (byte*)"0123456789012345"; + int ivSz = ARIA_BLOCK_SIZE; + /* Message to be encrypted */ + const int plaintxtSz = 40; + byte plaintxt[WC_ARIA_GCM_GET_CIPHERTEXT_SIZE(plaintxtSz)]; + XMEMCPY(plaintxt,"for things to change you have to change",plaintxtSz); + /* Additional non-confidential data */ + byte *aad = (byte*)"Don't spend major time on minor things."; + + unsigned char tag[ARIA_BLOCK_SIZE] = {0}; + int aadSz = (int)XSTRLEN((char*)aad); + byte ciphertxt[WC_ARIA_GCM_GET_CIPHERTEXT_SIZE(plaintxtSz)]; + byte decryptedtxt[plaintxtSz]; + int ciphertxtSz = 0; + int decryptedtxtSz = 0; + int len = 0; + int i = 0; + #define TEST_ARIA_GCM_COUNT 6 + EVP_CIPHER_CTX en[TEST_ARIA_GCM_COUNT]; + EVP_CIPHER_CTX de[TEST_ARIA_GCM_COUNT]; + + for (i = 0; i < TEST_ARIA_GCM_COUNT; i++) { + + EVP_CIPHER_CTX_init(&en[i]); + switch (i) { + case 0: + /* Default uses 96-bits IV length */ + AssertIntEQ(1, EVP_EncryptInit_ex(&en[i], EVP_aria_128_gcm(), NULL, key, iv)); + break; + case 1: + /* Default uses 96-bits IV length */ + AssertIntEQ(1, EVP_EncryptInit_ex(&en[i], EVP_aria_192_gcm(), NULL, key, iv)); + break; + case 2: + /* Default uses 96-bits IV length */ + AssertIntEQ(1, EVP_EncryptInit_ex(&en[i], EVP_aria_256_gcm(), NULL, key, iv)); + break; + case 3: + AssertIntEQ(1, EVP_EncryptInit_ex(&en[i], EVP_aria_128_gcm(), NULL, NULL, NULL)); + /* non-default must to set the IV length first */ + AssertIntEQ(1, EVP_CIPHER_CTX_ctrl(&en[i], EVP_CTRL_GCM_SET_IVLEN, ivSz, NULL)); + AssertIntEQ(1, EVP_EncryptInit_ex(&en[i], NULL, NULL, key, iv)); + break; + case 4: + AssertIntEQ(1, EVP_EncryptInit_ex(&en[i], EVP_aria_192_gcm(), NULL, NULL, NULL)); + /* non-default must to set the IV length first */ + AssertIntEQ(1, EVP_CIPHER_CTX_ctrl(&en[i], EVP_CTRL_GCM_SET_IVLEN, ivSz, NULL)); + AssertIntEQ(1, EVP_EncryptInit_ex(&en[i], NULL, NULL, key, iv)); + break; + case 5: + AssertIntEQ(1, EVP_EncryptInit_ex(&en[i], EVP_aria_256_gcm(), NULL, NULL, NULL)); + /* non-default must to set the IV length first */ + AssertIntEQ(1, EVP_CIPHER_CTX_ctrl(&en[i], EVP_CTRL_GCM_SET_IVLEN, ivSz, NULL)); + AssertIntEQ(1, EVP_EncryptInit_ex(&en[i], NULL, NULL, key, iv)); + break; + } + XMEMSET(ciphertxt,0,sizeof(ciphertxt)); + AssertIntEQ(1, EVP_EncryptUpdate(&en[i], NULL, &len, aad, aadSz)); + AssertIntEQ(1, EVP_EncryptUpdate(&en[i], ciphertxt, &len, plaintxt, plaintxtSz)); + ciphertxtSz = len; + AssertIntEQ(1, EVP_EncryptFinal_ex(&en[i], ciphertxt, &len)); + AssertIntNE(0, XMEMCMP(plaintxt, ciphertxt, plaintxtSz)); + ciphertxtSz += len; + AssertIntEQ(1, EVP_CIPHER_CTX_ctrl(&en[i], EVP_CTRL_GCM_GET_TAG, ARIA_BLOCK_SIZE, tag)); + AssertIntEQ(wolfSSL_EVP_CIPHER_CTX_cleanup(&en[i]), 1); + + EVP_CIPHER_CTX_init(&de[i]); + switch (i) { + case 0: + /* Default uses 96-bits IV length */ + AssertIntEQ(1, EVP_DecryptInit_ex(&de[i], EVP_aria_128_gcm(), NULL, key, iv)); + break; + case 1: + /* Default uses 96-bits IV length */ + AssertIntEQ(1, EVP_DecryptInit_ex(&de[i], EVP_aria_192_gcm(), NULL, key, iv)); + break; + case 2: + /* Default uses 96-bits IV length */ + AssertIntEQ(1, EVP_DecryptInit_ex(&de[i], EVP_aria_256_gcm(), NULL, key, iv)); + break; + case 3: + AssertIntEQ(1, EVP_DecryptInit_ex(&de[i], EVP_aria_128_gcm(), NULL, NULL, NULL)); + /* non-default must to set the IV length first */ + AssertIntEQ(1, EVP_CIPHER_CTX_ctrl(&de[i], EVP_CTRL_GCM_SET_IVLEN, ivSz, NULL)); + AssertIntEQ(1, EVP_DecryptInit_ex(&de[i], NULL, NULL, key, iv)); + break; + case 4: + AssertIntEQ(1, EVP_DecryptInit_ex(&de[i], EVP_aria_192_gcm(), NULL, NULL, NULL)); + /* non-default must to set the IV length first */ + AssertIntEQ(1, EVP_CIPHER_CTX_ctrl(&de[i], EVP_CTRL_GCM_SET_IVLEN, ivSz, NULL)); + AssertIntEQ(1, EVP_DecryptInit_ex(&de[i], NULL, NULL, key, iv)); + break; + case 5: + AssertIntEQ(1, EVP_DecryptInit_ex(&de[i], EVP_aria_256_gcm(), NULL, NULL, NULL)); + /* non-default must to set the IV length first */ + AssertIntEQ(1, EVP_CIPHER_CTX_ctrl(&de[i], EVP_CTRL_GCM_SET_IVLEN, ivSz, NULL)); + AssertIntEQ(1, EVP_DecryptInit_ex(&de[i], NULL, NULL, key, iv)); + break; + } + XMEMSET(decryptedtxt,0,sizeof(decryptedtxt)); + AssertIntEQ(1, EVP_DecryptUpdate(&de[i], NULL, &len, aad, aadSz)); + AssertIntEQ(1, EVP_DecryptUpdate(&de[i], decryptedtxt, &len, ciphertxt, ciphertxtSz)); + decryptedtxtSz = len; + AssertIntEQ(1, EVP_CIPHER_CTX_ctrl(&de[i], EVP_CTRL_GCM_SET_TAG, ARIA_BLOCK_SIZE, tag)); + AssertIntEQ(1, EVP_DecryptFinal_ex(&de[i], decryptedtxt, &len)); + decryptedtxtSz += len; + AssertIntEQ(plaintxtSz, decryptedtxtSz); + AssertIntEQ(0, XMEMCMP(plaintxt, decryptedtxt, decryptedtxtSz)); + + XMEMSET(decryptedtxt,0,sizeof(decryptedtxt)); + /* modify tag*/ + tag[AES_BLOCK_SIZE-1]+=0xBB; + AssertIntEQ(1, EVP_DecryptUpdate(&de[i], NULL, &len, aad, aadSz)); + AssertIntEQ(1, EVP_CIPHER_CTX_ctrl(&de[i], EVP_CTRL_GCM_SET_TAG, ARIA_BLOCK_SIZE, tag)); + /* fail due to wrong tag */ + AssertIntEQ(1, EVP_DecryptUpdate(&de[i], decryptedtxt, &len, ciphertxt, ciphertxtSz)); + AssertIntEQ(0, EVP_DecryptFinal_ex(&de[i], decryptedtxt, &len)); + AssertIntEQ(0, len); + AssertIntEQ(wolfSSL_EVP_CIPHER_CTX_cleanup(&de[i]), 1); + } + + res = TEST_RES_CHECK(1); +#endif /* OPENSSL_EXTRA && !NO_AES && HAVE_AESGCM */ + return res; +} + +static int test_wolfssl_EVP_aes_ccm_zeroLen(void) +{ + EXPECT_DECLS; +#if defined(OPENSSL_EXTRA) && !defined(NO_AES) && defined(HAVE_AESCCM) && \ + !defined(HAVE_SELFTEST) && !defined(HAVE_FIPS) && defined(WOLFSSL_AES_256) + /* Zero length plain text */ + byte key[] = { + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 + }; /* align */ + byte iv[] = { + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 + }; /* align */ + byte plaintxt[1]; + int ivSz = 12; + int plaintxtSz = 0; + unsigned char tag[16]; + + byte ciphertxt[AES_BLOCK_SIZE * 4] = {0}; + byte decryptedtxt[AES_BLOCK_SIZE * 4] = {0}; + int ciphertxtSz = 0; + int decryptedtxtSz = 0; + int len = 0; + + EVP_CIPHER_CTX *en = EVP_CIPHER_CTX_new(); + EVP_CIPHER_CTX *de = EVP_CIPHER_CTX_new(); + + ExpectIntEQ(1, EVP_EncryptInit_ex(en, EVP_aes_256_ccm(), NULL, key, iv)); + ExpectIntEQ(1, EVP_CIPHER_CTX_ctrl(en, EVP_CTRL_CCM_SET_IVLEN, ivSz, NULL)); + ExpectIntEQ(1, EVP_EncryptUpdate(en, ciphertxt, &ciphertxtSz , plaintxt, + plaintxtSz)); + ExpectIntEQ(1, EVP_EncryptFinal_ex(en, ciphertxt, &len)); + ciphertxtSz += len; + ExpectIntEQ(1, EVP_CIPHER_CTX_ctrl(en, EVP_CTRL_CCM_GET_TAG, 16, tag)); + ExpectIntEQ(1, EVP_CIPHER_CTX_cleanup(en)); + + ExpectIntEQ(0, ciphertxtSz); + + EVP_CIPHER_CTX_init(de); + ExpectIntEQ(1, EVP_DecryptInit_ex(de, EVP_aes_256_ccm(), NULL, key, iv)); + ExpectIntEQ(1, EVP_CIPHER_CTX_ctrl(de, EVP_CTRL_CCM_SET_IVLEN, ivSz, NULL)); + ExpectIntEQ(1, EVP_DecryptUpdate(de, NULL, &len, ciphertxt, len)); + decryptedtxtSz = len; + ExpectIntEQ(1, EVP_CIPHER_CTX_ctrl(de, EVP_CTRL_CCM_SET_TAG, 16, tag)); + ExpectIntEQ(1, EVP_DecryptFinal_ex(de, decryptedtxt, &len)); + decryptedtxtSz += len; + ExpectIntEQ(0, decryptedtxtSz); + + EVP_CIPHER_CTX_free(en); + EVP_CIPHER_CTX_free(de); +#endif + return EXPECT_RESULT(); +} + +static int test_wolfssl_EVP_aes_ccm(void) +{ + EXPECT_DECLS; +#if defined(OPENSSL_EXTRA) && !defined(NO_AES) && defined(HAVE_AESCCM) && \ + !defined(HAVE_SELFTEST) && !defined(HAVE_FIPS) + /* A 256 bit key, AES_128 will use the first 128 bit*/ + byte *key = (byte*)"01234567890123456789012345678901"; + /* A 128 bit IV */ + byte *iv = (byte*)"0123456789012"; + int ivSz = (int)XSTRLEN((char*)iv); + /* Message to be encrypted */ + byte *plaintxt = (byte*)"for things to change you have to change"; + /* Additional non-confidential data */ + byte *aad = (byte*)"Don't spend major time on minor things."; + + unsigned char tag[AES_BLOCK_SIZE] = {0}; + int plaintxtSz = (int)XSTRLEN((char*)plaintxt); + int aadSz = (int)XSTRLEN((char*)aad); + byte ciphertxt[AES_BLOCK_SIZE * 4] = {0}; + byte decryptedtxt[AES_BLOCK_SIZE * 4] = {0}; + int ciphertxtSz = 0; + int decryptedtxtSz = 0; + int len = 0; + int i = 0; + int ret; + EVP_CIPHER_CTX en[2]; + EVP_CIPHER_CTX de[2]; + + for (i = 0; i < 2; i++) { + EVP_CIPHER_CTX_init(&en[i]); + + if (i == 0) { + /* Default uses 96-bits IV length */ +#ifdef WOLFSSL_AES_128 + ExpectIntEQ(1, EVP_EncryptInit_ex(&en[i], EVP_aes_128_ccm(), NULL, + key, iv)); +#elif defined(WOLFSSL_AES_192) + ExpectIntEQ(1, EVP_EncryptInit_ex(&en[i], EVP_aes_192_ccm(), NULL, + key, iv)); +#elif defined(WOLFSSL_AES_256) + ExpectIntEQ(1, EVP_EncryptInit_ex(&en[i], EVP_aes_256_ccm(), NULL, + key, iv)); +#endif + } + else { +#ifdef WOLFSSL_AES_128 + ExpectIntEQ(1, EVP_EncryptInit_ex(&en[i], EVP_aes_128_ccm(), NULL, + NULL, NULL)); +#elif defined(WOLFSSL_AES_192) + ExpectIntEQ(1, EVP_EncryptInit_ex(&en[i], EVP_aes_192_ccm(), NULL, + NULL, NULL)); +#elif defined(WOLFSSL_AES_256) + ExpectIntEQ(1, EVP_EncryptInit_ex(&en[i], EVP_aes_256_ccm(), NULL, + NULL, NULL)); +#endif + /* non-default must to set the IV length first */ + ExpectIntEQ(1, EVP_CIPHER_CTX_ctrl(&en[i], EVP_CTRL_CCM_SET_IVLEN, + ivSz, NULL)); + ExpectIntEQ(1, EVP_EncryptInit_ex(&en[i], NULL, NULL, key, iv)); + } + ExpectIntEQ(1, EVP_EncryptUpdate(&en[i], NULL, &len, aad, aadSz)); + ExpectIntEQ(1, EVP_EncryptUpdate(&en[i], ciphertxt, &len, plaintxt, + plaintxtSz)); + ciphertxtSz = len; + ExpectIntEQ(1, EVP_EncryptFinal_ex(&en[i], ciphertxt, &len)); + ciphertxtSz += len; + ExpectIntEQ(1, EVP_CIPHER_CTX_ctrl(&en[i], EVP_CTRL_CCM_GET_TAG, + AES_BLOCK_SIZE, tag)); + ret = wolfSSL_EVP_CIPHER_CTX_cleanup(&en[i]); + ExpectIntEQ(ret, 1); + + EVP_CIPHER_CTX_init(&de[i]); + if (i == 0) { + /* Default uses 96-bits IV length */ +#ifdef WOLFSSL_AES_128 + ExpectIntEQ(1, EVP_DecryptInit_ex(&de[i], EVP_aes_128_ccm(), NULL, + key, iv)); +#elif defined(WOLFSSL_AES_192) + ExpectIntEQ(1, EVP_DecryptInit_ex(&de[i], EVP_aes_192_ccm(), NULL, + key, iv)); +#elif defined(WOLFSSL_AES_256) + ExpectIntEQ(1, EVP_DecryptInit_ex(&de[i], EVP_aes_256_ccm(), NULL, + key, iv)); +#endif + } + else { +#ifdef WOLFSSL_AES_128 + ExpectIntEQ(1, EVP_DecryptInit_ex(&de[i], EVP_aes_128_ccm(), NULL, + NULL, NULL)); +#elif defined(WOLFSSL_AES_192) + ExpectIntEQ(1, EVP_DecryptInit_ex(&de[i], EVP_aes_192_ccm(), NULL, + NULL, NULL)); +#elif defined(WOLFSSL_AES_256) + ExpectIntEQ(1, EVP_DecryptInit_ex(&de[i], EVP_aes_256_ccm(), NULL, + NULL, NULL)); +#endif + /* non-default must to set the IV length first */ + ExpectIntEQ(1, EVP_CIPHER_CTX_ctrl(&de[i], EVP_CTRL_CCM_SET_IVLEN, + ivSz, NULL)); + ExpectIntEQ(1, EVP_DecryptInit_ex(&de[i], NULL, NULL, key, iv)); + + } + ExpectIntEQ(1, EVP_DecryptUpdate(&de[i], NULL, &len, aad, aadSz)); + ExpectIntEQ(1, EVP_DecryptUpdate(&de[i], decryptedtxt, &len, ciphertxt, + ciphertxtSz)); + decryptedtxtSz = len; + ExpectIntEQ(1, EVP_CIPHER_CTX_ctrl(&de[i], EVP_CTRL_CCM_SET_TAG, + AES_BLOCK_SIZE, tag)); + ExpectIntEQ(1, EVP_DecryptFinal_ex(&de[i], decryptedtxt, &len)); + decryptedtxtSz += len; + ExpectIntEQ(ciphertxtSz, decryptedtxtSz); + ExpectIntEQ(0, XMEMCMP(plaintxt, decryptedtxt, decryptedtxtSz)); + + /* modify tag*/ + tag[AES_BLOCK_SIZE-1]+=0xBB; + ExpectIntEQ(1, EVP_DecryptUpdate(&de[i], NULL, &len, aad, aadSz)); + ExpectIntEQ(1, EVP_CIPHER_CTX_ctrl(&de[i], EVP_CTRL_CCM_SET_TAG, + AES_BLOCK_SIZE, tag)); + /* fail due to wrong tag */ + ExpectIntEQ(1, EVP_DecryptUpdate(&de[i], decryptedtxt, &len, ciphertxt, + ciphertxtSz)); + ExpectIntEQ(0, EVP_DecryptFinal_ex(&de[i], decryptedtxt, &len)); + ExpectIntEQ(0, len); + ret = wolfSSL_EVP_CIPHER_CTX_cleanup(&de[i]); + ExpectIntEQ(ret, 1); + } +#endif /* OPENSSL_EXTRA && !NO_AES && HAVE_AESCCM */ + return EXPECT_RESULT(); +} + +static int test_wolfssl_EVP_chacha20_poly1305(void) +{ + EXPECT_DECLS; +#if defined(OPENSSL_EXTRA) && defined(HAVE_CHACHA) && defined(HAVE_POLY1305) + byte key[CHACHA20_POLY1305_AEAD_KEYSIZE]; + byte iv [CHACHA20_POLY1305_AEAD_IV_SIZE]; + byte plainText[] = {0xDE, 0xAD, 0xBE, 0xEF}; + byte aad[] = {0xAA, 0XBB, 0xCC, 0xDD, 0xEE, 0xFF}; + byte cipherText[sizeof(plainText)]; + byte decryptedText[sizeof(plainText)]; + byte tag[CHACHA20_POLY1305_AEAD_AUTHTAG_SIZE]; + EVP_CIPHER_CTX* ctx = NULL; + int outSz; + + XMEMSET(key, 0, sizeof(key)); + XMEMSET(iv, 0, sizeof(iv)); + + /* Encrypt. */ + ExpectNotNull((ctx = EVP_CIPHER_CTX_new())); + ExpectIntEQ(EVP_EncryptInit_ex(ctx, EVP_chacha20_poly1305(), NULL, NULL, + NULL), WOLFSSL_SUCCESS); + /* Invalid IV length. */ + ExpectIntEQ(EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_IVLEN, + CHACHA20_POLY1305_AEAD_IV_SIZE-1, NULL), WC_NO_ERR_TRACE(WOLFSSL_FAILURE)); + /* Valid IV length. */ + ExpectIntEQ(EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_IVLEN, + CHACHA20_POLY1305_AEAD_IV_SIZE, NULL), WOLFSSL_SUCCESS); + /* Invalid tag length. */ + ExpectIntEQ(EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG, + CHACHA20_POLY1305_AEAD_AUTHTAG_SIZE-1, NULL), WC_NO_ERR_TRACE(WOLFSSL_FAILURE)); + /* Valid tag length. */ + ExpectIntEQ(EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG, + CHACHA20_POLY1305_AEAD_AUTHTAG_SIZE, NULL), WOLFSSL_SUCCESS); + ExpectIntEQ(EVP_EncryptInit_ex(ctx, NULL, NULL, key, iv), WOLFSSL_SUCCESS); + ExpectIntEQ(EVP_EncryptUpdate(ctx, NULL, &outSz, aad, sizeof(aad)), + WOLFSSL_SUCCESS); + ExpectIntEQ(outSz, sizeof(aad)); + ExpectIntEQ(EVP_EncryptUpdate(ctx, cipherText, &outSz, plainText, + sizeof(plainText)), WOLFSSL_SUCCESS); + ExpectIntEQ(outSz, sizeof(plainText)); + ExpectIntEQ(EVP_EncryptFinal_ex(ctx, cipherText, &outSz), WOLFSSL_SUCCESS); + ExpectIntEQ(outSz, 0); + /* Invalid tag length. */ + ExpectIntEQ(EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_GET_TAG, + CHACHA20_POLY1305_AEAD_AUTHTAG_SIZE-1, tag), WC_NO_ERR_TRACE(WOLFSSL_FAILURE)); + /* Valid tag length. */ + ExpectIntEQ(EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_GET_TAG, + CHACHA20_POLY1305_AEAD_AUTHTAG_SIZE, tag), WOLFSSL_SUCCESS); + EVP_CIPHER_CTX_free(ctx); + ctx = NULL; + + /* Decrypt. */ + ExpectNotNull((ctx = EVP_CIPHER_CTX_new())); + ExpectIntEQ(EVP_DecryptInit_ex(ctx, EVP_chacha20_poly1305(), NULL, NULL, + NULL), WOLFSSL_SUCCESS); + ExpectIntEQ(EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_IVLEN, + CHACHA20_POLY1305_AEAD_IV_SIZE, NULL), WOLFSSL_SUCCESS); + ExpectIntEQ(EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG, + CHACHA20_POLY1305_AEAD_AUTHTAG_SIZE, tag), WOLFSSL_SUCCESS); + ExpectIntEQ(EVP_DecryptInit_ex(ctx, NULL, NULL, key, iv), WOLFSSL_SUCCESS); + ExpectIntEQ(EVP_DecryptUpdate(ctx, NULL, &outSz, aad, sizeof(aad)), + WOLFSSL_SUCCESS); + ExpectIntEQ(outSz, sizeof(aad)); + ExpectIntEQ(EVP_DecryptUpdate(ctx, decryptedText, &outSz, cipherText, + sizeof(cipherText)), WOLFSSL_SUCCESS); + ExpectIntEQ(outSz, sizeof(cipherText)); + ExpectIntEQ(EVP_DecryptFinal_ex(ctx, decryptedText, &outSz), + WOLFSSL_SUCCESS); + ExpectIntEQ(outSz, 0); + EVP_CIPHER_CTX_free(ctx); + ctx = NULL; + + /* Test partial Inits. CipherInit() allow setting of key and iv + * in separate calls. */ + ExpectNotNull((ctx = EVP_CIPHER_CTX_new())); + ExpectIntEQ(wolfSSL_EVP_CipherInit(ctx, EVP_chacha20_poly1305(), + key, NULL, 1), WOLFSSL_SUCCESS); + ExpectIntEQ(wolfSSL_EVP_CipherInit(ctx, NULL, NULL, iv, 1), + WOLFSSL_SUCCESS); + ExpectIntEQ(wolfSSL_EVP_CipherUpdate(ctx, NULL, &outSz, + aad, sizeof(aad)), WOLFSSL_SUCCESS); + ExpectIntEQ(outSz, sizeof(aad)); + ExpectIntEQ(EVP_DecryptUpdate(ctx, decryptedText, &outSz, cipherText, + sizeof(cipherText)), WOLFSSL_SUCCESS); + ExpectIntEQ(outSz, sizeof(cipherText)); + ExpectIntEQ(EVP_DecryptFinal_ex(ctx, decryptedText, &outSz), + WOLFSSL_SUCCESS); + ExpectIntEQ(outSz, 0); + EVP_CIPHER_CTX_free(ctx); +#endif + return EXPECT_RESULT(); +} + +static int test_wolfssl_EVP_chacha20(void) +{ + EXPECT_DECLS; +#if defined(OPENSSL_EXTRA) && defined(HAVE_CHACHA) + byte key[CHACHA_MAX_KEY_SZ]; + byte iv [WOLFSSL_EVP_CHACHA_IV_BYTES]; + byte plainText[] = {0xDE, 0xAD, 0xBE, 0xEF}; + byte cipherText[sizeof(plainText)]; + byte decryptedText[sizeof(plainText)]; + EVP_CIPHER_CTX* ctx = NULL; + int outSz; + + XMEMSET(key, 0, sizeof(key)); + XMEMSET(iv, 0, sizeof(iv)); + /* Encrypt. */ + ExpectNotNull((ctx = EVP_CIPHER_CTX_new())); + ExpectIntEQ(EVP_EncryptInit_ex(ctx, EVP_chacha20(), NULL, NULL, + NULL), WOLFSSL_SUCCESS); + /* Any tag length must fail - not an AEAD cipher. */ + ExpectIntEQ(EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG, + 16, NULL), WC_NO_ERR_TRACE(WOLFSSL_FAILURE)); + ExpectIntEQ(EVP_EncryptInit_ex(ctx, NULL, NULL, key, iv), WOLFSSL_SUCCESS); + ExpectIntEQ(EVP_EncryptUpdate(ctx, cipherText, &outSz, plainText, + sizeof(plainText)), WOLFSSL_SUCCESS); + ExpectIntEQ(outSz, sizeof(plainText)); + ExpectIntEQ(EVP_EncryptFinal_ex(ctx, cipherText, &outSz), WOLFSSL_SUCCESS); + ExpectIntEQ(outSz, 0); + EVP_CIPHER_CTX_free(ctx); + ctx = NULL; + + /* Decrypt. */ + ExpectNotNull((ctx = EVP_CIPHER_CTX_new())); + ExpectIntEQ(EVP_DecryptInit_ex(ctx, EVP_chacha20(), NULL, NULL, + NULL), WOLFSSL_SUCCESS); + ExpectIntEQ(EVP_DecryptInit_ex(ctx, NULL, NULL, key, iv), WOLFSSL_SUCCESS); + ExpectIntEQ(EVP_DecryptUpdate(ctx, decryptedText, &outSz, cipherText, + sizeof(cipherText)), WOLFSSL_SUCCESS); + ExpectIntEQ(outSz, sizeof(cipherText)); + ExpectIntEQ(EVP_DecryptFinal_ex(ctx, decryptedText, &outSz), + WOLFSSL_SUCCESS); + ExpectIntEQ(outSz, 0); + EVP_CIPHER_CTX_free(ctx); + ctx = NULL; + + /* Test partial Inits. CipherInit() allow setting of key and iv + * in separate calls. */ + ExpectNotNull((ctx = EVP_CIPHER_CTX_new())); + ExpectIntEQ(wolfSSL_EVP_CipherInit(ctx, EVP_chacha20(), + key, NULL, 1), WOLFSSL_SUCCESS); + ExpectIntEQ(wolfSSL_EVP_CipherInit(ctx, NULL, NULL, iv, 1), + WOLFSSL_SUCCESS); + ExpectIntEQ(EVP_DecryptUpdate(ctx, decryptedText, &outSz, cipherText, + sizeof(cipherText)), WOLFSSL_SUCCESS); + ExpectIntEQ(outSz, sizeof(cipherText)); + ExpectIntEQ(EVP_DecryptFinal_ex(ctx, decryptedText, &outSz), + WOLFSSL_SUCCESS); + ExpectIntEQ(outSz, 0); + EVP_CIPHER_CTX_free(ctx); +#endif + return EXPECT_RESULT(); +} + +static int test_wolfssl_EVP_sm4_ecb(void) +{ + int res = TEST_SKIPPED; +#if defined(OPENSSL_EXTRA) && defined(WOLFSSL_SM4_ECB) + EXPECT_DECLS; + byte key[SM4_KEY_SIZE]; + byte plainText[SM4_BLOCK_SIZE] = { + 0xDE, 0xAD, 0xBE, 0xEF, 0xDE, 0xAD, 0xBE, 0xEF, + 0xDE, 0xAD, 0xBE, 0xEF, 0xDE, 0xAD, 0xBE, 0xEF + }; + byte cipherText[sizeof(plainText) + SM4_BLOCK_SIZE]; + byte decryptedText[sizeof(plainText) + SM4_BLOCK_SIZE]; + EVP_CIPHER_CTX* ctx; + int outSz; + + XMEMSET(key, 0, sizeof(key)); + + /* Encrypt. */ + ExpectNotNull((ctx = EVP_CIPHER_CTX_new())); + ExpectIntEQ(EVP_EncryptInit_ex(ctx, EVP_sm4_ecb(), NULL, NULL, NULL), + WOLFSSL_SUCCESS); + /* Any tag length must fail - not an AEAD cipher. */ + ExpectIntEQ(EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG, 16, NULL), + WC_NO_ERR_TRACE(WOLFSSL_FAILURE)); + ExpectIntEQ(EVP_EncryptInit_ex(ctx, NULL, NULL, key, NULL), + WOLFSSL_SUCCESS); + ExpectIntEQ(EVP_EncryptUpdate(ctx, cipherText, &outSz, plainText, + sizeof(plainText)), WOLFSSL_SUCCESS); + ExpectIntEQ(outSz, sizeof(plainText)); + ExpectIntEQ(EVP_EncryptFinal_ex(ctx, cipherText + outSz, &outSz), + WOLFSSL_SUCCESS); + ExpectIntEQ(outSz, SM4_BLOCK_SIZE); + ExpectBufNE(cipherText, plainText, sizeof(plainText)); + EVP_CIPHER_CTX_free(ctx); + + /* Decrypt. */ + ExpectNotNull((ctx = EVP_CIPHER_CTX_new())); + ExpectIntEQ(EVP_DecryptInit_ex(ctx, EVP_sm4_ecb(), NULL, NULL, NULL), + WOLFSSL_SUCCESS); + ExpectIntEQ(EVP_DecryptInit_ex(ctx, NULL, NULL, key, NULL), + WOLFSSL_SUCCESS); + ExpectIntEQ(EVP_DecryptUpdate(ctx, decryptedText, &outSz, cipherText, + sizeof(cipherText)), WOLFSSL_SUCCESS); + ExpectIntEQ(outSz, sizeof(plainText)); + ExpectIntEQ(EVP_DecryptFinal_ex(ctx, decryptedText + outSz, &outSz), + WOLFSSL_SUCCESS); + ExpectIntEQ(outSz, 0); + ExpectBufEQ(decryptedText, plainText, sizeof(plainText)); + EVP_CIPHER_CTX_free(ctx); + + res = EXPECT_RESULT(); +#endif + return res; +} + +static int test_wolfssl_EVP_sm4_cbc(void) +{ + int res = TEST_SKIPPED; +#if defined(OPENSSL_EXTRA) && defined(WOLFSSL_SM4_CBC) + EXPECT_DECLS; + byte key[SM4_KEY_SIZE]; + byte iv[SM4_BLOCK_SIZE]; + byte plainText[SM4_BLOCK_SIZE] = { + 0xDE, 0xAD, 0xBE, 0xEF, 0xDE, 0xAD, 0xBE, 0xEF, + 0xDE, 0xAD, 0xBE, 0xEF, 0xDE, 0xAD, 0xBE, 0xEF + }; + byte cipherText[sizeof(plainText) + SM4_BLOCK_SIZE]; + byte decryptedText[sizeof(plainText) + SM4_BLOCK_SIZE]; + EVP_CIPHER_CTX* ctx; + int outSz; + + XMEMSET(key, 0, sizeof(key)); + XMEMSET(iv, 0, sizeof(iv)); + + /* Encrypt. */ + ExpectNotNull((ctx = EVP_CIPHER_CTX_new())); + ExpectIntEQ(EVP_EncryptInit_ex(ctx, EVP_sm4_cbc(), NULL, NULL, NULL), + WOLFSSL_SUCCESS); + /* Any tag length must fail - not an AEAD cipher. */ + ExpectIntEQ(EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG, 16, NULL), + WC_NO_ERR_TRACE(WOLFSSL_FAILURE)); + ExpectIntEQ(EVP_EncryptInit_ex(ctx, NULL, NULL, key, iv), WOLFSSL_SUCCESS); + ExpectIntEQ(EVP_EncryptUpdate(ctx, cipherText, &outSz, plainText, + sizeof(plainText)), WOLFSSL_SUCCESS); + ExpectIntEQ(outSz, sizeof(plainText)); + ExpectIntEQ(EVP_EncryptFinal_ex(ctx, cipherText + outSz, &outSz), + WOLFSSL_SUCCESS); + ExpectIntEQ(outSz, SM4_BLOCK_SIZE); + ExpectBufNE(cipherText, plainText, sizeof(plainText)); + EVP_CIPHER_CTX_free(ctx); + + /* Decrypt. */ + ExpectNotNull((ctx = EVP_CIPHER_CTX_new())); + ExpectIntEQ(EVP_DecryptInit_ex(ctx, EVP_sm4_cbc(), NULL, NULL, NULL), + WOLFSSL_SUCCESS); + ExpectIntEQ(EVP_DecryptInit_ex(ctx, NULL, NULL, key, iv), WOLFSSL_SUCCESS); + ExpectIntEQ(EVP_DecryptUpdate(ctx, decryptedText, &outSz, cipherText, + sizeof(cipherText)), WOLFSSL_SUCCESS); + ExpectIntEQ(outSz, sizeof(plainText)); + ExpectIntEQ(EVP_DecryptFinal_ex(ctx, decryptedText + outSz, &outSz), + WOLFSSL_SUCCESS); + ExpectIntEQ(outSz, 0); + ExpectBufEQ(decryptedText, plainText, sizeof(plainText)); + EVP_CIPHER_CTX_free(ctx); + + /* Test partial Inits. CipherInit() allow setting of key and iv + * in separate calls. */ + ExpectNotNull((ctx = EVP_CIPHER_CTX_new())); + ExpectIntEQ(wolfSSL_EVP_CipherInit(ctx, EVP_sm4_cbc(), key, NULL, 0), + WOLFSSL_SUCCESS); + ExpectIntEQ(wolfSSL_EVP_CipherInit(ctx, NULL, NULL, iv, 0), + WOLFSSL_SUCCESS); + ExpectIntEQ(EVP_DecryptUpdate(ctx, decryptedText, &outSz, cipherText, + sizeof(cipherText)), WOLFSSL_SUCCESS); + ExpectIntEQ(outSz, sizeof(plainText)); + ExpectIntEQ(EVP_DecryptFinal_ex(ctx, decryptedText + outSz, &outSz), + WOLFSSL_SUCCESS); + ExpectIntEQ(outSz, 0); + ExpectBufEQ(decryptedText, plainText, sizeof(plainText)); + EVP_CIPHER_CTX_free(ctx); + + res = EXPECT_RESULT(); +#endif + return res; +} + +static int test_wolfssl_EVP_sm4_ctr(void) +{ + int res = TEST_SKIPPED; +#if defined(OPENSSL_EXTRA) && defined(WOLFSSL_SM4_CTR) + EXPECT_DECLS; + byte key[SM4_KEY_SIZE]; + byte iv[SM4_BLOCK_SIZE]; + byte plainText[] = {0xDE, 0xAD, 0xBE, 0xEF}; + byte cipherText[sizeof(plainText)]; + byte decryptedText[sizeof(plainText)]; + EVP_CIPHER_CTX* ctx; + int outSz; + + XMEMSET(key, 0, sizeof(key)); + XMEMSET(iv, 0, sizeof(iv)); + + /* Encrypt. */ + ExpectNotNull((ctx = EVP_CIPHER_CTX_new())); + ExpectIntEQ(EVP_EncryptInit_ex(ctx, EVP_sm4_ctr(), NULL, NULL, NULL), + WOLFSSL_SUCCESS); + /* Any tag length must fail - not an AEAD cipher. */ + ExpectIntEQ(EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG, 16, NULL), + WC_NO_ERR_TRACE(WOLFSSL_FAILURE)); + ExpectIntEQ(EVP_EncryptInit_ex(ctx, NULL, NULL, key, iv), WOLFSSL_SUCCESS); + ExpectIntEQ(EVP_EncryptUpdate(ctx, cipherText, &outSz, plainText, + sizeof(plainText)), WOLFSSL_SUCCESS); + ExpectIntEQ(outSz, sizeof(plainText)); + ExpectIntEQ(EVP_EncryptFinal_ex(ctx, cipherText, &outSz), WOLFSSL_SUCCESS); + ExpectIntEQ(outSz, 0); + ExpectBufNE(cipherText, plainText, sizeof(plainText)); + EVP_CIPHER_CTX_free(ctx); + + /* Decrypt. */ + ExpectNotNull((ctx = EVP_CIPHER_CTX_new())); + ExpectIntEQ(EVP_DecryptInit_ex(ctx, EVP_sm4_ctr(), NULL, NULL, NULL), + WOLFSSL_SUCCESS); + ExpectIntEQ(EVP_DecryptInit_ex(ctx, NULL, NULL, key, iv), WOLFSSL_SUCCESS); + ExpectIntEQ(EVP_DecryptUpdate(ctx, decryptedText, &outSz, cipherText, + sizeof(cipherText)), WOLFSSL_SUCCESS); + ExpectIntEQ(outSz, sizeof(cipherText)); + ExpectIntEQ(EVP_DecryptFinal_ex(ctx, decryptedText, &outSz), + WOLFSSL_SUCCESS); + ExpectIntEQ(outSz, 0); + ExpectBufEQ(decryptedText, plainText, sizeof(plainText)); + EVP_CIPHER_CTX_free(ctx); + + /* Test partial Inits. CipherInit() allow setting of key and iv + * in separate calls. */ + ExpectNotNull((ctx = EVP_CIPHER_CTX_new())); + ExpectIntEQ(wolfSSL_EVP_CipherInit(ctx, EVP_sm4_ctr(), key, NULL, 1), + WOLFSSL_SUCCESS); + ExpectIntEQ(wolfSSL_EVP_CipherInit(ctx, NULL, NULL, iv, 1), + WOLFSSL_SUCCESS); + ExpectIntEQ(EVP_DecryptUpdate(ctx, decryptedText, &outSz, cipherText, + sizeof(cipherText)), WOLFSSL_SUCCESS); + ExpectIntEQ(outSz, sizeof(cipherText)); + ExpectIntEQ(EVP_DecryptFinal_ex(ctx, decryptedText, &outSz), + WOLFSSL_SUCCESS); + ExpectIntEQ(outSz, 0); + ExpectBufEQ(decryptedText, plainText, sizeof(plainText)); + EVP_CIPHER_CTX_free(ctx); + + res = EXPECT_RESULT(); +#endif + return res; +} + +static int test_wolfssl_EVP_sm4_gcm_zeroLen(void) +{ + int res = TEST_SKIPPED; +#if defined(OPENSSL_EXTRA) && defined(WOLFSSL_SM4_GCM) + /* Zero length plain text */ + EXPECT_DECLS; + byte key[] = { + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 + }; /* align */ + byte iv[] = { + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 + }; /* align */ + byte plaintxt[1]; + int ivSz = 12; + int plaintxtSz = 0; + unsigned char tag[16]; + unsigned char tag_kat[16] = { + 0x23,0x2f,0x0c,0xfe,0x30,0x8b,0x49,0xea, + 0x6f,0xc8,0x82,0x29,0xb5,0xdc,0x85,0x8d + }; + + byte ciphertxt[SM4_BLOCK_SIZE * 4] = {0}; + byte decryptedtxt[SM4_BLOCK_SIZE * 4] = {0}; + int ciphertxtSz = 0; + int decryptedtxtSz = 0; + int len = 0; + + EVP_CIPHER_CTX *en = EVP_CIPHER_CTX_new(); + EVP_CIPHER_CTX *de = EVP_CIPHER_CTX_new(); + + ExpectIntEQ(1, EVP_EncryptInit_ex(en, EVP_sm4_gcm(), NULL, key, iv)); + ExpectIntEQ(1, EVP_CIPHER_CTX_ctrl(en, EVP_CTRL_GCM_SET_IVLEN, ivSz, NULL)); + ExpectIntEQ(1, EVP_EncryptUpdate(en, ciphertxt, &ciphertxtSz , plaintxt, + plaintxtSz)); + ExpectIntEQ(1, EVP_EncryptFinal_ex(en, ciphertxt, &len)); + ciphertxtSz += len; + ExpectIntEQ(1, EVP_CIPHER_CTX_ctrl(en, EVP_CTRL_GCM_GET_TAG, 16, tag)); + ExpectIntEQ(1, EVP_CIPHER_CTX_cleanup(en)); + + ExpectIntEQ(0, ciphertxtSz); + ExpectIntEQ(0, XMEMCMP(tag, tag_kat, sizeof(tag))); + + EVP_CIPHER_CTX_init(de); + ExpectIntEQ(1, EVP_DecryptInit_ex(de, EVP_sm4_gcm(), NULL, key, iv)); + ExpectIntEQ(1, EVP_CIPHER_CTX_ctrl(de, EVP_CTRL_GCM_SET_IVLEN, ivSz, NULL)); + ExpectIntEQ(1, EVP_DecryptUpdate(de, NULL, &len, ciphertxt, len)); + decryptedtxtSz = len; + ExpectIntEQ(1, EVP_CIPHER_CTX_ctrl(de, EVP_CTRL_GCM_SET_TAG, 16, tag)); + ExpectIntEQ(1, EVP_DecryptFinal_ex(de, decryptedtxt, &len)); + decryptedtxtSz += len; + ExpectIntEQ(0, decryptedtxtSz); + + EVP_CIPHER_CTX_free(en); + EVP_CIPHER_CTX_free(de); + + res = EXPECT_RESULT(); +#endif /* OPENSSL_EXTRA && WOLFSSL_SM4_GCM */ + return res; +} + +static int test_wolfssl_EVP_sm4_gcm(void) +{ + int res = TEST_SKIPPED; +#if defined(OPENSSL_EXTRA) && defined(WOLFSSL_SM4_GCM) + EXPECT_DECLS; + byte *key = (byte*)"0123456789012345"; + /* A 128 bit IV */ + byte *iv = (byte*)"0123456789012345"; + int ivSz = SM4_BLOCK_SIZE; + /* Message to be encrypted */ + byte *plaintxt = (byte*)"for things to change you have to change"; + /* Additional non-confidential data */ + byte *aad = (byte*)"Don't spend major time on minor things."; + + unsigned char tag[SM4_BLOCK_SIZE] = {0}; + int plaintxtSz = (int)XSTRLEN((char*)plaintxt); + int aadSz = (int)XSTRLEN((char*)aad); + byte ciphertxt[SM4_BLOCK_SIZE * 4] = {0}; + byte decryptedtxt[SM4_BLOCK_SIZE * 4] = {0}; + int ciphertxtSz = 0; + int decryptedtxtSz = 0; + int len = 0; + int i = 0; + EVP_CIPHER_CTX en[2]; + EVP_CIPHER_CTX de[2]; + + for (i = 0; i < 2; i++) { + EVP_CIPHER_CTX_init(&en[i]); + + if (i == 0) { + /* Default uses 96-bits IV length */ + ExpectIntEQ(1, EVP_EncryptInit_ex(&en[i], EVP_sm4_gcm(), NULL, key, + iv)); + } + else { + ExpectIntEQ(1, EVP_EncryptInit_ex(&en[i], EVP_sm4_gcm(), NULL, NULL, + NULL)); + /* non-default must to set the IV length first */ + ExpectIntEQ(1, EVP_CIPHER_CTX_ctrl(&en[i], EVP_CTRL_GCM_SET_IVLEN, + ivSz, NULL)); + ExpectIntEQ(1, EVP_EncryptInit_ex(&en[i], NULL, NULL, key, iv)); + } + ExpectIntEQ(1, EVP_EncryptUpdate(&en[i], NULL, &len, aad, aadSz)); + ExpectIntEQ(1, EVP_EncryptUpdate(&en[i], ciphertxt, &len, plaintxt, + plaintxtSz)); + ciphertxtSz = len; + ExpectIntEQ(1, EVP_EncryptFinal_ex(&en[i], ciphertxt, &len)); + ciphertxtSz += len; + ExpectIntEQ(1, EVP_CIPHER_CTX_ctrl(&en[i], EVP_CTRL_GCM_GET_TAG, + SM4_BLOCK_SIZE, tag)); + ExpectIntEQ(wolfSSL_EVP_CIPHER_CTX_cleanup(&en[i]), 1); + + EVP_CIPHER_CTX_init(&de[i]); + if (i == 0) { + /* Default uses 96-bits IV length */ + ExpectIntEQ(1, EVP_DecryptInit_ex(&de[i], EVP_sm4_gcm(), NULL, key, + iv)); + } + else { + ExpectIntEQ(1, EVP_DecryptInit_ex(&de[i], EVP_sm4_gcm(), NULL, NULL, + NULL)); + /* non-default must to set the IV length first */ + ExpectIntEQ(1, EVP_CIPHER_CTX_ctrl(&de[i], EVP_CTRL_GCM_SET_IVLEN, + ivSz, NULL)); + ExpectIntEQ(1, EVP_DecryptInit_ex(&de[i], NULL, NULL, key, iv)); + + } + ExpectIntEQ(1, EVP_DecryptUpdate(&de[i], NULL, &len, aad, aadSz)); + ExpectIntEQ(1, EVP_DecryptUpdate(&de[i], decryptedtxt, &len, ciphertxt, + ciphertxtSz)); + decryptedtxtSz = len; + ExpectIntEQ(1, EVP_CIPHER_CTX_ctrl(&de[i], EVP_CTRL_GCM_SET_TAG, + SM4_BLOCK_SIZE, tag)); + ExpectIntEQ(1, EVP_DecryptFinal_ex(&de[i], decryptedtxt, &len)); + decryptedtxtSz += len; + ExpectIntEQ(ciphertxtSz, decryptedtxtSz); + ExpectIntEQ(0, XMEMCMP(plaintxt, decryptedtxt, decryptedtxtSz)); + + /* modify tag*/ + tag[SM4_BLOCK_SIZE-1]+=0xBB; + ExpectIntEQ(1, EVP_DecryptUpdate(&de[i], NULL, &len, aad, aadSz)); + ExpectIntEQ(1, EVP_CIPHER_CTX_ctrl(&de[i], EVP_CTRL_GCM_SET_TAG, + SM4_BLOCK_SIZE, tag)); + /* fail due to wrong tag */ + ExpectIntEQ(1, EVP_DecryptUpdate(&de[i], decryptedtxt, &len, ciphertxt, + ciphertxtSz)); + ExpectIntEQ(0, EVP_DecryptFinal_ex(&de[i], decryptedtxt, &len)); + ExpectIntEQ(0, len); + ExpectIntEQ(wolfSSL_EVP_CIPHER_CTX_cleanup(&de[i]), 1); + } + + res = EXPECT_RESULT(); +#endif /* OPENSSL_EXTRA && WOLFSSL_SM4_GCM */ + return res; +} + +static int test_wolfssl_EVP_sm4_ccm_zeroLen(void) +{ + int res = TEST_SKIPPED; +#if defined(OPENSSL_EXTRA) && defined(WOLFSSL_SM4_CCM) + /* Zero length plain text */ + EXPECT_DECLS; + byte key[] = { + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 + }; /* align */ + byte iv[] = { + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 + }; /* align */ + byte plaintxt[1]; + int ivSz = 12; + int plaintxtSz = 0; + unsigned char tag[16]; + + byte ciphertxt[SM4_BLOCK_SIZE * 4] = {0}; + byte decryptedtxt[SM4_BLOCK_SIZE * 4] = {0}; + int ciphertxtSz = 0; + int decryptedtxtSz = 0; + int len = 0; + + EVP_CIPHER_CTX *en = EVP_CIPHER_CTX_new(); + EVP_CIPHER_CTX *de = EVP_CIPHER_CTX_new(); + + ExpectIntEQ(1, EVP_EncryptInit_ex(en, EVP_sm4_ccm(), NULL, key, iv)); + ExpectIntEQ(1, EVP_CIPHER_CTX_ctrl(en, EVP_CTRL_CCM_SET_IVLEN, ivSz, NULL)); + ExpectIntEQ(1, EVP_EncryptUpdate(en, ciphertxt, &ciphertxtSz , plaintxt, + plaintxtSz)); + ExpectIntEQ(1, EVP_EncryptFinal_ex(en, ciphertxt, &len)); + ciphertxtSz += len; + ExpectIntEQ(1, EVP_CIPHER_CTX_ctrl(en, EVP_CTRL_CCM_GET_TAG, 16, tag)); + ExpectIntEQ(1, EVP_CIPHER_CTX_cleanup(en)); + + ExpectIntEQ(0, ciphertxtSz); + + EVP_CIPHER_CTX_init(de); + ExpectIntEQ(1, EVP_DecryptInit_ex(de, EVP_sm4_ccm(), NULL, key, iv)); + ExpectIntEQ(1, EVP_CIPHER_CTX_ctrl(de, EVP_CTRL_CCM_SET_IVLEN, ivSz, NULL)); + ExpectIntEQ(1, EVP_DecryptUpdate(de, NULL, &len, ciphertxt, len)); + decryptedtxtSz = len; + ExpectIntEQ(1, EVP_CIPHER_CTX_ctrl(de, EVP_CTRL_CCM_SET_TAG, 16, tag)); + ExpectIntEQ(1, EVP_DecryptFinal_ex(de, decryptedtxt, &len)); + decryptedtxtSz += len; + ExpectIntEQ(0, decryptedtxtSz); + + EVP_CIPHER_CTX_free(en); + EVP_CIPHER_CTX_free(de); + + res = EXPECT_RESULT(); +#endif /* OPENSSL_EXTRA && WOLFSSL_SM4_CCM */ + return res; +} + +static int test_wolfssl_EVP_sm4_ccm(void) +{ + int res = TEST_SKIPPED; +#if defined(OPENSSL_EXTRA) && defined(WOLFSSL_SM4_CCM) + EXPECT_DECLS; + byte *key = (byte*)"0123456789012345"; + byte *iv = (byte*)"0123456789012"; + int ivSz = (int)XSTRLEN((char*)iv); + /* Message to be encrypted */ + byte *plaintxt = (byte*)"for things to change you have to change"; + /* Additional non-confidential data */ + byte *aad = (byte*)"Don't spend major time on minor things."; + + unsigned char tag[SM4_BLOCK_SIZE] = {0}; + int plaintxtSz = (int)XSTRLEN((char*)plaintxt); + int aadSz = (int)XSTRLEN((char*)aad); + byte ciphertxt[SM4_BLOCK_SIZE * 4] = {0}; + byte decryptedtxt[SM4_BLOCK_SIZE * 4] = {0}; + int ciphertxtSz = 0; + int decryptedtxtSz = 0; + int len = 0; + int i = 0; + EVP_CIPHER_CTX en[2]; + EVP_CIPHER_CTX de[2]; + + for (i = 0; i < 2; i++) { + EVP_CIPHER_CTX_init(&en[i]); + + if (i == 0) { + /* Default uses 96-bits IV length */ + ExpectIntEQ(1, EVP_EncryptInit_ex(&en[i], EVP_sm4_ccm(), NULL, key, + iv)); + } + else { + ExpectIntEQ(1, EVP_EncryptInit_ex(&en[i], EVP_sm4_ccm(), NULL, NULL, + NULL)); + /* non-default must to set the IV length first */ + ExpectIntEQ(1, EVP_CIPHER_CTX_ctrl(&en[i], EVP_CTRL_CCM_SET_IVLEN, + ivSz, NULL)); + ExpectIntEQ(1, EVP_EncryptInit_ex(&en[i], NULL, NULL, key, iv)); + } + ExpectIntEQ(1, EVP_EncryptUpdate(&en[i], NULL, &len, aad, aadSz)); + ExpectIntEQ(1, EVP_EncryptUpdate(&en[i], ciphertxt, &len, plaintxt, + plaintxtSz)); + ciphertxtSz = len; + ExpectIntEQ(1, EVP_EncryptFinal_ex(&en[i], ciphertxt, &len)); + ciphertxtSz += len; + ExpectIntEQ(1, EVP_CIPHER_CTX_ctrl(&en[i], EVP_CTRL_CCM_GET_TAG, + SM4_BLOCK_SIZE, tag)); + ExpectIntEQ(wolfSSL_EVP_CIPHER_CTX_cleanup(&en[i]), 1); + + EVP_CIPHER_CTX_init(&de[i]); + if (i == 0) { + /* Default uses 96-bits IV length */ + ExpectIntEQ(1, EVP_DecryptInit_ex(&de[i], EVP_sm4_ccm(), NULL, key, + iv)); + } + else { + ExpectIntEQ(1, EVP_DecryptInit_ex(&de[i], EVP_sm4_ccm(), NULL, NULL, + NULL)); + /* non-default must to set the IV length first */ + ExpectIntEQ(1, EVP_CIPHER_CTX_ctrl(&de[i], EVP_CTRL_CCM_SET_IVLEN, + ivSz, NULL)); + ExpectIntEQ(1, EVP_DecryptInit_ex(&de[i], NULL, NULL, key, iv)); + + } + ExpectIntEQ(1, EVP_DecryptUpdate(&de[i], NULL, &len, aad, aadSz)); + ExpectIntEQ(1, EVP_DecryptUpdate(&de[i], decryptedtxt, &len, ciphertxt, + ciphertxtSz)); + decryptedtxtSz = len; + ExpectIntEQ(1, EVP_CIPHER_CTX_ctrl(&de[i], EVP_CTRL_CCM_SET_TAG, + SM4_BLOCK_SIZE, tag)); + ExpectIntEQ(1, EVP_DecryptFinal_ex(&de[i], decryptedtxt, &len)); + decryptedtxtSz += len; + ExpectIntEQ(ciphertxtSz, decryptedtxtSz); + ExpectIntEQ(0, XMEMCMP(plaintxt, decryptedtxt, decryptedtxtSz)); + + /* modify tag*/ + tag[SM4_BLOCK_SIZE-1]+=0xBB; + ExpectIntEQ(1, EVP_DecryptUpdate(&de[i], NULL, &len, aad, aadSz)); + ExpectIntEQ(1, EVP_CIPHER_CTX_ctrl(&de[i], EVP_CTRL_CCM_SET_TAG, + SM4_BLOCK_SIZE, tag)); + /* fail due to wrong tag */ + ExpectIntEQ(1, EVP_DecryptUpdate(&de[i], decryptedtxt, &len, ciphertxt, + ciphertxtSz)); + ExpectIntEQ(0, EVP_DecryptFinal_ex(&de[i], decryptedtxt, &len)); + ExpectIntEQ(0, len); + ExpectIntEQ(wolfSSL_EVP_CIPHER_CTX_cleanup(&de[i]), 1); + } + + res = EXPECT_RESULT(); +#endif /* OPENSSL_EXTRA && WOLFSSL_SM4_CCM */ + return res; +} + +static int test_wolfSSL_EVP_PKEY_hkdf(void) +{ + EXPECT_DECLS; +#if defined(OPENSSL_EXTRA) && defined(HAVE_HKDF) + EVP_PKEY_CTX* ctx = NULL; + byte salt[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F}; + byte key[] = {0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F}; + byte info[] = {0X01, 0x02, 0x03, 0x04, 0x05}; + byte info2[] = {0X06, 0x07, 0x08, 0x09, 0x0A}; + byte outKey[34]; + size_t outKeySz = sizeof(outKey); + /* These expected outputs were gathered by running the same test below using + * OpenSSL. */ + const byte extractAndExpand[] = { + 0x8B, 0xEB, 0x90, 0xA9, 0x04, 0xFF, 0x05, 0x10, 0xE4, 0xB5, 0xB1, 0x10, + 0x31, 0x34, 0xFF, 0x07, 0x5B, 0xE3, 0xC6, 0x93, 0xD4, 0xF8, 0xC7, 0xEE, + 0x96, 0xDA, 0x78, 0x7A, 0xE2, 0x9A, 0x2D, 0x05, 0x4B, 0xF6 + }; + const byte extractOnly[] = { + 0xE7, 0x6B, 0x9E, 0x0F, 0xE4, 0x02, 0x1D, 0x62, 0xEA, 0x97, 0x74, 0x5E, + 0xF4, 0x3C, 0x65, 0x4D, 0xC1, 0x46, 0x98, 0xAA, 0x79, 0x9A, 0xCB, 0x9C, + 0xCC, 0x3E, 0x7F, 0x2A, 0x2B, 0x41, 0xA1, 0x9E + }; + const byte expandOnly[] = { + 0xFF, 0x29, 0x29, 0x56, 0x9E, 0xA7, 0x66, 0x02, 0xDB, 0x4F, 0xDB, 0x53, + 0x7D, 0x21, 0x67, 0x52, 0xC3, 0x0E, 0xF3, 0xFC, 0x71, 0xCE, 0x67, 0x2B, + 0xEA, 0x3B, 0xE9, 0xFC, 0xDD, 0xC8, 0xCC, 0xB7, 0x42, 0x74 + }; + const byte extractAndExpandAddInfo[] = { + 0x5A, 0x74, 0x79, 0x83, 0xA3, 0xA4, 0x2E, 0xB7, 0xD4, 0x08, 0xC2, 0x6A, + 0x2F, 0xA5, 0xE3, 0x4E, 0xF1, 0xF4, 0x87, 0x3E, 0xA6, 0xC7, 0x88, 0x45, + 0xD7, 0xE2, 0x15, 0xBC, 0xB8, 0x10, 0xEF, 0x6C, 0x4D, 0x7A + }; + ExpectNotNull((ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_HKDF, NULL))); + ExpectIntEQ(EVP_PKEY_derive_init(ctx), WOLFSSL_SUCCESS); + /* NULL ctx. */ + ExpectIntEQ(EVP_PKEY_CTX_set_hkdf_md(NULL, EVP_sha256()), WC_NO_ERR_TRACE(WOLFSSL_FAILURE)); + /* NULL md. */ + ExpectIntEQ(EVP_PKEY_CTX_set_hkdf_md(ctx, NULL), WC_NO_ERR_TRACE(WOLFSSL_FAILURE)); + ExpectIntEQ(EVP_PKEY_CTX_set_hkdf_md(ctx, EVP_sha256()), WOLFSSL_SUCCESS); + /* NULL ctx. */ + ExpectIntEQ(EVP_PKEY_CTX_set1_hkdf_salt(NULL, salt, sizeof(salt)), + WC_NO_ERR_TRACE(WOLFSSL_FAILURE)); + /* NULL salt is ok. */ + ExpectIntEQ(EVP_PKEY_CTX_set1_hkdf_salt(ctx, NULL, sizeof(salt)), + WOLFSSL_SUCCESS); + /* Salt length <= 0. */ + /* Length 0 salt is ok. */ + ExpectIntEQ(EVP_PKEY_CTX_set1_hkdf_salt(ctx, salt, 0), WOLFSSL_SUCCESS); + ExpectIntEQ(EVP_PKEY_CTX_set1_hkdf_salt(ctx, salt, -1), WC_NO_ERR_TRACE(WOLFSSL_FAILURE)); + ExpectIntEQ(EVP_PKEY_CTX_set1_hkdf_salt(ctx, salt, sizeof(salt)), + WOLFSSL_SUCCESS); + /* NULL ctx. */ + ExpectIntEQ(EVP_PKEY_CTX_set1_hkdf_key(NULL, key, sizeof(key)), + WC_NO_ERR_TRACE(WOLFSSL_FAILURE)); + /* NULL key. */ + ExpectIntEQ(EVP_PKEY_CTX_set1_hkdf_key(ctx, NULL, sizeof(key)), + WC_NO_ERR_TRACE(WOLFSSL_FAILURE)); + /* Key length <= 0 */ + ExpectIntEQ(EVP_PKEY_CTX_set1_hkdf_key(ctx, key, 0), WC_NO_ERR_TRACE(WOLFSSL_FAILURE)); + ExpectIntEQ(EVP_PKEY_CTX_set1_hkdf_key(ctx, key, -1), WC_NO_ERR_TRACE(WOLFSSL_FAILURE)); + ExpectIntEQ(EVP_PKEY_CTX_set1_hkdf_key(ctx, key, sizeof(key)), + WOLFSSL_SUCCESS); + /* NULL ctx. */ + ExpectIntEQ(EVP_PKEY_CTX_add1_hkdf_info(NULL, info, sizeof(info)), + WC_NO_ERR_TRACE(WOLFSSL_FAILURE)); + /* NULL info is ok. */ + ExpectIntEQ(EVP_PKEY_CTX_add1_hkdf_info(ctx, NULL, sizeof(info)), + WOLFSSL_SUCCESS); + /* Info length <= 0 */ + /* Length 0 info is ok. */ + ExpectIntEQ(EVP_PKEY_CTX_add1_hkdf_info(ctx, info, 0), WOLFSSL_SUCCESS); + ExpectIntEQ(EVP_PKEY_CTX_add1_hkdf_info(ctx, info, -1), WC_NO_ERR_TRACE(WOLFSSL_FAILURE)); + ExpectIntEQ(EVP_PKEY_CTX_add1_hkdf_info(ctx, info, sizeof(info)), + WOLFSSL_SUCCESS); + /* NULL ctx. */ + ExpectIntEQ(EVP_PKEY_CTX_hkdf_mode(NULL, EVP_PKEY_HKDEF_MODE_EXTRACT_ONLY), + WC_NO_ERR_TRACE(WOLFSSL_FAILURE)); + /* Extract and expand (default). */ + ExpectIntEQ(EVP_PKEY_derive(ctx, outKey, &outKeySz), WOLFSSL_SUCCESS); + ExpectIntEQ(outKeySz, sizeof(extractAndExpand)); + ExpectIntEQ(XMEMCMP(outKey, extractAndExpand, outKeySz), 0); + /* Extract only. */ + ExpectIntEQ(EVP_PKEY_CTX_hkdf_mode(ctx, EVP_PKEY_HKDEF_MODE_EXTRACT_ONLY), + WOLFSSL_SUCCESS); + ExpectIntEQ(EVP_PKEY_derive(ctx, outKey, &outKeySz), WOLFSSL_SUCCESS); + ExpectIntEQ(outKeySz, sizeof(extractOnly)); + ExpectIntEQ(XMEMCMP(outKey, extractOnly, outKeySz), 0); + outKeySz = sizeof(outKey); + /* Expand only. */ + ExpectIntEQ(EVP_PKEY_CTX_hkdf_mode(ctx, EVP_PKEY_HKDEF_MODE_EXPAND_ONLY), + WOLFSSL_SUCCESS); + ExpectIntEQ(EVP_PKEY_derive(ctx, outKey, &outKeySz), WOLFSSL_SUCCESS); + ExpectIntEQ(outKeySz, sizeof(expandOnly)); + ExpectIntEQ(XMEMCMP(outKey, expandOnly, outKeySz), 0); + outKeySz = sizeof(outKey); + /* Extract and expand with appended additional info. */ + ExpectIntEQ(EVP_PKEY_CTX_add1_hkdf_info(ctx, info2, sizeof(info2)), + WOLFSSL_SUCCESS); + ExpectIntEQ(EVP_PKEY_CTX_hkdf_mode(ctx, + EVP_PKEY_HKDEF_MODE_EXTRACT_AND_EXPAND), WOLFSSL_SUCCESS); + ExpectIntEQ(EVP_PKEY_derive(ctx, outKey, &outKeySz), WOLFSSL_SUCCESS); + ExpectIntEQ(outKeySz, sizeof(extractAndExpandAddInfo)); + ExpectIntEQ(XMEMCMP(outKey, extractAndExpandAddInfo, outKeySz), 0); + + EVP_PKEY_CTX_free(ctx); +#endif /* OPENSSL_EXTRA && HAVE_HKDF */ + return EXPECT_RESULT(); +} + +#ifndef NO_BIO +static int test_wolfSSL_PEM_X509_INFO_read_bio(void) +{ + EXPECT_DECLS; +#if defined(OPENSSL_ALL) && !defined(NO_FILESYSTEM) && !defined(NO_RSA) + BIO* bio = NULL; + X509_INFO* info = NULL; + STACK_OF(X509_INFO)* sk = NULL; + STACK_OF(X509_INFO)* sk2 = NULL; + char* subject = NULL; + char exp1[] = "/C=US/ST=Montana/L=Bozeman/O=Sawtooth/OU=Consulting/" + "CN=www.wolfssl.com/emailAddress=info@wolfssl.com"; + char exp2[] = "/C=US/ST=Montana/L=Bozeman/O=wolfSSL/OU=Support/" + "CN=www.wolfssl.com/emailAddress=info@wolfssl.com"; + + ExpectNotNull(bio = BIO_new(BIO_s_file())); + ExpectIntGT(BIO_read_filename(bio, svrCertFile), 0); + ExpectNotNull(sk = PEM_X509_INFO_read_bio(bio, NULL, NULL, NULL)); + ExpectIntEQ(sk_X509_INFO_num(sk), 2); + + /* using dereference to maintain testing for Apache port*/ + ExpectNull(sk_X509_INFO_pop(NULL)); + ExpectNotNull(info = sk_X509_INFO_pop(sk)); + ExpectNotNull(subject = X509_NAME_oneline(X509_get_subject_name(info->x509), + 0, 0)); + + ExpectIntEQ(0, XSTRNCMP(subject, exp1, sizeof(exp1))); + XFREE(subject, 0, DYNAMIC_TYPE_OPENSSL); + subject = NULL; + X509_INFO_free(info); + info = NULL; + + ExpectNotNull(info = sk_X509_INFO_pop(sk)); + ExpectNotNull(subject = X509_NAME_oneline(X509_get_subject_name(info->x509), + 0, 0)); + + ExpectIntEQ(0, XSTRNCMP(subject, exp2, sizeof(exp2))); + XFREE(subject, 0, DYNAMIC_TYPE_OPENSSL); + subject = NULL; + X509_INFO_free(info); + ExpectNull(info = sk_X509_INFO_pop(sk)); + + sk_X509_INFO_pop_free(sk, X509_INFO_free); + sk = NULL; + BIO_free(bio); + bio = NULL; + + ExpectNotNull(sk = wolfSSL_sk_X509_INFO_new_null()); + ExpectNotNull(bio = BIO_new(BIO_s_file())); + ExpectIntGT(BIO_read_filename(bio, svrCertFile), 0); + ExpectNotNull(sk2 = PEM_X509_INFO_read_bio(bio, sk, NULL, NULL)); + ExpectPtrEq(sk, sk2); + if (sk2 != sk) { + sk_X509_INFO_pop_free(sk, X509_INFO_free); + } + sk = NULL; + BIO_free(bio); + sk_X509_INFO_pop_free(sk2, X509_INFO_free); + + ExpectNotNull(sk = wolfSSL_sk_X509_INFO_new_null()); + sk_X509_INFO_free(sk); +#endif + return EXPECT_RESULT(); +} + +static int test_wolfSSL_PEM_X509_INFO_read(void) +{ + EXPECT_DECLS; +#if defined(OPENSSL_ALL) && !defined(NO_FILESYSTEM) && !defined(NO_RSA) + XFILE fp = XBADFILE; + STACK_OF(X509_INFO)* sk = NULL; + + ExpectTrue((fp = XFOPEN(svrCertFile, "rb")) != XBADFILE); + ExpectNull(wolfSSL_PEM_X509_INFO_read(XBADFILE, NULL, NULL, NULL)); + ExpectNotNull(sk = wolfSSL_PEM_X509_INFO_read(fp, NULL, NULL, NULL)); + + sk_X509_INFO_pop_free(sk, X509_INFO_free); + if (fp != XBADFILE) + XFCLOSE(fp); +#endif + return EXPECT_RESULT(); +} +#endif /* !NO_BIO */ + +static int test_wolfSSL_X509_NAME_ENTRY_get_object(void) +{ + EXPECT_DECLS; +#if defined(OPENSSL_EXTRA) && !defined(NO_FILESYSTEM) && !defined(NO_RSA) + X509 *x509 = NULL; + X509_NAME* name = NULL; + int idx = 0; + X509_NAME_ENTRY *ne = NULL; + ASN1_OBJECT *object = NULL; + + ExpectNotNull(x509 = wolfSSL_X509_load_certificate_file(cliCertFile, + WOLFSSL_FILETYPE_PEM)); + ExpectNotNull(name = X509_get_subject_name(x509)); + ExpectIntGE(X509_NAME_get_index_by_NID(NULL, NID_commonName, -1), + BAD_FUNC_ARG); + ExpectIntGE(idx = X509_NAME_get_index_by_NID(name, NID_commonName, -1), 0); + ExpectIntGE(idx = X509_NAME_get_index_by_NID(name, NID_commonName, -2), 0); + + ExpectNotNull(ne = X509_NAME_get_entry(name, idx)); + ExpectNull(X509_NAME_ENTRY_get_object(NULL)); + ExpectNotNull(object = X509_NAME_ENTRY_get_object(ne)); + + X509_free(x509); +#endif + return EXPECT_RESULT(); +} + +static int test_wolfSSL_X509_STORE_get1_certs(void) +{ + EXPECT_DECLS; +#if defined(OPENSSL_EXTRA) && defined(WOLFSSL_SIGNER_DER_CERT) && \ + !defined(NO_FILESYSTEM) && !defined(NO_RSA) + X509_STORE_CTX *storeCtx = NULL; + X509_STORE *store = NULL; + X509 *caX509 = NULL; + X509 *svrX509 = NULL; + X509_NAME *subject = NULL; + WOLF_STACK_OF(WOLFSSL_X509) *certs = NULL; + + ExpectNotNull(caX509 = X509_load_certificate_file(caCertFile, + SSL_FILETYPE_PEM)); + ExpectNotNull((svrX509 = wolfSSL_X509_load_certificate_file(svrCertFile, + SSL_FILETYPE_PEM))); + ExpectNotNull(storeCtx = X509_STORE_CTX_new()); + ExpectNotNull(store = X509_STORE_new()); + ExpectNotNull(subject = X509_get_subject_name(caX509)); + + /* Errors */ + ExpectNull(X509_STORE_get1_certs(storeCtx, subject)); + ExpectNull(X509_STORE_get1_certs(NULL, subject)); + ExpectNull(X509_STORE_get1_certs(storeCtx, NULL)); + + ExpectIntEQ(X509_STORE_add_cert(store, caX509), SSL_SUCCESS); + ExpectIntEQ(X509_STORE_CTX_init(storeCtx, store, caX509, NULL), + SSL_SUCCESS); + + /* Should find the cert */ + ExpectNotNull(certs = X509_STORE_get1_certs(storeCtx, subject)); + ExpectIntEQ(1, wolfSSL_sk_X509_num(certs)); + + sk_X509_pop_free(certs, NULL); + certs = NULL; + + /* Should not find the cert */ + ExpectNotNull(subject = X509_get_subject_name(svrX509)); + ExpectNotNull(certs = X509_STORE_get1_certs(storeCtx, subject)); + ExpectIntEQ(0, wolfSSL_sk_X509_num(certs)); + + sk_X509_pop_free(certs, NULL); + certs = NULL; + + X509_STORE_free(store); + X509_STORE_CTX_free(storeCtx); + X509_free(svrX509); + X509_free(caX509); +#endif /* OPENSSL_EXTRA && WOLFSSL_SIGNER_DER_CERT && !NO_FILESYSTEM */ + return EXPECT_RESULT(); +} + +#if defined(HAVE_SSL_MEMIO_TESTS_DEPENDENCIES) && \ + defined(WOLFSSL_LOCAL_X509_STORE) && \ + (defined(OPENSSL_ALL) || defined(WOLFSSL_QT)) && defined(HAVE_CRL) +static int test_wolfSSL_X509_STORE_set_get_crl_provider(X509_STORE_CTX* ctx, + X509_CRL** crl_out, X509* cert) { + X509_CRL *crl = NULL; + XFILE fp = XBADFILE; + char* cert_issuer = X509_NAME_oneline(X509_get_issuer_name(cert), NULL, 0); + int ret = 0; + + (void)ctx; + + if (cert_issuer == NULL) + return 0; + + if ((fp = XFOPEN("certs/crl/crl.pem", "rb")) != XBADFILE) { + PEM_read_X509_CRL(fp, &crl, NULL, NULL); + XFCLOSE(fp); + if (crl != NULL) { + char* crl_issuer = X509_NAME_oneline( + X509_CRL_get_issuer(crl), NULL, 0); + if ((crl_issuer != NULL) && + (XSTRCMP(cert_issuer, crl_issuer) == 0)) { + *crl_out = X509_CRL_dup(crl); + if (*crl_out != NULL) + ret = 1; + } + OPENSSL_free(crl_issuer); + } + } + + X509_CRL_free(crl); + OPENSSL_free(cert_issuer); + return ret; +} + +static int test_wolfSSL_X509_STORE_set_get_crl_provider2(X509_STORE_CTX* ctx, + X509_CRL** crl_out, X509* cert) { + (void)ctx; + (void)cert; + *crl_out = NULL; + return 1; +} + +#ifndef NO_WOLFSSL_STUB +static int test_wolfSSL_X509_STORE_set_get_crl_check(X509_STORE_CTX* ctx, + X509_CRL* crl) { + (void)ctx; + (void)crl; + return 1; +} +#endif + +static int test_wolfSSL_X509_STORE_set_get_crl_verify(int ok, + X509_STORE_CTX* ctx) { + int cert_error = X509_STORE_CTX_get_error(ctx); + X509_VERIFY_PARAM* param = X509_STORE_CTX_get0_param(ctx); + int flags = X509_VERIFY_PARAM_get_flags(param); + if ((flags & (X509_V_FLAG_CRL_CHECK | X509_V_FLAG_CRL_CHECK_ALL)) != + (X509_V_FLAG_CRL_CHECK | X509_V_FLAG_CRL_CHECK_ALL)) { + /* Make sure the flags are set */ + return 0; + } + /* Ignore CRL missing error */ +#ifndef OPENSSL_COMPATIBLE_DEFAULTS + if (cert_error == WC_NO_ERR_TRACE(CRL_MISSING)) +#else + if (cert_error == X509_V_ERR_UNABLE_TO_GET_CRL) +#endif + return 1; + return ok; +} + +static int test_wolfSSL_X509_STORE_set_get_crl_ctx_ready(WOLFSSL_CTX* ctx) +{ + EXPECT_DECLS; + X509_STORE* cert_store = NULL; + + ExpectIntEQ(wolfSSL_CTX_EnableCRL(ctx, WOLFSSL_CRL_CHECKALL), + WOLFSSL_SUCCESS); + ExpectNotNull(cert_store = SSL_CTX_get_cert_store(ctx)); + X509_STORE_set_get_crl(cert_store, + test_wolfSSL_X509_STORE_set_get_crl_provider); +#ifndef NO_WOLFSSL_STUB + X509_STORE_set_check_crl(cert_store, + test_wolfSSL_X509_STORE_set_get_crl_check); +#endif + + return EXPECT_RESULT(); +} + +static int test_wolfSSL_X509_STORE_set_get_crl_ctx_ready2(WOLFSSL_CTX* ctx) +{ + EXPECT_DECLS; + X509_STORE* cert_store = NULL; + X509_VERIFY_PARAM* param = NULL; + + SSL_CTX_set_verify(ctx, WOLFSSL_VERIFY_PEER, NULL); + ExpectIntEQ(wolfSSL_CTX_EnableCRL(ctx, WOLFSSL_CRL_CHECKALL), + WOLFSSL_SUCCESS); + ExpectNotNull(cert_store = SSL_CTX_get_cert_store(ctx)); + X509_STORE_set_get_crl(cert_store, + test_wolfSSL_X509_STORE_set_get_crl_provider2); +#ifndef NO_WOLFSSL_STUB + X509_STORE_set_check_crl(cert_store, + test_wolfSSL_X509_STORE_set_get_crl_check); +#endif + X509_STORE_set_verify_cb(cert_store, + test_wolfSSL_X509_STORE_set_get_crl_verify); + ExpectNotNull(X509_STORE_get0_param(cert_store)); + ExpectNotNull(param = X509_VERIFY_PARAM_new()); + ExpectIntEQ(X509_VERIFY_PARAM_inherit(NULL, NULL) , WOLFSSL_SUCCESS); + ExpectIntEQ(X509_VERIFY_PARAM_inherit(param, NULL) , WOLFSSL_SUCCESS); + ExpectIntEQ(X509_VERIFY_PARAM_inherit(param, + X509_STORE_get0_param(cert_store)), WOLFSSL_SUCCESS); + ExpectIntEQ(X509_VERIFY_PARAM_inherit(param, + X509_STORE_get0_param(cert_store)), 1); + ExpectIntEQ(X509_VERIFY_PARAM_set_flags( + param, X509_V_FLAG_CRL_CHECK | X509_V_FLAG_CRL_CHECK_ALL), 1); + ExpectIntEQ(X509_STORE_set1_param(cert_store, param), 1); + ExpectIntEQ(X509_STORE_set_flags(cert_store, + X509_V_FLAG_CRL_CHECK | X509_V_FLAG_CRL_CHECK_ALL), 1); + + + X509_VERIFY_PARAM_free(param); + return EXPECT_RESULT(); +} +#endif + +/* This test mimics the usage of the CRL provider in gRPC */ +static int test_wolfSSL_X509_STORE_set_get_crl(void) +{ + EXPECT_DECLS; +#if defined(HAVE_SSL_MEMIO_TESTS_DEPENDENCIES) && \ + defined(WOLFSSL_LOCAL_X509_STORE) && \ + (defined(OPENSSL_ALL) || defined(WOLFSSL_QT)) && defined(HAVE_CRL) + test_ssl_cbf func_cb_client; + test_ssl_cbf func_cb_server; + + XMEMSET(&func_cb_client, 0, sizeof(func_cb_client)); + XMEMSET(&func_cb_server, 0, sizeof(func_cb_server)); + + func_cb_client.ctx_ready = test_wolfSSL_X509_STORE_set_get_crl_ctx_ready; + + ExpectIntEQ(test_wolfSSL_client_server_nofail_memio(&func_cb_client, + &func_cb_server, NULL), TEST_SUCCESS); + + XMEMSET(&func_cb_client, 0, sizeof(func_cb_client)); + XMEMSET(&func_cb_server, 0, sizeof(func_cb_server)); + + func_cb_client.ctx_ready = test_wolfSSL_X509_STORE_set_get_crl_ctx_ready2; + + ExpectIntEQ(test_wolfSSL_client_server_nofail_memio(&func_cb_client, + &func_cb_server, NULL), TEST_SUCCESS); +#endif + return EXPECT_RESULT(); +} + static int test_wolfSSL_dup_CA_list(void) { int res = TEST_SKIPPED; diff --git a/tests/api/test_ecc.c b/tests/api/test_ecc.c index 69fd8b1e955..a5f0c7d7afd 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; @@ -1519,7 +1521,7 @@ int test_wc_ecc_shared_secret_ssh(void) ExpectIntEQ(wc_ecc_set_rng(&key, &rng), 0); #endif - ExpectIntEQ(wc_ecc_shared_secret_ssh(&key, &key2.pubkey, secret, + ExpectIntEQ(wc_ecc_shared_secret_ssh(&key, key2.pubkey, secret, &secretLen), 0); /* Pass in bad args. */ ExpectIntEQ(wc_ecc_shared_secret_ssh(NULL, &key2.pubkey, secret, @@ -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; 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 3e1dcf050fd..aebdde3c3fc 100644 --- a/wolfcrypt/benchmark/benchmark.c +++ b/wolfcrypt/benchmark/benchmark.c @@ -819,7 +819,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 +2050,9 @@ static const char* bench_result_words2[][6] = { }; #endif #endif +#if defined(WOLFSSL_MICROCHIP_TA100) + #include +#endif #ifdef WOLFSSL_CAAM #include @@ -2078,7 +2080,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 +9990,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 +10131,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 +12160,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 +12175,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 +12374,10 @@ 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 - +#if defined(WOLFSSL_MICROCHIP_TA100) + atmel_ecc_free(ATMEL_SLOT_ECDHE_ALICE); + atmel_ecc_free(ATMEL_SLOT_ECDHE_BOB); +#endif (void)useDeviceID; (void)pending; (void)x; diff --git a/wolfcrypt/src/aes.c b/wolfcrypt/src/aes.c index 823fc6aef88..28f6602afa2 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 @@ -5057,7 +5059,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 @@ -9824,7 +9837,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, @@ -10548,6 +10576,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 */ @@ -13452,7 +13494,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 da309eb2ab9..b9a18bb1912 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..f35e6ef3aaa 100644 --- a/wolfcrypt/src/port/atmel/README.md +++ b/wolfcrypt/src/port/atmel/README.md @@ -96,5 +96,75 @@ 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 + +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..351f5d88731 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,161 @@ 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 + #define MAP_TO_HANDLE(value) (SHARED_DATA_ADDR + (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 +260,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 +336,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 +368,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 +447,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 +467,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 +567,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 +590,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 +608,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 +630,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 +753,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 +1216,19 @@ 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 */ + atmel_createHandles(); + #endif } /* show revision information */ @@ -577,7 +1258,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 +1298,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 +1373,8 @@ 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(MAP_TO_HANDLE(slotId), otherKey->dp->id, + peerKey); if (ret != ATCA_SUCCESS) { goto exit; } @@ -731,7 +1414,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 +1503,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 +1596,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 +1627,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 +1645,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 +1654,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 +1691,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 +1756,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 +1766,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 +1776,7 @@ int atcatls_set_callbacks(WOLFSSL_CTX* ctx) #endif } #endif +#endif /* ATCA_TFLEX_SUPPORT */ return ret; } @@ -1100,4 +1792,204 @@ 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); + + /* 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); + } + + 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 6cfb368f1e3..ee7e0ce23c2 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; } @@ -3380,6 +3382,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, @@ -3542,6 +3562,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, @@ -4236,6 +4275,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) @@ -4285,6 +4335,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) @@ -4392,6 +4453,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 = 2048 / 8; + } +#endif + #ifdef WOLF_CRYPTO_CB if (ret == 0 && key->devId != INVALID_DEVID) { if (wc_CryptoCb_RsaGetSize(key, &ret) == WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE)) { @@ -4843,7 +4910,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; @@ -4886,6 +4954,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..28607ad4b26 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 2048-bit RSA key. */ + if (r->rKeyH != 0 || r->uKeyH != 0) { + sig_len = 256; + } + } +#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 dddcfc99670..6ffe47a0a49 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 037ef6b9401..56e9b05f017 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 */ @@ -2670,7 +2675,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 */ @@ -21285,7 +21291,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 @@ -22000,6 +22006,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)) @@ -22057,6 +22070,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); @@ -22185,8 +22205,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) @@ -22195,6 +22220,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 @@ -22703,6 +22731,7 @@ 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; + word32 sigSz; word32 plainSz; word32 digestSz; int i, j; @@ -22713,6 +22742,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, @@ -22747,6 +22780,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); @@ -22790,11 +22824,29 @@ 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; + /* Preserve signature length for TA100 verify. */ + sigSz = outSz; 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, @@ -22823,6 +22875,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++) { @@ -24028,7 +24081,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) @@ -24042,7 +24096,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; @@ -24103,7 +24157,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); } @@ -24118,7 +24174,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 */ @@ -24126,7 +24181,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) @@ -24671,11 +24725,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 */ @@ -24689,12 +24770,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) @@ -24745,18 +24837,7 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t rsa_test(void) ERROR_OUT(WC_TEST_RET_ENC_NC, exit_rsa); } TEST_SLEEP(); - - do { -#if defined(WOLFSSL_ASYNC_CRYPT) - ret = wc_AsyncWait(ret, &key->asyncDev, WC_ASYNC_FLAG_CALL_AGAIN); -#endif - if (ret >= 0) { - ret = wc_RsaSSL_Sign(in, inLen, out, outSz, key, &rng); - } - } while (ret == WC_NO_ERR_TRACE(WC_PENDING_E)); - if (ret < 0) - ERROR_OUT(WC_TEST_RET_ENC_EC(ret), exit_rsa); - TEST_SLEEP(); +#endif /* !WOLFSSL_MICROCHIP_TA100 */ #elif defined(WOLFSSL_PUBLIC_MP) { @@ -24969,7 +25050,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; @@ -25100,6 +25182,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) @@ -33674,7 +33760,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; @@ -33709,7 +33796,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 @@ -33725,7 +33813,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 @@ -33780,6 +33869,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); @@ -33807,9 +33899,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); @@ -33925,7 +34021,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 { @@ -34073,7 +34170,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) @@ -34114,7 +34211,10 @@ 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 - +#if defined(WOLFSSL_MICROCHIP_TA100) + atmel_ecc_free(ATMEL_SLOT_ECDHE_ALICE); + atmel_ecc_free(ATMEL_SLOT_ECDHE_BOB); +#endif (void)keySize; (void)curve_id; (void)rng; @@ -34152,7 +34252,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 @@ -34205,6 +34305,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) @@ -34494,7 +34595,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) { @@ -34607,8 +34708,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) @@ -34691,10 +34793,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; @@ -34789,7 +34892,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) @@ -34835,13 +34939,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; @@ -36664,6 +36771,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(); @@ -36797,8 +36905,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"); @@ -37656,7 +37765,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 fa077bfe8e4..e44fc3632c9 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..e28f3159bde 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,79 @@ 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) + +#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 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..00d3ac72625 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[TA_KEY_TYPE_RSA2048_SIZE]; /* public key */ +#endif #ifdef WOLF_CRYPTO_CB void* devCtx; int devId; diff --git a/wolfssl/wolfcrypt/settings.h b/wolfssl/wolfcrypt/settings.h index bf3029791cf..9071fe7b3f7 100644 --- a/wolfssl/wolfcrypt/settings.h +++ b/wolfssl/wolfcrypt/settings.h @@ -1180,7 +1180,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 @@ -3083,6 +3085,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