diff --git a/configure.ac b/configure.ac index 7a9ec151d1..9761841611 100644 --- a/configure.ac +++ b/configure.ac @@ -2975,15 +2975,41 @@ 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/)])], + [AS_HELP_STRING([--with-cryptoauthlib=PATH],[PATH to CryptoAuthLib install (default /usr)])], [ AC_MSG_CHECKING([for cryptoauthlib]) - CPPFLAGS="$CPPFLAGS -DWOLFSSL_ATECC508A" - LIBS="$LIBS -lcryptoauth" + LIBS="$LIBS -lcryptoauth -lwolfssl -lpthread -lrt" AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include ]], [[ atcab_init(0); ]])],[ libatca_linked=yes ],[ libatca_linked=no ]) @@ -2995,25 +3021,23 @@ AC_ARG_WITH([cryptoauthlib], trylibatcadir="/usr" 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 ]) - - 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 "$host_cpu" = "aarch64" ; then + LIB_SUFFIX="/aarch64-linux-gnu" + else + LIB_SUFFIX="" fi - AM_LDFLAGS="$AM_LDFLAGS -L$trylibatcadir/lib" - AM_CFLAGS="$AM_CFLAGS -I$trylibatcadir/lib" + LDFLAGS="$LDFLAGS -L$trylibatcadir/lib$LIB_SUFFIX" + CPPFLAGS="$CPPFLAGS -I$trylibatcadir/include/cryptoauthlib" + AM_LDFLAGS="$AM_LDFLAGS -L$trylibatcadir/lib$LIB_SUFFIX" + AM_CFLAGS="$AM_CFLAGS -I$trylibatcadir/include/cryptoauthlib" + AC_MSG_RESULT([yes]) else AC_MSG_RESULT([yes]) fi ENABLED_CRYPTOAUTHLIB="yes" - AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_ATECC508A" ] ) diff --git a/tests/api.c b/tests/api.c index c8df1a9f36..3bce0e440d 100644 --- a/tests/api.c +++ b/tests/api.c @@ -26611,6 +26611,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 f70882a76a..157fa4225d 100644 --- a/tests/api/test_ecc.c +++ b/tests/api/test_ecc.c @@ -1422,7 +1422,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; @@ -1525,7 +1526,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; @@ -1570,7 +1572,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, @@ -1605,7 +1607,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; @@ -1699,6 +1702,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/wolfcrypt/benchmark/benchmark.c b/wolfcrypt/benchmark/benchmark.c index 7fc62536a9..1307722c0c 100644 --- a/wolfcrypt/benchmark/benchmark.c +++ b/wolfcrypt/benchmark/benchmark.c @@ -805,7 +805,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. @@ -2109,7 +2108,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 @@ -10571,8 +10571,12 @@ exit_rsa_sign: 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); @@ -10708,6 +10712,13 @@ void bench_rsa(int useDeviceID) #else /* Note: To benchmark public only define WOLFSSL_PUBLIC_MP */ rsaKeySz = 0; +#endif +#if 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 } @@ -12985,6 +12996,9 @@ void bench_ecc(int useDeviceID, int curveId) 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); @@ -12997,6 +13011,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; @@ -13193,7 +13210,10 @@ exit: 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 8fb72e5598..32b991ecdb 100644 --- a/wolfcrypt/src/aes.c +++ b/wolfcrypt/src/aes.c @@ -150,7 +150,9 @@ block cipher mechanism that uses n-bit binary string parameter key with 128-bits #if defined(WOLFSSL_SE050) && defined(WOLFSSL_SE050_CRYPT) #include #endif - +#ifdef WOLFSSL_MICROCHIP_TA100 + #include +#endif #ifdef WOLFSSL_CMAC #include #endif @@ -5310,7 +5312,13 @@ 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) + ret = wc_Microchip_aes_set_key(aes, userKey, keylen, iv, dir); + if (ret == 0) { + ret = wc_AesSetIV(aes, iv); + } + return ret; +#endif XMEMCPY(aes->key, userKey, keylen); #ifndef WC_AES_BITSLICED @@ -10141,7 +10149,13 @@ 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) + 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, @@ -10870,6 +10884,11 @@ 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) + 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 */ @@ -13852,7 +13871,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 8cdfd6f806..96f063752f 100644 --- a/wolfcrypt/src/ecc.c +++ b/wolfcrypt/src/ecc.c @@ -284,10 +284,10 @@ 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 @@ -296,6 +296,7 @@ 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(NO_ECC_MAKE_PUB) && \ !defined(WOLF_CRYPTO_CB_ONLY_ECC) @@ -308,6 +309,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) @@ -1977,6 +1979,7 @@ static void alt_fp_init(mp_int* a) #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)) @@ -4700,7 +4703,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 @@ -4743,8 +4746,8 @@ 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) { err = atmel_ecc_create_pms(private_key->slot, public_key->pubkey_raw, out); @@ -4782,6 +4785,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) @@ -5297,6 +5301,7 @@ int wc_ecc_point_is_on_curve(ecc_point *p, int curve_idx) } #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)) @@ -5661,6 +5666,7 @@ static int _ecc_make_key_ex(WC_RNG* rng, int keysize, ecc_key* key, { 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; @@ -5741,11 +5747,21 @@ 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) { +#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, curve_id, key->pubkey_raw); /* populate key->pubkey */ if (err == 0 @@ -6241,7 +6257,8 @@ 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; #else #if defined(WOLFSSL_KCAPI_ECC) @@ -6437,6 +6454,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) @@ -6450,7 +6468,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; @@ -6481,9 +6499,12 @@ 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) + (void)inlen; /* Sign: Result is 32-bytes of R then 32-bytes of S */ err = atmel_ecc_sign(key->slot, in, out); + if (err != 0) { return err; } @@ -6833,6 +6854,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) @@ -6954,6 +6976,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, @@ -8022,7 +8045,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 */ @@ -8075,6 +8099,7 @@ int wc_ecc_free(ecc_key* key) } #if !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_ATECC608A) && \ + !defined(WOLFSSL_MICROCHIP_TA100) && \ !defined(WOLFSSL_CRYPTOCELL) && !defined(WOLFSSL_SP_MATH) && \ (!defined(WOLF_CRYPTO_CB_ONLY_ECC) || defined(WOLFSSL_QNX_CAAM) || \ defined(WOLFSSL_IMXRT1170_CAAM)) @@ -8199,7 +8224,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 @@ -8795,7 +8821,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) { @@ -8953,7 +8979,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) { @@ -9290,7 +9316,8 @@ int wc_ecc_verify_hash_ex(mp_int *r, mp_int *s, const byte* hash, byte hashIsZero = 0; word32 zIdx; #endif -#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]; @@ -9376,7 +9403,8 @@ 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_ATECC508A) || defined(WOLFSSL_ATECC608A) || \ + defined(WOLFSSL_MICROCHIP_TA100) err = atmel_ecc_verify(hash, sigRS, key->pubkey_raw, res); if (err != 0) { return err; @@ -10402,14 +10430,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) @@ -10620,7 +10650,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; DECLARE_CURVE_SPECS(4); #endif @@ -10866,7 +10896,8 @@ static int _ecc_import_x963_ex2(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 @@ -11293,7 +11324,8 @@ static int _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 @@ -11862,13 +11894,13 @@ static int _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 @@ -11963,7 +11995,8 @@ static int _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; @@ -12048,7 +12081,8 @@ static int _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; @@ -12116,9 +12150,11 @@ static int _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; @@ -15427,6 +15463,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 01b11a040d..37f2307f23 100644 --- a/wolfcrypt/src/port/atmel/README.md +++ b/wolfcrypt/src/port/atmel/README.md @@ -96,5 +96,60 @@ 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 + +`./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 1215d87c1f..619ca882c9 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,111 @@ 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) + #ifndef SHARED_DATA_ADDR + #define SHARED_DATA_ADDR 0x8006 + #endif + #define MAP_TO_HANDLE(value) (SHARED_DATA_ADDR + (value)) +#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, 0x1600, 0x00, 0x00, 0x00, 0x41, 0x10}, + {0x81, 0x1600, 0x00, 0x00, 0x00, 0x41, 0x10}, + {0x81, 0x1600, 0x00, 0x00, 0x00, 0x41, 0x10}, + {0x81, 0x1600, 0x00, 0x00, 0x00, 0x41, 0x10}, + {0x81, 0x1600, 0x00, 0x00, 0x00, 0x41, 0x10}, + {0x81, 0x1600, 0x00, 0x00, 0x00, 0x41, 0x10}, + {0x81, 0x1600, 0x00, 0x00, 0x00, 0x41, 0x10}, + {0x81, 0x1600, 0x00, 0x00, 0x00, 0x41, 0x10}, +}; +static ta_element_attributes_t* gSharedDataAttr = sharedData_attr; + +#endif /* WOLFSSL_MICROCHIP_TA100 */ #endif /* WOLFSSL_ATECC508A */ /** @@ -105,7 +210,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) uint32_t i = 0; uint32_t copy_count = 0; uint8_t rng_buffer[RANDOM_NUM_SIZE]; @@ -180,8 +286,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,25 +318,12 @@ int wolfCrypt_ATECC_SetConfig(ATCAIfaceCfg* cfg) if (cfg == NULL) { return -1; } + /* Copy the full configuration into the active local device slot so + * non-I2C interface unions (for example ATCA_CUSTOM_IFACE callbacks) + * remain intact. */ + XMEMCPY(gCfg, cfg, sizeof(*gCfg)); - /* Copy whole struct so non-I2C interface unions (e.g. atcacustom function - * pointers when iface_type == ATCA_CUSTOM_IFACE) survive. The field-by- - * field assignments below then refresh the I2C-specific fields. */ - XMEMCPY(&cfg_ateccx08a_i2c_pi, cfg, 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; - - ateccx08a_cfg_initialized = 1; + ateccx08a_cfg_initialized = 0; return 0; } @@ -286,6 +399,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 */ @@ -303,7 +424,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 { @@ -416,10 +538,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; @@ -432,13 +556,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); @@ -447,21 +578,42 @@ 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; } - -int atmel_ecc_create_key(int slotId, byte* peerKey) +#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, 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 = atcab_genkey(MAP_TO_HANDLE(slotId), peerKey); ret = atmel_ecc_translate_err(ret); return ret; } @@ -480,7 +632,7 @@ int atmel_ecc_sign(int slotId, const byte* message, byte* signature) return ECC_BAD_ARG_E; #endif - ret = atcab_sign(slotId, message, signature); + ret = atcab_sign(MAP_TO_HANDLE(slotId), message, signature); ret = atmel_ecc_translate_err(ret); return ret; } @@ -498,15 +650,263 @@ int atmel_ecc_verify(const byte* message, const byte* signature, return ret; } -#endif /* WOLFSSL_ATECC508A */ +#endif /* HAVE_ECC */ +#endif /* WOLFSSL_ATECC508A || WOLFSSL_ATECC608A || WOLFSSL_MICROCHIP_TA100 */ +#ifdef WOLFSSL_MICROCHIP_TA100 +#ifndef NO_RSA +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 = WOLFSSL_TA_KEY_TYPE_RSA_SIZE; + + (void)size; + (void)e; + + ret = talib_handle_init_private_key(&rKeyA, WOLFSSL_TA_KEY_TYPE_RSA, + 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; + + ret = talib_create_element(atcab_get_device(), &rKeyA, &key->rKeyH); + if (ret != ATCA_SUCCESS) return WC_HW_E; + + ret = talib_handle_init_public_key(&uKeyA, WOLFSSL_TA_KEY_TYPE_RSA, + TA_ALG_MODE_RSA_SSA_PSS, TA_PROP_VAL_NO_SECURE_BOOT_SIGN, + TA_PROP_ROOT_PUB_KEY_VERIFY); + if (ret != ATCA_SUCCESS) return WC_HW_E; + + 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; + + /* Write the RSA public key to the handle. */ + ret = talib_write_pub_key(atcab_get_device(), key->uKeyH, (uint16_t)uKey_len, + key->uKey); + + ret = atmel_ecc_translate_err(ret); + + return ret; + +} +int wc_Microchip_rsa_sign(const byte* in, word32 inLen, byte* out, word32 outLen, + RsaKey* key) +{ + int ret; + uint16_t sign_size = outLen; /* WOLFSSL_TA_KEY_TYPE_RSA_SIZE */ + byte hash_data[WC_SHA256_DIGEST_SIZE]; + + if ((ret = wc_Sha256Hash(in, inLen, hash_data)) != 0) { + return ret; + } + + ret = talib_sign_external(atcab_get_device(), WOLFSSL_TA_KEY_TYPE_RSA, + key->rKeyH, TA_HANDLE_INPUT_BUFFER, hash_data, + WC_SHA256_DIGEST_SIZE, out, &sign_size); + ret = atmel_ecc_translate_err(ret); + 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; + byte hash_data[WC_SHA256_DIGEST_SIZE]; + + if ((ret = wc_Sha256Hash(in, inLen, hash_data)) != 0) { + return ret; + } + ret = talib_verify(atcab_get_device(), WOLFSSL_TA_KEY_TYPE_RSA, + TA_HANDLE_INPUT_BUFFER, key->uKeyH, sig, + sigLen, hash_data, WC_SHA256_DIGEST_SIZE, NULL, + sigLen, &verified); + + ret = atmel_ecc_translate_err(ret); + if (pVerified) + *pVerified = (int)verified; + + return ret; +} + +int wc_Microchip_rsa_encrypt(const byte* in, word32 inLen, byte* out, word32 outLen, + RsaKey* key) +{ + int ret; + + /* Encrypt the plaintext with the rsa public key in handle */ + ret = talib_rsaenc_encrypt(atcab_get_device(), key->uKeyH, + inLen, in, outLen, out); + ret = atmel_ecc_translate_err(ret); + return ret; +} + +int wc_Microchip_rsa_decrypt(const byte* in, word32 inLen, byte* out, + word32 outLen, RsaKey* key) +{ + int ret; + /* Decrypt the ciphertext with the rsa private key in handle */ + ret = talib_rsaenc_decrypt(atcab_get_device(), key->rKeyH, + inLen, in, outLen, out); + ret = atmel_ecc_translate_err(ret); + return ret; +} + +void wc_Microchip_rsa_free(struct RsaKey* key) +{ + if (key->rKeyH) + (void)talib_delete_handle(atcab_get_device(), (uint32_t)key->rKeyH); + if (key->uKeyH) + (void)talib_delete_handle(atcab_get_device(), (uint32_t)key->uKeyH); + +} +#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 + +#define CHECK_STATUS(s) \ + if (s != ATCA_SUCCESS) \ + { \ + printf("Error: Line %d in File %s\r\n", __LINE__, __FILE__); \ + printf("STATUS = %X\r\n", s); \ + printf("See atca_status.h for error code \r\n"); \ + return atmel_ecc_translate_err(s); \ + } +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(); + printf("atmel_Handle_Attributes() finished \n\n"); +#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; + } + 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*/ @@ -540,31 +940,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 */ @@ -594,7 +982,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(); @@ -633,7 +1022,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) { @@ -710,7 +1099,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) { atmel_ecc_free(slotId); goto exit; @@ -751,7 +1141,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 @@ -840,12 +1230,12 @@ 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); + ret = atmel_ecc_sign(MAP_TO_HANDLE(slotId), in, sigRs); 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 @@ -930,7 +1320,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 @@ -963,6 +1353,7 @@ exit: return ret; } +#ifdef ATCA_TFLEX_SUPPORT static int atcatls_set_certificates(WOLFSSL_CTX *ctx) { #ifndef ATCATLS_SIGNER_CERT_MAX_SIZE @@ -980,7 +1371,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]; @@ -990,6 +1380,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 @@ -1026,8 +1417,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 @@ -1099,6 +1489,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) { @@ -1107,6 +1499,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) { @@ -1115,6 +1509,7 @@ int atcatls_set_callbacks(WOLFSSL_CTX* ctx) #endif } #endif +#endif /* ATCA_TFLEX_SUPPORT */ return ret; } @@ -1130,4 +1525,117 @@ 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) +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; + + (void)dir; + (void)iv; + + if (aes == NULL) { + return BAD_FUNC_ARG; + } + aes->key_id = atmel_ecc_alloc(ATMEL_SLOT_ENCKEY); + + if (aes->key_id == ATECC_INVALID_SLOT) { + return WC_HW_WAIT_E; + } + + aes->keylen = keylen; + aes->rounds = keylen/4 + 6; + XMEMCPY(aes->key, key, keylen); + + status = talib_write_element(atcab_get_device(), MAP_TO_HANDLE(aes->key_id), + TA_KEY_TYPE_AES128_SIZE, (const uint8_t*)key); + + /*status = talib_write_bytes_zone(atcab_get_device(), (uint8_t)ATCA_ZONE_DATA, + MAP_TO_HANDLE(aes->key_id), 0, (const uint8_t*)key, + (const size_t)keylen); + */ + CHECK_STATUS(status); + + status = talib_aes_gcm_keyload(atcab_get_device(), aes->key_id, keylen); + CHECK_STATUS(status); + (void)is_locked; + + /* 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; + atca_aes_gcm_ctx_t ctx; + + (void)out; + (void)in; + (void)sz; + (void)iv; + (void)ivSz; + (void)authTag; + (void)authTagSz; + (void)authIn; + (void)authInSz; + (void)dir; + + (void)ctx; + + if (aes == NULL) { + return BAD_FUNC_ARG; + } + if (dir != AES_ENCRYPTION && + dir != AES_DECRYPTION) { + return BAD_FUNC_ARG; + } + + + if (dir == AES_ENCRYPTION) { + status = talib_aes_gcm_encrypt(atcab_get_device(), authIn, + authInSz, iv, in, sz, out, authTag); + CHECK_STATUS(status); + } + else { + status = talib_aes_gcm_decrypt(atcab_get_device(), authIn, + authInSz, iv, authTag, in, sz, out); + + /* Add cipher to gcm */ + status = atcab_aes_gcm_decrypt_update(&ctx, in, sz, out); + CHECK_STATUS(status); + } + return atmel_ecc_translate_err(status); +} +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 a116de7aee..c6223cdfa1 100644 --- a/wolfcrypt/src/rsa.c +++ b/wolfcrypt/src/rsa.c @@ -729,7 +729,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; } @@ -3642,6 +3644,16 @@ 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) { + + return wc_Microchip_rsa_encrypt(in, inLen, out, outLen, key); + } + else if (rsa_type == RSA_PRIVATE_ENCRYPT && + pad_value == RSA_BLOCK_TYPE_1) { + return wc_Microchip_rsa_sign(in, inLen, out, outLen, key); + } #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, @@ -3809,6 +3821,17 @@ 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) { + + return wc_Microchip_rsa_decrypt(in, inLen, out, outLen, key); + } + else if (rsa_type == RSA_PUBLIC_DECRYPT && + pad_value == RSA_BLOCK_TYPE_1) { + int tmp; + return wc_Microchip_rsa_verify(in, inLen, out, outLen, key, &tmp); + } #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, @@ -5239,7 +5262,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; @@ -5282,6 +5306,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/wc_port.c b/wolfcrypt/src/wc_port.c index e84c385744..f382588ad8 100644 --- a/wolfcrypt/src/wc_port.c +++ b/wolfcrypt/src/wc_port.c @@ -139,7 +139,8 @@ Threading/Mutex options: #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) @@ -381,7 +382,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 5b0834019e..af670abeb9 100644 --- a/wolfcrypt/test/test.c +++ b/wolfcrypt/test/test.c @@ -926,7 +926,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) && \ !defined(WOLFSSL_SE050) @@ -3042,7 +3043,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) && \ !defined(WOLFSSL_SE050) @@ -23109,7 +23111,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 @@ -26058,7 +26060,8 @@ exit_rsa: } #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) @@ -26072,7 +26075,8 @@ static wc_test_ret_t rsa_keygen_test(WC_RNG* rng) #else byte der[1280]; #endif -#if !defined(WOLFSSL_CRYPTOCELL) && !defined(WOLFSSL_SE050) +#if !defined(WOLFSSL_CRYPTOCELL) && !defined(WOLFSSL_SE050) && \ + !defined(WOLFSSL_MICROCHIP) word32 idx = 0; #endif int derSz = 0; @@ -26133,7 +26137,7 @@ static wc_test_ret_t rsa_keygen_test(WC_RNG* rng) #else derSz = sizeof(der); #endif -#if !defined(WC_TEST_SKIP_RSA_PRIVATE_EXPORT) +#if !defined(WC_TEST_SKIP_RSA_PRIVATE_EXPORT) && !defined(WOLFSSL_MICROCHIP) derSz = wc_RsaKeyToDer(genKey, der, derSz); if (derSz < 0) { ERROR_OUT(WC_TEST_RET_ENC_EC(derSz), exit_rsa); @@ -26149,19 +26153,18 @@ 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); - -#if !defined(WOLFSSL_CRYPTOCELL) && !defined(WOLFSSL_SE050) +#if !defined(WOLFSSL_CRYPTOCELL) && !defined(WOLFSSL_SE050) && \ + !defined(WOLFSSL_MICROCHIP) idx = 0; /* The private key part of key pairs generated inside a secure element - * (CryptoCell, SE050) stays in hardware and isn't available to + * (CryptoCell, SE050, Microchip) stays in hardware and isn't available to * wc_RsaKeyToDer, so the exported DER can't be parsed back as a * complete RSAPrivateKey. */ ret = wc_RsaPrivateKeyDecode(der, &idx, genKey, (word32)derSz); if (ret != 0) ERROR_OUT(WC_TEST_RET_ENC_EC(ret), exit_rsa); -#endif /* WOLFSSL_CRYPTOCELL && !WOLFSSL_SE050 */ -#endif /* !WC_TEST_SKIP_RSA_PRIVATE_EXPORT */ - +#endif /* !WOLFSSL_CRYPTOCELL && !WOLFSSL_SE050 && !WOLFSSL_MICROCHIP */ +#endif /* !WC_TEST_SKIP_RSA_PRIVATE_EXPORT && !WOLFSSL_MICROCHIP */ exit_rsa: #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_NO_MALLOC) @@ -27020,7 +27023,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; @@ -36554,7 +36558,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; @@ -36591,7 +36596,8 @@ static wc_test_ret_t ecc_test_curve_size(WC_RNG* rng, int keySize, int testVerif word32 x = 0; #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 @@ -36607,7 +36613,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 @@ -36662,6 +36669,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); @@ -36691,9 +36701,13 @@ static wc_test_ret_t ecc_test_curve_size(WC_RNG* rng, int keySize, int testVerif TEST_SLEEP(); #endif -/* 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); @@ -36809,7 +36823,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 { @@ -36978,7 +36993,8 @@ 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(WC_TEST_SKIP_ECC_PRIVATE_EXPORT) + !defined(WC_TEST_SKIP_ECC_PRIVATE_EXPORT) && \ + !defined(WOLFSSL_MICROCHIP_TA100) x = ECC_KEY_EXPORT_BUF_SIZE; ret = wc_ecc_export_private_only(userA, exportBuf, &x); if (ret != 0) @@ -37020,7 +37036,10 @@ done: 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; @@ -37058,7 +37077,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 @@ -37113,6 +37132,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) @@ -37429,7 +37449,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) { @@ -37543,7 +37563,8 @@ done: #if defined(HAVE_ECC_KEY_IMPORT) && !defined(WOLFSSL_VALIDATE_ECC_IMPORT) && \ !defined(WOLFSSL_CRYPTOCELL) && !defined(WOLF_CRYPTO_CB_ONLY_ECC) && \ - !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_ATECC608A) + !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_ATECC608A) && \ + !defined(WOLFSSL_MICROCHIP) static wc_test_ret_t ecc_mulmod_test(ecc_key* key1) { wc_test_ret_t ret; @@ -37627,10 +37648,11 @@ done: } #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; @@ -37728,7 +37750,7 @@ static wc_test_ret_t ecc_def_curve_test(WC_RNG *rng) #if 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) ret = ecc_ssh_test(key, rng); if (ret < 0) goto done; @@ -37774,14 +37796,16 @@ static wc_test_ret_t ecc_def_curve_test(WC_RNG *rng) } #if defined(HAVE_ECC_KEY_IMPORT) && defined(HAVE_ECC_KEY_EXPORT) && \ - !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_ATECC608A) + !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_ATECC608A) && \ + !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_ATECC508A) && \ - !defined(WOLFSSL_ATECC608A) + !defined(WOLFSSL_CRYPTOCELL) && !defined(WOLF_CRYPTO_CB_ONLY_ECC) && \ + !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_ATECC608A) && \ + !defined(WOLFSSL_MICROCHIP) ret = ecc_mulmod_test(key); if (ret < 0) goto done; @@ -39612,6 +39636,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(); @@ -39745,8 +39770,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"); @@ -40605,7 +40631,8 @@ done: #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) && \ !defined(WOLFSSL_SE050) diff --git a/wolfssl/wolfcrypt/aes.h b/wolfssl/wolfcrypt/aes.h index b01aa3b473..8f7b87bf03 100644 --- a/wolfssl/wolfcrypt/aes.h +++ b/wolfssl/wolfcrypt/aes.h @@ -312,6 +312,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 3eb6454b8b..d3ab68e41d 100644 --- a/wolfssl/wolfcrypt/ecc.h +++ b/wolfssl/wolfcrypt/ecc.h @@ -46,7 +46,8 @@ #include #endif -#if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A) +#if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A) || \ + defined(WOLFSSL_MICROCHIP_TA100) #include #endif /* WOLFSSL_ATECC508A */ @@ -165,7 +166,8 @@ 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_ATECC508A) || defined(WOLFSSL_ATECC608A) || \ + defined(WOLFSSL_MICROCHIP_TA100) 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) @@ -531,7 +533,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 @@ -708,8 +711,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 @@ -826,7 +832,8 @@ int wc_ecc_point_is_at_infinity(ecc_point *p); WOLFSSL_API int wc_ecc_point_is_on_curve(ecc_point *p, int curve_idx); -#if !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_ATECC608A) +#if !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_ATECC608A) && \ + !defined(WOLFSSL_MICROCHIP_TA100) WOLFSSL_API int wc_ecc_mulmod(const mp_int* k, ecc_point *G, ecc_point *R, mp_int* a, mp_int* modulus, int map); diff --git a/wolfssl/wolfcrypt/port/atmel/atmel.h b/wolfssl/wolfcrypt/port/atmel/atmel.h index 4b31b1be93..09b43e60e9 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,6 +105,8 @@ 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); @@ -108,21 +122,70 @@ 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); - +#endif /* HAVE_ECC */ #endif /* WOLFSSL_ATECC508A */ +#if defined(WOLFSSL_MICROCHIP_TA100) + +#if !defined(NO_AES) && defined(HAVE_AESGCM) && \ + defined(WOLFSSL_MICROCHIP_AESGCM) +#include + +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 +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 8c48fe9e8d..20d07861a9 100644 --- a/wolfssl/wolfcrypt/rsa.h +++ b/wolfssl/wolfcrypt/rsa.h @@ -141,6 +141,9 @@ RSA keys can be used to encrypt, decrypt, sign and verify data. #ifdef WOLFSSL_ASYNC_CRYPT #include #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 @@ -220,6 +223,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 ea6d86c8dd..9a7f5450ff 100644 --- a/wolfssl/wolfcrypt/settings.h +++ b/wolfssl/wolfcrypt/settings.h @@ -1227,7 +1227,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 @@ -3197,6 +3199,15 @@ extern void uITRON4_free(void *p) ; #define USE_ECC_B_PARAM #endif +#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 + #define USE_ECC_B_PARAM +#endif + /* Curve25519 Configs */ #ifdef HAVE_CURVE25519