diff --git a/configure.ac b/configure.ac index 04e80bf39..96d25fccd 100644 --- a/configure.ac +++ b/configure.ac @@ -1914,6 +1914,18 @@ fi # CAAM build +trylibsecodir="/usr" +AC_ARG_WITH([seco], + [AS_HELP_STRING([--with-seco=PATH],[PATH to SECO install (default /usr/lib/)])], + [ +AC_MSG_CHECKING([for SECO]) + +if test "x$withval" != "xno" ; then + trylibsecodir=$withval +fi +] +) + AC_ARG_ENABLE([caam], [AS_HELP_STRING([--enable-caam],[Enable wolfSSL support for CAAM (default: disabled)])], [ ENABLED_CAAM=$enableval ], @@ -1921,14 +1933,33 @@ AC_ARG_ENABLE([caam], ) if test "$ENABLED_CAAM" = "yes" then - AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_IMX6_CAAM" + AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_CAAM -DWOLFSSL_IMX6_CAAM" fi if test "$ENABLED_CAAM" = "qnx" then - AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_IMX6_CAAM -DWOLFSSL_QNX_CAAM" + AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_CAAM -DWOLFSSL_IMX6_CAAM -DWOLFSSL_QNX_CAAM" + AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_CAAM_ECC" + AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_CAAM_CMAC" fi +if test "$ENABLED_CAAM" = "seco" +then + SECO_DIR=$trylibsecodir + AM_CPPFLAGS="$AM_CPPFLAGS -I$SECO_DIR/include" + AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_CAAM -DWOLFSSL_SECO_CAAM -DWOLFSSL_HASH_KEEP" + AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_CAAM_ECC" + AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_CAAM_CMAC" + AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_CAAM_CIPHER" + AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_CAAM_HMAC" + AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_CAAM_HASH" + AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_CAAM_CURVE25519" + + AC_CHECK_LIB([hsm_lib],[hsm_open_session]) + AC_CHECK_LIB([seco_nvm_manager],[seco_nvm_manager]) + LIB_STATIC_ADD="$LIB_STATIC_ADD $SECO_DIR/lib/hsm_lib.a $SECO_DIR/lib/seco_nvm_manager.a" + LIB_ADD="$LIB_ADD -lz" +fi # INTEL AES-NI AC_ARG_ENABLE([aesni], @@ -2219,6 +2250,30 @@ then AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_NO_HASH_RAW" ENABLED_DEVCRYPTO=yes fi +if test "$ENABLED_DEVCRYPTO" = "hmac" +then + #enable only hmac algorithm support + AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_DEVCRYPTO" + AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_DEVCRYPTO_HMAC" + ENABLED_DEVCRYPTO=yes +fi +if test "$ENABLED_DEVCRYPTO" = "rsa" +then + #enable only rsa algorithm support + AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_DEVCRYPTO" + AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_DEVCRYPTO_RSA" + ENABLED_DEVCRYPTO=yes +fi +if test "$ENABLED_DEVCRYPTO" = "seco" +then + #enable support of devcrypto for algos not supported with seco + AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_DEVCRYPTO" + AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_DEVCRYPTO_HMAC" + AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_DEVCRYPTO_RSA" + AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_DEVCRYPTO_CURVE25519" + AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_DEVCRYPTO_ECDSA" + ENABLED_DEVCRYPTO=yes +fi # Camellia @@ -6715,7 +6770,7 @@ AC_ARG_ENABLE([cryptocb], [ ENABLED_CRYPTOCB=no ] ) -if test "x$ENABLED_PKCS11" = "xyes" || test "x$ENABLED_WOLFTPM" = "xyes" || test "$ENABLED_CAAM" = "qnx" +if test "x$ENABLED_PKCS11" = "xyes" || test "x$ENABLED_WOLFTPM" = "xyes" || test "$ENABLED_CAAM" = "qnx" || test "$ENABLED_CAAM" = "seco" then ENABLED_CRYPTOCB=yes fi @@ -7405,7 +7460,9 @@ AS_IF([(test "x$ENABLED_AFALG" = "xyes") && (test "x$ENABLED_SHA224" = "xyes")], [AC_MSG_ERROR([--enable-sha224 with --enable-afalg not yet supported])]) # WOLFSSL_DEVCRYPTO does not support SHA224 yet -AS_IF([(test "x$ENABLED_DEVCRYPTO" = "xyes") && (test "x$ENABLED_SHA224" = "xyes")], +AS_IF([(test "x$ENABLED_DEVCRYPTO" = "xyes") && \ + (test "x$ENABLED_CAAM" = "xno") && \ + (test "x$ENABLED_SHA224" = "xyes")], [AC_MSG_ERROR([--enable-sha224 with --enable-devcrypto not yet supported])]) # SCTP and Multicast require DTLS @@ -7737,7 +7794,7 @@ AM_CONDITIONAL([BUILD_DES3],[test "x$ENABLED_DES3" = "xyes" || test "x$ENABLED_U AM_CONDITIONAL([BUILD_PKCS7],[test "x$ENABLED_PKCS7" = "xyes" || test "x$ENABLED_USERSETTINGS" = "xyes"]) AM_CONDITIONAL([BUILD_SMIME],[test "x$ENABLED_SMIME" = "xyes" || test "x$ENABLED_USERSETTINGS" = "xyes"]) AM_CONDITIONAL([BUILD_HASHFLAGS],[test "x$ENABLED_HASHFLAGS" = "xyes"]) -AM_CONDITIONAL([BUILD_CAAM],[test "x$ENABLED_CAAM" = "xyes" || test "x$ENABLED_CAAM" = "xqnx"]) +AM_CONDITIONAL([BUILD_CAAM],[test "x$ENABLED_CAAM" = "xyes" || test "x$ENABLED_CAAM" = "xqnx" || test "x$ENABLED_CAAM" = "xseco"]) AM_CONDITIONAL([BUILD_LINUXKM],[test "$ENABLED_LINUXKM" = "yes"]) AM_CONDITIONAL([BUILD_NO_LIBRARY],[test "$ENABLED_NO_LIBRARY" = "yes"]) AM_CONDITIONAL([BUILD_BENCHMARK],[test "$ENABLED_BENCHMARK" = "yes"]) @@ -8158,7 +8215,7 @@ echo " * Linux AF_ALG: $ENABLED_AFALG" echo " * Linux KCAPI: $ENABLED_KCAPI" echo " * Linux devcrypto: $ENABLED_DEVCRYPTO" echo " * Crypto callbacks: $ENABLED_CRYPTOCB" -echo " * i.MX6 CAAM: $ENABLED_CAAM" +echo " * i.MX CAAM: $ENABLED_CAAM" echo " * IoT-Safe: $ENABLED_IOTSAFE" echo " * IoT-Safe HWRNG: $ENABLED_IOTSAFE_HWRNG" echo " * NXP SE050: $ENABLED_SE050" diff --git a/wolfcrypt/benchmark/benchmark.c b/wolfcrypt/benchmark/benchmark.c index a6fb680a0..0b788e32d 100644 --- a/wolfcrypt/benchmark/benchmark.c +++ b/wolfcrypt/benchmark/benchmark.c @@ -979,14 +979,20 @@ static const char* bench_result_words2[][5] = { #endif #endif -/* Asynchronous helper macros */ -#ifdef WOLFSSL_QNX_CAAM -#include -static THREAD_LS_T int devId = WOLFSSL_CAAM_DEVID; +#ifdef WOLFSSL_CAAM + #include + #ifdef WOLFSSL_SECO_CAAM + #define SECO_MAX_UPDATES 10000 + #define SECO_BENCHMARK_NONCE 0x7777 + #define SECO_KEY_STORE_ID 1 + #endif + + static THREAD_LS_T int devId = WOLFSSL_CAAM_DEVID; #else -static THREAD_LS_T int devId = INVALID_DEVID; + static THREAD_LS_T int devId = INVALID_DEVID; #endif +/* Asynchronous helper macros */ #ifdef WC_ENABLE_BENCH_THREADING typedef struct ThreadData { pthread_t thread_id; @@ -999,7 +1005,7 @@ static THREAD_LS_T int devId = INVALID_DEVID; static WOLF_EVENT_QUEUE eventQueue; #define BENCH_ASYNC_GET_DEV(obj) (&(obj)->asyncDev) - #define BENCH_ASYNC_GET_NAME(doAsync) (doAsync) ? "HW" : "SW" + #define BENCH_ASYNC_GET_NAME(useDeviceID) (useDeviceID) ? "HW" : "SW" #define BENCH_MAX_PENDING (WOLF_ASYNC_MAX_PENDING) @@ -1091,7 +1097,7 @@ static THREAD_LS_T int devId = INVALID_DEVID; #else #define BENCH_MAX_PENDING (1) - #define BENCH_ASYNC_GET_NAME(doAsync) "" + #define BENCH_ASYNC_GET_NAME(useDeviceID) "" #define BENCH_ASYNC_GET_DEV(obj) NULL static WC_INLINE int bench_async_check(int* ret, void* asyncDev, @@ -1127,8 +1133,9 @@ static THREAD_LS_T int devId = INVALID_DEVID; /* maximum runtime for each benchmark */ -#define BENCH_MIN_RUNTIME_SEC 1.0f - +#ifndef BENCH_MIN_RUNTIME_SEC + #define BENCH_MIN_RUNTIME_SEC 1.0f +#endif #if defined(HAVE_AESGCM) || defined(HAVE_AESCCM) #if !defined(AES_AUTH_ADD_SZ) && \ @@ -1273,7 +1280,7 @@ typedef enum bench_stat_type { const char* desc; double perfsec; int strength; - int doAsync; + int useDeviceID; int finishCount; bench_stat_type_t type; int lastRet; @@ -1283,7 +1290,7 @@ typedef enum bench_stat_type { static bench_stats_t* bench_stats_tail; static bench_stats_t* bench_stats_add(bench_stat_type_t type, - const char* algo, int strength, const char* desc, int doAsync, + const char* algo, int strength, const char* desc, int useDeviceID, double perfsec, const char* perftype, int ret) { bench_stats_t* bstat = NULL; @@ -1298,7 +1305,7 @@ typedef enum bench_stat_type { if (XSTRNCMP(bstat->algo, algo, BENCH_MAX_NAME_SZ) == 0 && bstat->strength == strength && bstat->desc == desc && - bstat->doAsync == doAsync) { + bstat->useDeviceID == useDeviceID) { break; } } @@ -1329,7 +1336,7 @@ typedef enum bench_stat_type { XSTRNCPY(bstat->algo, algo, BENCH_MAX_NAME_SZ); bstat->strength = strength; bstat->desc = desc; - bstat->doAsync = doAsync; + bstat->useDeviceID = useDeviceID; bstat->perfsec += perfsec; bstat->finishCount++; bstat->perftype = perftype; @@ -1351,13 +1358,13 @@ typedef enum bench_stat_type { for (bstat = bench_stats_head; bstat != NULL; ) { if (bstat->type == BENCH_STAT_SYM) { printf("%-16s%s %8.3f %s/s\n", bstat->desc, - BENCH_ASYNC_GET_NAME(bstat->doAsync), bstat->perfsec, + BENCH_ASYNC_GET_NAME(bstat->useDeviceID), bstat->perfsec, base2 ? "MB" : "mB"); } else { printf("%-5s %4d %-9s %s %.3f ops/sec\n", bstat->algo, bstat->strength, bstat->desc, - BENCH_ASYNC_GET_NAME(bstat->doAsync), bstat->perfsec); + BENCH_ASYNC_GET_NAME(bstat->useDeviceID), bstat->perfsec); } bstat = bstat->next; @@ -1383,7 +1390,7 @@ typedef enum bench_stat_type { static int gStatsCount; static bench_stats_t* bench_stats_add(bench_stat_type_t type, - const char* algo, int strength, const char* desc, int doAsync, + const char* algo, int strength, const char* desc, int useDeviceID, double perfsec, const char* perftype, int ret) { bench_stats_t* bstat = NULL; @@ -1420,7 +1427,7 @@ typedef enum bench_stat_type { bstat->type = type; bstat->ret = ret; - (void)doAsync; + (void)useDeviceID; #ifdef WC_ENABLE_BENCH_THREADING pthread_mutex_unlock(&bench_lock); @@ -1508,7 +1515,7 @@ static WC_INLINE int bench_stats_sym_check(double start) /* countSz is number of bytes that 1 count represents. Normally bench_size, * except for AES direct that operates on AES_BLOCK_SIZE blocks */ -static void bench_stats_sym_finish(const char* desc, int doAsync, int count, +static void bench_stats_sym_finish(const char* desc, int useDeviceID, int count, int countSz, double start, int ret) { double total, persec = 0, blocks = count; @@ -1562,7 +1569,7 @@ static void bench_stats_sym_finish(const char* desc, int doAsync, int count, SHOW_INTEL_CYCLES_CSV(msg, sizeof(msg), countSz); } else { XSNPRINTF(msg, sizeof(msg), "%-16s%s %5.0f %s %s %5.3f %s, %8.3f %s/s", - desc, BENCH_ASYNC_GET_NAME(doAsync), blocks, blockType, word[0], + desc, BENCH_ASYNC_GET_NAME(useDeviceID), blocks, blockType, word[0], total, word[1], persec, blockType); SHOW_INTEL_CYCLES(msg, sizeof(msg), countSz); } @@ -1574,9 +1581,10 @@ static void bench_stats_sym_finish(const char* desc, int doAsync, int count, } /* Add to thread stats */ - bench_stats_add(BENCH_STAT_SYM, desc, 0, desc, doAsync, persec, blockType, ret); + bench_stats_add(BENCH_STAT_SYM, desc, 0, desc, useDeviceID, persec, + blockType, ret); - (void)doAsync; + (void)useDeviceID; (void)ret; TEST_SLEEP(); @@ -1587,7 +1595,7 @@ static void bench_stats_sym_finish(const char* desc, int doAsync, int count, defined(HAVE_CURVE25519) || defined(HAVE_ED25519) || \ defined(HAVE_CURVE448) || defined(HAVE_ED448) static void bench_stats_asym_finish(const char* algo, int strength, - const char* desc, int doAsync, int count, double start, int ret) + const char* desc, int useDeviceID, int count, double start, int ret) { double total, each = 0, opsSec, milliEach; const char **word = bench_result_words2[lng_index]; @@ -1611,7 +1619,7 @@ static void bench_stats_asym_finish(const char* algo, int strength, XSNPRINTF(msg, sizeof(msg), "%s %d %s,%.3f,%.3f,\n", algo, strength, desc, milliEach, opsSec); } else { XSNPRINTF(msg, sizeof(msg), "%-6s %5d %-9s %s %6d %s %5.3f %s, %s %5.3f ms," - " %.3f %s\n", algo, strength, desc, BENCH_ASYNC_GET_NAME(doAsync), + " %.3f %s\n", algo, strength, desc, BENCH_ASYNC_GET_NAME(useDeviceID), count, word[0], total, word[1], word[2], milliEach, opsSec, word[3]); } printf("%s", msg); @@ -1622,9 +1630,9 @@ static void bench_stats_asym_finish(const char* algo, int strength, } /* Add to thread stats */ - bench_stats_add(BENCH_STAT_ASYM, algo, strength, desc, doAsync, opsSec, kOpsSec, ret); + bench_stats_add(BENCH_STAT_ASYM, algo, strength, desc, useDeviceID, opsSec, kOpsSec, ret); - (void)doAsync; + (void)useDeviceID; (void)ret; TEST_SLEEP(); @@ -1632,7 +1640,7 @@ static void bench_stats_asym_finish(const char* algo, int strength, #endif #if defined(HAVE_PQC) -static void bench_stats_pq_asym_finish(const char* algo, int doAsync, int count, +static void bench_stats_pq_asym_finish(const char* algo, int useDeviceID, int count, double start, int ret) { double total, each = 0, opsSec, milliEach; @@ -1657,7 +1665,7 @@ static void bench_stats_pq_asym_finish(const char* algo, int doAsync, int count, XSNPRINTF(msg, sizeof(msg), "%s %.3f,%.3f,\n", algo, milliEach, opsSec); } else { XSNPRINTF(msg, sizeof(msg), "%-18s %s %6d %s %5.3f %s, %s %5.3f ms," - " %.3f %s\n", algo, BENCH_ASYNC_GET_NAME(doAsync), + " %.3f %s\n", algo, BENCH_ASYNC_GET_NAME(useDeviceID), count, word[0], total, word[1], word[2], milliEach, opsSec, word[3]); } printf("%s", msg); @@ -1668,9 +1676,9 @@ static void bench_stats_pq_asym_finish(const char* algo, int doAsync, int count, } /* Add to thread stats */ - bench_stats_add(BENCH_STAT_ASYM, algo, 0, "", doAsync, opsSec, kOpsSec, ret); + bench_stats_add(BENCH_STAT_ASYM, algo, 0, "", useDeviceID, opsSec, kOpsSec, ret); - (void)doAsync; + (void)useDeviceID; (void)ret; TEST_SLEEP(); @@ -1812,7 +1820,7 @@ static void* benchmarks_do(void* args) #endif #if ((defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_3DES)) || \ defined(HAVE_INTEL_QA_SYNC) || defined(HAVE_CAVIUM_OCTEON_SYNC) || \ - defined(HAVE_RENESAS_SYNC)) && \ + defined(HAVE_RENESAS_SYNC) || defined(WOLFSSL_CAAM)) && \ !defined(NO_HW_BENCH) bench_aescbc(1); #endif @@ -1825,7 +1833,7 @@ static void* benchmarks_do(void* args) #endif #if ((defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_3DES)) || \ defined(HAVE_INTEL_QA_SYNC) || defined(HAVE_CAVIUM_OCTEON_SYNC) || \ - defined(HAVE_RENESAS_SYNC)) && \ + defined(HAVE_RENESAS_SYNC) || defined(WOLFSSL_CAAM)) && \ !defined(NO_HW_BENCH) bench_aesgcm(1); #endif @@ -1833,13 +1841,13 @@ static void* benchmarks_do(void* args) bench_gmac(); } #endif -#ifdef WOLFSSL_AES_DIRECT +#ifdef HAVE_AES_ECB if (bench_all || (bench_cipher_algs & BENCH_AES_ECB)) { #ifndef NO_SW_BENCH bench_aesecb(0); #endif - #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_AES) && \ - !defined(NO_HW_BENCH) + #if ((defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_AES)) || \ + defined(WOLFSSL_CAAM)) && !defined(NO_HW_BENCH) bench_aesecb(1); #endif } @@ -2418,6 +2426,16 @@ int benchmark_init(void) printf("wolfCrypt_Init failed %d\n", ret); return EXIT_FAILURE; } +#ifdef WOLFSSL_SECO_CAAM + if (devId == WOLFSSL_SECO_DEVID && wc_SECO_OpenHSM(SECO_KEY_STORE_ID, + SECO_BENCHMARK_NONCE, SECO_MAX_UPDATES, CAAM_KEYSTORE_CREATE) + != 0) { + printf("unable to open HSM\n"); + wolfCrypt_Cleanup(); + return EXIT_FAILURE; + } +#endif + #ifdef WC_RNG_SEED_CB wc_SetSeed_Cb(wc_GenerateSeed); #endif @@ -2488,6 +2506,12 @@ int benchmark_free(void) } #endif +#ifdef WOLFSSL_SECO_CAAM + if (devId == WOLFSSL_SECO_DEVID && wc_SECO_CloseHSM() != 0) { + printf("Error closing down the key store\n"); + } +#endif + if ((ret = wolfCrypt_Cleanup()) != 0) { printf("error %d with wolfCrypt_Cleanup\n", ret); } @@ -2656,7 +2680,7 @@ exit_rng: #ifndef NO_AES #ifdef HAVE_AES_CBC -static void bench_aescbc_internal(int doAsync, const byte* key, word32 keySz, +static void bench_aescbc_internal(int useDeviceID, const byte* key, word32 keySz, const byte* iv, const char* encLabel, const char* decLabel) { @@ -2670,7 +2694,7 @@ static void bench_aescbc_internal(int doAsync, const byte* key, word32 keySz, /* init keys */ for (i = 0; i < BENCH_MAX_PENDING; i++) { if ((ret = wc_AesInit(&enc[i], HEAP_HINT, - doAsync ? devId : INVALID_DEVID)) != 0) { + useDeviceID ? devId : INVALID_DEVID)) != 0) { printf("AesInit failed, ret = %d\n", ret); goto exit; } @@ -2704,7 +2728,7 @@ static void bench_aescbc_internal(int doAsync, const byte* key, word32 keySz, count += times; } while (bench_stats_sym_check(start)); exit_aes_enc: - bench_stats_sym_finish(encLabel, doAsync, count, bench_size, start, ret); + bench_stats_sym_finish(encLabel, useDeviceID, count, bench_size, start, ret); if (ret < 0) { goto exit; @@ -2742,7 +2766,7 @@ exit_aes_enc: count += times; } while (bench_stats_sym_check(start)); exit_aes_dec: - bench_stats_sym_finish(decLabel, doAsync, count, bench_size, start, ret); + bench_stats_sym_finish(decLabel, useDeviceID, count, bench_size, start, ret); #endif /* HAVE_AES_DECRYPT */ @@ -2754,18 +2778,18 @@ exit: } } -void bench_aescbc(int doAsync) +void bench_aescbc(int useDeviceID) { #ifdef WOLFSSL_AES_128 - bench_aescbc_internal(doAsync, bench_key, 16, bench_iv, + bench_aescbc_internal(useDeviceID, bench_key, 16, bench_iv, "AES-128-CBC-enc", "AES-128-CBC-dec"); #endif #ifdef WOLFSSL_AES_192 - bench_aescbc_internal(doAsync, bench_key, 24, bench_iv, + bench_aescbc_internal(useDeviceID, bench_key, 24, bench_iv, "AES-192-CBC-enc", "AES-192-CBC-dec"); #endif #ifdef WOLFSSL_AES_256 - bench_aescbc_internal(doAsync, bench_key, 32, bench_iv, + bench_aescbc_internal(useDeviceID, bench_key, 32, bench_iv, "AES-256-CBC-enc", "AES-256-CBC-dec"); #endif } @@ -2773,7 +2797,7 @@ void bench_aescbc(int doAsync) #endif /* HAVE_AES_CBC */ #ifdef HAVE_AESGCM -static void bench_aesgcm_internal(int doAsync, const byte* key, word32 keySz, +static void bench_aesgcm_internal(int useDeviceID, const byte* key, word32 keySz, const byte* iv, word32 ivSz, const char* encLabel, const char* decLabel) { @@ -2810,7 +2834,7 @@ static void bench_aesgcm_internal(int doAsync, const byte* key, word32 keySz, /* init keys */ for (i = 0; i < BENCH_MAX_PENDING; i++) { if ((ret = wc_AesInit(&enc[i], HEAP_HINT, - doAsync ? devId : INVALID_DEVID)) != 0) { + useDeviceID ? devId : INVALID_DEVID)) != 0) { printf("AesInit failed, ret = %d\n", ret); goto exit; } @@ -2859,13 +2883,13 @@ static void bench_aesgcm_internal(int doAsync, const byte* key, word32 keySz, count += times; } while (bench_stats_sym_check(start)); exit_aes_gcm: - bench_stats_sym_finish(encLabel, doAsync, count, bench_size, start, ret); + bench_stats_sym_finish(encLabel, useDeviceID, count, bench_size, start, ret); #ifdef HAVE_AES_DECRYPT /* init keys */ for (i = 0; i < BENCH_MAX_PENDING; i++) { if ((ret = wc_AesInit(&dec[i], HEAP_HINT, - doAsync ? devId : INVALID_DEVID)) != 0) { + useDeviceID ? devId : INVALID_DEVID)) != 0) { printf("AesInit failed, ret = %d\n", ret); goto exit; } @@ -2913,7 +2937,7 @@ exit_aes_gcm: count += times; } while (bench_stats_sym_check(start)); exit_aes_gcm_dec: - bench_stats_sym_finish(decLabel, doAsync, count, bench_size, start, ret); + bench_stats_sym_finish(decLabel, useDeviceID, count, bench_size, start, ret); #endif /* HAVE_AES_DECRYPT */ (void)decLabel; @@ -2936,20 +2960,20 @@ exit: WC_FREE_VAR(bench_tag, HEAP_HINT); } -void bench_aesgcm(int doAsync) +void bench_aesgcm(int useDeviceID) { #if defined(WOLFSSL_AES_128) && !defined(WOLFSSL_AFALG_XILINX_AES) \ && !defined(WOLFSSL_XILINX_CRYPT) - bench_aesgcm_internal(doAsync, bench_key, 16, bench_iv, 12, + bench_aesgcm_internal(useDeviceID, bench_key, 16, bench_iv, 12, "AES-128-GCM-enc", "AES-128-GCM-dec"); #endif #if defined(WOLFSSL_AES_192) && !defined(WOLFSSL_AFALG_XILINX_AES) \ && !defined(WOLFSSL_XILINX_CRYPT) - bench_aesgcm_internal(doAsync, bench_key, 24, bench_iv, 12, + bench_aesgcm_internal(useDeviceID, bench_key, 24, bench_iv, 12, "AES-192-GCM-enc", "AES-192-GCM-dec"); #endif #ifdef WOLFSSL_AES_256 - bench_aesgcm_internal(doAsync, bench_key, 32, bench_iv, 12, + bench_aesgcm_internal(useDeviceID, bench_key, 32, bench_iv, 12, "AES-256-GCM-enc", "AES-256-GCM-dec"); #endif } @@ -2997,8 +3021,8 @@ void bench_gmac(void) #endif /* HAVE_AESGCM */ -#ifdef WOLFSSL_AES_DIRECT -static void bench_aesecb_internal(int doAsync, const byte* key, word32 keySz, +#ifdef HAVE_AES_ECB +static void bench_aesecb_internal(int useDeviceID, const byte* key, word32 keySz, const char* encLabel, const char* decLabel) { int ret = 0, i, count = 0, times, pending = 0; @@ -3011,7 +3035,7 @@ static void bench_aesecb_internal(int doAsync, const byte* key, word32 keySz, /* init keys */ for (i = 0; i < BENCH_MAX_PENDING; i++) { if ((ret = wc_AesInit(&enc[i], HEAP_HINT, - doAsync ? devId : INVALID_DEVID)) != 0) { + useDeviceID ? devId : INVALID_DEVID)) != 0) { printf("AesInit failed, ret = %d\n", ret); goto exit; } @@ -3032,7 +3056,12 @@ static void bench_aesecb_internal(int doAsync, const byte* key, word32 keySz, for (i = 0; i < BENCH_MAX_PENDING; i++) { if (bench_async_check(&ret, BENCH_ASYNC_GET_DEV(&enc[i]), 0, ×, numBlocks, &pending)) { + #ifdef HAVE_FIPS wc_AesEncryptDirect(&enc[i], bench_cipher, bench_plain); + #else + wc_AesEcbEncrypt(&enc[i], bench_cipher, bench_plain, + AES_BLOCK_SIZE); + #endif ret = 0; if (!bench_async_handle(&ret, BENCH_ASYNC_GET_DEV(&enc[i]), 0, ×, &pending)) { @@ -3044,7 +3073,7 @@ static void bench_aesecb_internal(int doAsync, const byte* key, word32 keySz, count += times; } while (bench_stats_sym_check(start)); exit_aes_enc: - bench_stats_sym_finish(encLabel, doAsync, count, AES_BLOCK_SIZE, + bench_stats_sym_finish(encLabel, useDeviceID, count, AES_BLOCK_SIZE, start, ret); #ifdef HAVE_AES_DECRYPT @@ -3066,7 +3095,12 @@ exit_aes_enc: for (i = 0; i < BENCH_MAX_PENDING; i++) { if (bench_async_check(&ret, BENCH_ASYNC_GET_DEV(&enc[i]), 0, ×, numBlocks, &pending)) { + #ifdef HAVE_FIPS wc_AesDecryptDirect(&enc[i], bench_plain, bench_cipher); + #else + wc_AesEcbDecrypt(&enc[i], bench_plain, bench_cipher, + AES_BLOCK_SIZE); + #endif ret = 0; if (!bench_async_handle(&ret, BENCH_ASYNC_GET_DEV(&enc[i]), 0, ×, &pending)) { @@ -3078,7 +3112,7 @@ exit_aes_enc: count += times; } while (bench_stats_sym_check(start)); exit_aes_dec: - bench_stats_sym_finish(decLabel, doAsync, count, AES_BLOCK_SIZE, + bench_stats_sym_finish(decLabel, useDeviceID, count, AES_BLOCK_SIZE, start, ret); #endif /* HAVE_AES_DECRYPT */ @@ -3090,22 +3124,22 @@ exit: } } -void bench_aesecb(int doAsync) +void bench_aesecb(int useDeviceID) { #ifdef WOLFSSL_AES_128 - bench_aesecb_internal(doAsync, bench_key, 16, + bench_aesecb_internal(useDeviceID, bench_key, 16, "AES-128-ECB-enc", "AES-128-ECB-dec"); #endif #ifdef WOLFSSL_AES_192 - bench_aesecb_internal(doAsync, bench_key, 24, + bench_aesecb_internal(useDeviceID, bench_key, 24, "AES-192-ECB-enc", "AES-192-ECB-dec"); #endif #ifdef WOLFSSL_AES_256 - bench_aesecb_internal(doAsync, bench_key, 32, + bench_aesecb_internal(useDeviceID, bench_key, 32, "AES-256-ECB-enc", "AES-256-ECB-dec"); #endif } -#endif /* WOLFSSL_AES_DIRECT */ +#endif /* HAVE_AES_ECB */ #ifdef WOLFSSL_AES_CFB static void bench_aescfb_internal(const byte* key, word32 keySz, const byte* iv, @@ -3317,6 +3351,11 @@ void bench_aesccm(void) XMEMSET(bench_tag, 0, AES_AUTH_TAG_SZ); XMEMSET(bench_additional, 0, AES_AUTH_ADD_SZ); + if ((ret = wc_AesInit(&enc, HEAP_HINT, devId)) != 0) { + printf("wc_AesInit failed, ret = %d\n", ret); + goto exit; + } + if ((ret = wc_AesCcmSetKey(&enc, bench_key, 16)) != 0) { printf("wc_AesCcmSetKey failed, ret = %d\n", ret); goto exit; @@ -3325,24 +3364,32 @@ void bench_aesccm(void) bench_stats_start(&count, &start); do { for (i = 0; i < numBlocks; i++) { - wc_AesCcmEncrypt(&enc, bench_cipher, bench_plain, BENCH_SIZE, + ret |= wc_AesCcmEncrypt(&enc, bench_cipher, bench_plain, BENCH_SIZE, bench_iv, 12, bench_tag, AES_AUTH_TAG_SZ, bench_additional, aesAuthAddSz); } count += i; } while (bench_stats_sym_check(start)); bench_stats_sym_finish("AES-CCM-Enc", 0, count, bench_size, start, ret); + if (ret != 0) { + printf("wc_AesCcmEncrypt failed, ret = %d\n", ret); + goto exit; + } bench_stats_start(&count, &start); do { for (i = 0; i < numBlocks; i++) { - wc_AesCcmDecrypt(&enc, bench_plain, bench_cipher, BENCH_SIZE, + ret |= wc_AesCcmDecrypt(&enc, bench_plain, bench_cipher, BENCH_SIZE, bench_iv, 12, bench_tag, AES_AUTH_TAG_SZ, bench_additional, aesAuthAddSz); } count += i; } while (bench_stats_sym_check(start)); bench_stats_sym_finish("AES-CCM-Dec", 0, count, bench_size, start, ret); + if (ret != 0) { + printf("wc_AesCcmEncrypt failed, ret = %d\n", ret); + goto exit; + } exit: @@ -3489,7 +3536,7 @@ void bench_camellia(void) #ifndef NO_DES3 -void bench_des(int doAsync) +void bench_des(int useDeviceID) { int ret = 0, i, count = 0, times, pending = 0; Des3 enc[BENCH_MAX_PENDING]; @@ -3501,7 +3548,7 @@ void bench_des(int doAsync) /* init keys */ for (i = 0; i < BENCH_MAX_PENDING; i++) { if ((ret = wc_Des3Init(&enc[i], HEAP_HINT, - doAsync ? devId : INVALID_DEVID)) != 0) { + useDeviceID ? devId : INVALID_DEVID)) != 0) { printf("Des3Init failed, ret = %d\n", ret); goto exit; } @@ -3534,7 +3581,7 @@ void bench_des(int doAsync) count += times; } while (bench_stats_sym_check(start)); exit_3des: - bench_stats_sym_finish("3DES", doAsync, count, bench_size, start, ret); + bench_stats_sym_finish("3DES", useDeviceID, count, bench_size, start, ret); exit: @@ -3546,7 +3593,7 @@ exit: #ifndef NO_RC4 -void bench_arc4(int doAsync) +void bench_arc4(int useDeviceID) { int ret = 0, i, count = 0, times, pending = 0; Arc4 enc[BENCH_MAX_PENDING]; @@ -3558,7 +3605,7 @@ void bench_arc4(int doAsync) /* init keys */ for (i = 0; i < BENCH_MAX_PENDING; i++) { if ((ret = wc_Arc4Init(&enc[i], HEAP_HINT, - doAsync ? devId : INVALID_DEVID)) != 0) { + useDeviceID ? devId : INVALID_DEVID)) != 0) { printf("Arc4Init failed, ret = %d\n", ret); goto exit; } @@ -3591,7 +3638,7 @@ void bench_arc4(int doAsync) count += times; } while (bench_stats_sym_check(start)); exit_arc4: - bench_stats_sym_finish("ARC4", doAsync, count, bench_size, start, ret); + bench_stats_sym_finish("ARC4", useDeviceID, count, bench_size, start, ret); exit: @@ -3650,7 +3697,7 @@ void bench_chacha20_poly1305_aead(void) #ifndef NO_MD5 -void bench_md5(int doAsync) +void bench_md5(int useDeviceID) { wc_Md5 hash[BENCH_MAX_PENDING]; double start; @@ -3664,7 +3711,7 @@ void bench_md5(int doAsync) /* init keys */ for (i = 0; i < BENCH_MAX_PENDING; i++) { ret = wc_InitMd5_ex(&hash[i], HEAP_HINT, - doAsync ? devId : INVALID_DEVID); + useDeviceID ? devId : INVALID_DEVID); if (ret != 0) { printf("InitMd5_ex failed, ret = %d\n", ret); goto exit; @@ -3727,7 +3774,7 @@ void bench_md5(int doAsync) } while (bench_stats_sym_check(start)); } exit_md5: - bench_stats_sym_finish("MD5", doAsync, count, bench_size, start, ret); + bench_stats_sym_finish("MD5", useDeviceID, count, bench_size, start, ret); exit: @@ -3743,7 +3790,7 @@ exit: #ifndef NO_SHA -void bench_sha(int doAsync) +void bench_sha(int useDeviceID) { wc_Sha hash[BENCH_MAX_PENDING]; double start; @@ -3757,7 +3804,7 @@ void bench_sha(int doAsync) /* init keys */ for (i = 0; i < BENCH_MAX_PENDING; i++) { ret = wc_InitSha_ex(&hash[i], HEAP_HINT, - doAsync ? devId : INVALID_DEVID); + useDeviceID ? devId : INVALID_DEVID); if (ret != 0) { printf("InitSha failed, ret = %d\n", ret); goto exit; @@ -3820,7 +3867,7 @@ void bench_sha(int doAsync) } while (bench_stats_sym_check(start)); } exit_sha: - bench_stats_sym_finish("SHA", doAsync, count, bench_size, start, ret); + bench_stats_sym_finish("SHA", useDeviceID, count, bench_size, start, ret); exit: @@ -3834,7 +3881,7 @@ exit: #ifdef WOLFSSL_SHA224 -void bench_sha224(int doAsync) +void bench_sha224(int useDeviceID) { wc_Sha224 hash[BENCH_MAX_PENDING]; double start; @@ -3848,7 +3895,7 @@ void bench_sha224(int doAsync) /* init keys */ for (i = 0; i < BENCH_MAX_PENDING; i++) { ret = wc_InitSha224_ex(&hash[i], HEAP_HINT, - doAsync ? devId : INVALID_DEVID); + useDeviceID ? devId : INVALID_DEVID); if (ret != 0) { printf("InitSha224_ex failed, ret = %d\n", ret); goto exit; @@ -3907,7 +3954,7 @@ void bench_sha224(int doAsync) } while (bench_stats_sym_check(start)); } exit_sha224: - bench_stats_sym_finish("SHA-224", doAsync, count, bench_size, start, ret); + bench_stats_sym_finish("SHA-224", useDeviceID, count, bench_size, start, ret); exit: @@ -3920,7 +3967,7 @@ exit: #endif #ifndef NO_SHA256 -void bench_sha256(int doAsync) +void bench_sha256(int useDeviceID) { wc_Sha256 hash[BENCH_MAX_PENDING]; double start; @@ -3934,7 +3981,7 @@ void bench_sha256(int doAsync) /* init keys */ for (i = 0; i < BENCH_MAX_PENDING; i++) { ret = wc_InitSha256_ex(&hash[i], HEAP_HINT, - doAsync ? devId : INVALID_DEVID); + useDeviceID ? devId : INVALID_DEVID); if (ret != 0) { printf("InitSha256_ex failed, ret = %d\n", ret); goto exit; @@ -3996,7 +4043,7 @@ void bench_sha256(int doAsync) } while (bench_stats_sym_check(start)); } exit_sha256: - bench_stats_sym_finish("SHA-256", doAsync, count, bench_size, start, ret); + bench_stats_sym_finish("SHA-256", useDeviceID, count, bench_size, start, ret); exit: @@ -4009,7 +4056,7 @@ exit: #endif #ifdef WOLFSSL_SHA384 -void bench_sha384(int doAsync) +void bench_sha384(int useDeviceID) { wc_Sha384 hash[BENCH_MAX_PENDING]; double start; @@ -4023,7 +4070,7 @@ void bench_sha384(int doAsync) /* init keys */ for (i = 0; i < BENCH_MAX_PENDING; i++) { ret = wc_InitSha384_ex(&hash[i], HEAP_HINT, - doAsync ? devId : INVALID_DEVID); + useDeviceID ? devId : INVALID_DEVID); if (ret != 0) { printf("InitSha384_ex failed, ret = %d\n", ret); goto exit; @@ -4082,7 +4129,7 @@ void bench_sha384(int doAsync) } while (bench_stats_sym_check(start)); } exit_sha384: - bench_stats_sym_finish("SHA-384", doAsync, count, bench_size, start, ret); + bench_stats_sym_finish("SHA-384", useDeviceID, count, bench_size, start, ret); exit: @@ -4095,7 +4142,7 @@ exit: #endif #ifdef WOLFSSL_SHA512 -void bench_sha512(int doAsync) +void bench_sha512(int useDeviceID) { wc_Sha512 hash[BENCH_MAX_PENDING]; double start; @@ -4109,7 +4156,7 @@ void bench_sha512(int doAsync) /* init keys */ for (i = 0; i < BENCH_MAX_PENDING; i++) { ret = wc_InitSha512_ex(&hash[i], HEAP_HINT, - doAsync ? devId : INVALID_DEVID); + useDeviceID ? devId : INVALID_DEVID); if (ret != 0) { printf("InitSha512_ex failed, ret = %d\n", ret); goto exit; @@ -4168,7 +4215,7 @@ void bench_sha512(int doAsync) } while (bench_stats_sym_check(start)); } exit_sha512: - bench_stats_sym_finish("SHA-512", doAsync, count, bench_size, start, ret); + bench_stats_sym_finish("SHA-512", useDeviceID, count, bench_size, start, ret); exit: @@ -4183,7 +4230,7 @@ exit: #ifdef WOLFSSL_SHA3 #ifndef WOLFSSL_NOSHA3_224 -void bench_sha3_224(int doAsync) +void bench_sha3_224(int useDeviceID) { wc_Sha3 hash[BENCH_MAX_PENDING]; double start; @@ -4197,7 +4244,7 @@ void bench_sha3_224(int doAsync) /* init keys */ for (i = 0; i < BENCH_MAX_PENDING; i++) { ret = wc_InitSha3_224(&hash[i], HEAP_HINT, - doAsync ? devId : INVALID_DEVID); + useDeviceID ? devId : INVALID_DEVID); if (ret != 0) { printf("InitSha3_224 failed, ret = %d\n", ret); goto exit; @@ -4256,7 +4303,7 @@ void bench_sha3_224(int doAsync) } while (bench_stats_sym_check(start)); } exit_sha3_224: - bench_stats_sym_finish("SHA3-224", doAsync, count, bench_size, start, ret); + bench_stats_sym_finish("SHA3-224", useDeviceID, count, bench_size, start, ret); exit: @@ -4269,7 +4316,7 @@ exit: #endif /* WOLFSSL_NOSHA3_224 */ #ifndef WOLFSSL_NOSHA3_256 -void bench_sha3_256(int doAsync) +void bench_sha3_256(int useDeviceID) { wc_Sha3 hash[BENCH_MAX_PENDING]; double start; @@ -4283,7 +4330,7 @@ void bench_sha3_256(int doAsync) /* init keys */ for (i = 0; i < BENCH_MAX_PENDING; i++) { ret = wc_InitSha3_256(&hash[i], HEAP_HINT, - doAsync ? devId : INVALID_DEVID); + useDeviceID ? devId : INVALID_DEVID); if (ret != 0) { printf("InitSha3_256 failed, ret = %d\n", ret); goto exit; @@ -4342,7 +4389,7 @@ void bench_sha3_256(int doAsync) } while (bench_stats_sym_check(start)); } exit_sha3_256: - bench_stats_sym_finish("SHA3-256", doAsync, count, bench_size, start, ret); + bench_stats_sym_finish("SHA3-256", useDeviceID, count, bench_size, start, ret); exit: @@ -4355,7 +4402,7 @@ exit: #endif /* WOLFSSL_NOSHA3_256 */ #ifndef WOLFSSL_NOSHA3_384 -void bench_sha3_384(int doAsync) +void bench_sha3_384(int useDeviceID) { wc_Sha3 hash[BENCH_MAX_PENDING]; double start; @@ -4369,7 +4416,7 @@ void bench_sha3_384(int doAsync) /* init keys */ for (i = 0; i < BENCH_MAX_PENDING; i++) { ret = wc_InitSha3_384(&hash[i], HEAP_HINT, - doAsync ? devId : INVALID_DEVID); + useDeviceID ? devId : INVALID_DEVID); if (ret != 0) { printf("InitSha3_384 failed, ret = %d\n", ret); goto exit; @@ -4428,7 +4475,7 @@ void bench_sha3_384(int doAsync) } while (bench_stats_sym_check(start)); } exit_sha3_384: - bench_stats_sym_finish("SHA3-384", doAsync, count, bench_size, start, ret); + bench_stats_sym_finish("SHA3-384", useDeviceID, count, bench_size, start, ret); exit: @@ -4441,7 +4488,7 @@ exit: #endif /* WOLFSSL_NOSHA3_384 */ #ifndef WOLFSSL_NOSHA3_512 -void bench_sha3_512(int doAsync) +void bench_sha3_512(int useDeviceID) { wc_Sha3 hash[BENCH_MAX_PENDING]; double start; @@ -4455,7 +4502,7 @@ void bench_sha3_512(int doAsync) /* init keys */ for (i = 0; i < BENCH_MAX_PENDING; i++) { ret = wc_InitSha3_512(&hash[i], HEAP_HINT, - doAsync ? devId : INVALID_DEVID); + useDeviceID ? devId : INVALID_DEVID); if (ret != 0) { printf("InitSha3_512 failed, ret = %d\n", ret); goto exit; @@ -4514,7 +4561,7 @@ void bench_sha3_512(int doAsync) } while (bench_stats_sym_check(start)); } exit_sha3_512: - bench_stats_sym_finish("SHA3-512", doAsync, count, bench_size, start, ret); + bench_stats_sym_finish("SHA3-512", useDeviceID, count, bench_size, start, ret); exit: @@ -4713,14 +4760,39 @@ static void bench_cmac_helper(int keySz, const char* outMsg) word32 digestSz = sizeof(digest); double start; int ret, i, count; +#ifdef WOLFSSL_SECO_CAAM + unsigned int keyID; + int keyGroup = 1; /* group one was chosen arbitrarily */ + int keyInfo = CAAM_KEY_TRANSIENT; + int keyType = CAAM_KEYTYPE_AES128; + byte pubKey[AES_256_KEY_SIZE]; + + if (keySz == AES_256_KEY_SIZE) { + keyType = CAAM_KEYTYPE_AES256; + } + + if (wc_SECO_GenerateKey(CAAM_GENERATE_KEY, keyGroup, pubKey, 0, keyType, + keyInfo, &keyID) != 0) { + printf("Error generating key in hsm\n"); + return; + } +#endif bench_stats_start(&count, &start); do { + #ifdef HAVE_FIPS ret = wc_InitCmac(&cmac, bench_key, keySz, WC_CMAC_AES, NULL); + #else + ret = wc_InitCmac_ex(&cmac, bench_key, keySz, WC_CMAC_AES, NULL, + HEAP_HINT, devId); + #endif if (ret != 0) { printf("InitCmac failed, ret = %d\n", ret); return; } + #ifdef WOLFSSL_SECO_CAAM + wc_SECO_CMACSetKeyID(&cmac, keyID); + #endif for (i = 0; i < numBlocks; i++) { ret = wc_CmacUpdate(&cmac, bench_plain, BENCH_SIZE); @@ -4780,7 +4852,7 @@ exit: #ifndef NO_HMAC -static void bench_hmac(int doAsync, int type, int digestSz, +static void bench_hmac(int useDeviceID, int type, int digestSz, byte* key, word32 keySz, const char* label) { Hmac hmac[BENCH_MAX_PENDING]; @@ -4800,7 +4872,7 @@ static void bench_hmac(int doAsync, int type, int digestSz, /* init keys */ for (i = 0; i < BENCH_MAX_PENDING; i++) { ret = wc_HmacInit(&hmac[i], HEAP_HINT, - doAsync ? devId : INVALID_DEVID); + useDeviceID ? devId : INVALID_DEVID); if (ret != 0) { printf("wc_HmacInit failed for %s, ret = %d\n", label, ret); goto exit; @@ -4849,7 +4921,7 @@ static void bench_hmac(int doAsync, int type, int digestSz, } while (pending > 0); } while (bench_stats_sym_check(start)); exit_hmac: - bench_stats_sym_finish(label, doAsync, count, bench_size, start, ret); + bench_stats_sym_finish(label, useDeviceID, count, bench_size, start, ret); exit: @@ -4864,12 +4936,12 @@ exit: #ifndef NO_MD5 -void bench_hmac_md5(int doAsync) +void bench_hmac_md5(int useDeviceID) { byte key[] = { 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b }; - bench_hmac(doAsync, WC_MD5, WC_MD5_DIGEST_SIZE, key, sizeof(key), + bench_hmac(useDeviceID, WC_MD5, WC_MD5_DIGEST_SIZE, key, sizeof(key), "HMAC-MD5"); } @@ -4877,13 +4949,13 @@ void bench_hmac_md5(int doAsync) #ifndef NO_SHA -void bench_hmac_sha(int doAsync) +void bench_hmac_sha(int useDeviceID) { byte key[] = { 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b }; - bench_hmac(doAsync, WC_SHA, WC_SHA_DIGEST_SIZE, key, sizeof(key), + bench_hmac(useDeviceID, WC_SHA, WC_SHA_DIGEST_SIZE, key, sizeof(key), "HMAC-SHA"); } @@ -4891,14 +4963,14 @@ void bench_hmac_sha(int doAsync) #ifdef WOLFSSL_SHA224 -void bench_hmac_sha224(int doAsync) +void bench_hmac_sha224(int useDeviceID) { byte key[] = { 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b }; - bench_hmac(doAsync, WC_SHA224, WC_SHA224_DIGEST_SIZE, key, sizeof(key), + bench_hmac(useDeviceID, WC_SHA224, WC_SHA224_DIGEST_SIZE, key, sizeof(key), "HMAC-SHA224"); } @@ -4906,14 +4978,14 @@ void bench_hmac_sha224(int doAsync) #ifndef NO_SHA256 -void bench_hmac_sha256(int doAsync) +void bench_hmac_sha256(int useDeviceID) { byte key[] = { 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b }; - bench_hmac(doAsync, WC_SHA256, WC_SHA256_DIGEST_SIZE, key, sizeof(key), + bench_hmac(useDeviceID, WC_SHA256, WC_SHA256_DIGEST_SIZE, key, sizeof(key), "HMAC-SHA256"); } @@ -4921,7 +4993,7 @@ void bench_hmac_sha256(int doAsync) #ifdef WOLFSSL_SHA384 -void bench_hmac_sha384(int doAsync) +void bench_hmac_sha384(int useDeviceID) { byte key[] = { 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, @@ -4930,7 +5002,7 @@ void bench_hmac_sha384(int doAsync) 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b }; - bench_hmac(doAsync, WC_SHA384, WC_SHA384_DIGEST_SIZE, key, sizeof(key), + bench_hmac(useDeviceID, WC_SHA384, WC_SHA384_DIGEST_SIZE, key, sizeof(key), "HMAC-SHA384"); } @@ -4938,7 +5010,7 @@ void bench_hmac_sha384(int doAsync) #ifdef WOLFSSL_SHA512 -void bench_hmac_sha512(int doAsync) +void bench_hmac_sha512(int useDeviceID) { byte key[] = { 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, @@ -4949,7 +5021,7 @@ void bench_hmac_sha512(int doAsync) 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b }; - bench_hmac(doAsync, WC_SHA512, WC_SHA512_DIGEST_SIZE, key, sizeof(key), + bench_hmac(useDeviceID, WC_SHA512, WC_SHA512_DIGEST_SIZE, key, sizeof(key), "HMAC-SHA512"); } @@ -5013,7 +5085,7 @@ void bench_siphash(void) #ifndef NO_RSA #if defined(WOLFSSL_KEY_GEN) -static void bench_rsaKeyGen_helper(int doAsync, int keySz) +static void bench_rsaKeyGen_helper(int useDeviceID, int keySz) { RsaKey genKey[BENCH_MAX_PENDING]; double start; @@ -5035,8 +5107,7 @@ static void bench_rsaKeyGen_helper(int doAsync, int keySz) 0, ×, genTimes, &pending)) { wc_FreeRsaKey(&genKey[i]); - ret = wc_InitRsaKey_ex(&genKey[i], HEAP_HINT, - doAsync ? devId : INVALID_DEVID); + ret = wc_InitRsaKey_ex(&genKey[i], HEAP_HINT, devId); if (ret < 0) { goto exit; } @@ -5052,7 +5123,7 @@ static void bench_rsaKeyGen_helper(int doAsync, int keySz) count += times; } while (bench_stats_sym_check(start)); exit: - bench_stats_asym_finish("RSA", keySz, desc[2], doAsync, count, start, ret); + bench_stats_asym_finish("RSA", keySz, desc[2], useDeviceID, count, start, ret); /* cleanup */ for (i = 0; i < BENCH_MAX_PENDING; i++) { @@ -5060,7 +5131,7 @@ exit: } } -void bench_rsaKeyGen(int doAsync) +void bench_rsaKeyGen(int useDeviceID) { int k, keySz; #if !defined(WOLFSSL_SP_MATH) || defined(WOLFSSL_SP_MATH_ALL) @@ -5071,14 +5142,14 @@ void bench_rsaKeyGen(int doAsync) for (k = 0; k < (int)(sizeof(keySizes)/sizeof(int)); k++) { keySz = keySizes[k]; - bench_rsaKeyGen_helper(doAsync, keySz); + bench_rsaKeyGen_helper(useDeviceID, keySz); } } -void bench_rsaKeyGen_size(int doAsync, int keySz) +void bench_rsaKeyGen_size(int useDeviceID, int keySz) { - bench_rsaKeyGen_helper(doAsync, keySz); + bench_rsaKeyGen_helper(useDeviceID, keySz); } #endif /* WOLFSSL_KEY_GEN */ @@ -5189,7 +5260,7 @@ static unsigned char rsa_3072_sig[] = { #endif #endif /* WOLFSSL_RSA_VERIFY_INLINE || WOLFSSL_RSA_PUBLIC_ONLY */ -static void bench_rsa_helper(int doAsync, RsaKey rsaKey[BENCH_MAX_PENDING], +static void bench_rsa_helper(int useDeviceID, RsaKey rsaKey[BENCH_MAX_PENDING], int rsaKeySz) { int ret = 0, i, times, count = 0, pending = 0; @@ -5267,7 +5338,7 @@ static void bench_rsa_helper(int doAsync, RsaKey rsaKey[BENCH_MAX_PENDING], count += times; } while (bench_stats_sym_check(start)); exit_rsa_verify: - bench_stats_asym_finish("RSA", rsaKeySz, desc[0], doAsync, count, + bench_stats_asym_finish("RSA", rsaKeySz, desc[0], useDeviceID, count, start, ret); #endif /* !WOLFSSL_RSA_VERIFY_ONLY */ @@ -5302,7 +5373,7 @@ exit_rsa_verify: count += times; } while (bench_stats_sym_check(start)); exit_rsa_pub: - bench_stats_asym_finish("RSA", rsaKeySz, desc[1], doAsync, count, + bench_stats_asym_finish("RSA", rsaKeySz, desc[1], useDeviceID, count, start, ret); #endif /* !WOLFSSL_RSA_PUBLIC_ONLY */ } @@ -5331,7 +5402,7 @@ exit_rsa_pub: count += times; } while (bench_stats_sym_check(start)); exit_rsa_sign: - bench_stats_asym_finish("RSA", rsaKeySz, desc[4], doAsync, count, start, + bench_stats_asym_finish("RSA", rsaKeySz, desc[4], useDeviceID, count, start, ret); if (ret < 0) { @@ -5384,7 +5455,7 @@ exit_rsa_sign: count += times; } while (bench_stats_sym_check(start)); exit_rsa_verifyinline: - bench_stats_asym_finish("RSA", rsaKeySz, desc[5], doAsync, count, + bench_stats_asym_finish("RSA", rsaKeySz, desc[5], useDeviceID, count, start, ret); } @@ -5397,7 +5468,7 @@ exit: WC_FREE_VAR(message, HEAP_HINT); } -void bench_rsa(int doAsync) +void bench_rsa(int useDeviceID) { int i; RsaKey rsaKey[BENCH_MAX_PENDING]; @@ -5432,7 +5503,7 @@ void bench_rsa(int doAsync) for (i = 0; i < BENCH_MAX_PENDING; i++) { /* setup an async context for each key */ ret = wc_InitRsaKey_ex(&rsaKey[i], HEAP_HINT, - doAsync ? devId : INVALID_DEVID); + useDeviceID ? devId : INVALID_DEVID); if (ret < 0) { goto exit_bench_rsa; } @@ -5477,7 +5548,7 @@ void bench_rsa(int doAsync) } if (rsaKeySz > 0) { - bench_rsa_helper(doAsync, rsaKey, rsaKeySz); + bench_rsa_helper(useDeviceID, rsaKey, rsaKeySz); } (void)bytes; @@ -5493,7 +5564,7 @@ exit_bench_rsa: #ifdef WOLFSSL_KEY_GEN /* bench any size of RSA key */ -void bench_rsa_key(int doAsync, int rsaKeySz) +void bench_rsa_key(int useDeviceID, int rsaKeySz) { int ret = 0, i, pending = 0; RsaKey rsaKey[BENCH_MAX_PENDING]; @@ -5512,7 +5583,7 @@ void bench_rsa_key(int doAsync, int rsaKeySz) * wc_MakeRsaKey again */ /* setup an async context for each key */ if (wc_InitRsaKey_ex(&rsaKey[i], HEAP_HINT, - doAsync ? devId : INVALID_DEVID) < 0) { + useDeviceID ? devId : INVALID_DEVID) < 0) { goto exit_bench_rsa_key; } @@ -5536,7 +5607,7 @@ void bench_rsa_key(int doAsync, int rsaKeySz) } /* for i */ } while (pending > 0); - bench_rsa_helper(doAsync, rsaKey, rsaKeySz); + bench_rsa_helper(useDeviceID, rsaKey, rsaKeySz); exit_bench_rsa_key: /* cleanup */ @@ -5572,7 +5643,7 @@ exit_bench_rsa_key: #endif #define BENCH_DH_PRIV_SIZE (BENCH_DH_KEY_SIZE/8) -void bench_dh(int doAsync) +void bench_dh(int useDeviceID) { int ret = 0, i; int count = 0, times, pending = 0; @@ -5670,7 +5741,7 @@ void bench_dh(int doAsync) for (i = 0; i < BENCH_MAX_PENDING; i++) { /* setup an async context for each key */ ret = wc_InitDhKey_ex(&dhKey[i], HEAP_HINT, - doAsync ? devId : INVALID_DEVID); + useDeviceID ? devId : INVALID_DEVID); if (ret != 0) goto exit; @@ -5728,7 +5799,7 @@ void bench_dh(int doAsync) } while (bench_stats_sym_check(start)); PRIVATE_KEY_LOCK(); exit_dh_gen: - bench_stats_asym_finish("DH", dhKeySz, desc[2], doAsync, count, start, ret); + bench_stats_asym_finish("DH", dhKeySz, desc[2], useDeviceID, count, start, ret); if (ret < 0) { goto exit; @@ -5766,7 +5837,7 @@ exit_dh_gen: } while (bench_stats_sym_check(start)); PRIVATE_KEY_LOCK(); exit: - bench_stats_asym_finish("DH", dhKeySz, desc[3], doAsync, count, start, ret); + bench_stats_asym_finish("DH", dhKeySz, desc[3], useDeviceID, count, start, ret); /* cleanup */ for (i = 0; i < BENCH_MAX_PENDING; i++) { @@ -5814,7 +5885,7 @@ void bench_ecc_curve(int curveId) } -void bench_eccMakeKey(int doAsync, int curveId) +void bench_eccMakeKey(int useDeviceID, int curveId) { int ret = 0, i, times, count, pending = 0; int deviceID; @@ -5825,7 +5896,7 @@ void bench_eccMakeKey(int doAsync, int curveId) const char**desc = bench_desc_words[lng_index]; #ifdef WOLFSSL_ASYNC_CRYPT - deviceID = doAsync ? devId : INVALID_DEVID; + deviceID = useDeviceID ? devId : INVALID_DEVID; #else deviceID = devId; #endif @@ -5867,7 +5938,7 @@ void bench_eccMakeKey(int doAsync, int curveId) exit: XSNPRINTF(name, BENCH_ECC_NAME_SZ, "ECC [%15s]", wc_ecc_get_name(curveId)); - bench_stats_asym_finish(name, keySize * 8, desc[2], doAsync, count, start, + bench_stats_asym_finish(name, keySize * 8, desc[2], useDeviceID, count, start, ret); /* cleanup */ @@ -5877,7 +5948,7 @@ exit: } -void bench_ecc(int doAsync, int curveId) +void bench_ecc(int useDeviceID, int curveId) { int ret = 0, i, times, count, pending = 0; int deviceID; @@ -5905,7 +5976,7 @@ void bench_ecc(int doAsync, int curveId) #endif #ifdef WOLFSSL_ASYNC_CRYPT - deviceID = doAsync ? devId : INVALID_DEVID; + deviceID = useDeviceID ? devId : INVALID_DEVID; #else deviceID = devId; #endif @@ -5979,7 +6050,7 @@ void bench_ecc(int doAsync, int curveId) exit_ecdhe: XSNPRINTF(name, BENCH_ECC_NAME_SZ, "ECDHE [%15s]", wc_ecc_get_name(curveId)); - bench_stats_asym_finish(name, keySize * 8, desc[3], doAsync, count, start, + bench_stats_asym_finish(name, keySize * 8, desc[3], useDeviceID, count, start, ret); if (ret < 0) { @@ -6023,7 +6094,7 @@ exit_ecdhe: exit_ecdsa_sign: XSNPRINTF(name, BENCH_ECC_NAME_SZ, "ECDSA [%15s]", wc_ecc_get_name(curveId)); - bench_stats_asym_finish(name, keySize * 8, desc[4], doAsync, count, start, + bench_stats_asym_finish(name, keySize * 8, desc[4], useDeviceID, count, start, ret); if (ret < 0) { @@ -6059,7 +6130,7 @@ exit_ecdsa_sign: exit_ecdsa_verify: XSNPRINTF(name, BENCH_ECC_NAME_SZ, "ECDSA [%15s]", wc_ecc_get_name(curveId)); - bench_stats_asym_finish(name, keySize * 8, desc[5], doAsync, count, start, + bench_stats_asym_finish(name, keySize * 8, desc[5], useDeviceID, count, start, ret); #endif /* HAVE_ECC_VERIFY */ #endif /* !NO_ASN && HAVE_ECC_SIGN */ @@ -6082,7 +6153,7 @@ exit: WC_FREE_ARRAY(digest, BENCH_MAX_PENDING, HEAP_HINT); #endif - (void)doAsync; + (void)useDeviceID; (void)pending; (void)x; (void)count; @@ -6226,8 +6297,8 @@ void bench_curve25519KeyAgree(void) const char**desc = bench_desc_words[lng_index]; word32 x = 0; - wc_curve25519_init(&genKey); - wc_curve25519_init(&genKey2); + wc_curve25519_init_ex(&genKey, HEAP_HINT, devId); + wc_curve25519_init_ex(&genKey2, HEAP_HINT, devId); ret = wc_curve25519_make_key(&gRng, 32, &genKey); if (ret != 0) { diff --git a/wolfcrypt/src/aes.c b/wolfcrypt/src/aes.c index ab00c8ff5..9362a95cd 100644 --- a/wolfcrypt/src/aes.c +++ b/wolfcrypt/src/aes.c @@ -65,6 +65,10 @@ block cipher mechanism that uses n-bit binary string parameter key with 128-bits #include #endif +#ifdef WOLFSSL_SECO_CAAM +#include +#endif + #ifdef WOLFSSL_IMXRT_DCP #include #endif @@ -2844,6 +2848,44 @@ static WARN_UNUSED_RESULT int wc_AesDecrypt( } #endif + #ifdef WOLFSSL_SECO_CAAM + /* if set to use hardware than import the key */ + if (aes->devId == WOLFSSL_SECO_DEVID) { + int keyGroup = 1; /* group one was chosen arbitrarily */ + unsigned int keyIdOut; + byte importiv[GCM_NONCE_MID_SZ]; + int importivSz = GCM_NONCE_MID_SZ; + int keyType = 0; + WC_RNG rng; + + if (wc_InitRng(&rng) != 0) { + WOLFSSL_MSG("RNG init for IV failed"); + return WC_HW_E; + } + + if (wc_RNG_GenerateBlock(&rng, importiv, importivSz) != 0) { + WOLFSSL_MSG("Generate IV failed"); + wc_FreeRng(&rng); + return WC_HW_E; + } + wc_FreeRng(&rng); + + switch (keylen) { + case AES_128_KEY_SIZE: keyType = CAAM_KEYTYPE_AES128; break; + case AES_192_KEY_SIZE: keyType = CAAM_KEYTYPE_AES192; break; + case AES_256_KEY_SIZE: keyType = CAAM_KEYTYPE_AES256; break; + } + + keyIdOut = wc_SECO_WrapKey(0, (byte*)userKey, keylen, importiv, + importivSz, keyType, CAAM_KEY_TRANSIENT, keyGroup); + if (keyIdOut == 0) { + return WC_HW_E; + } + aes->blackKey = keyIdOut; + return 0; + } + #endif + #if defined(WOLF_CRYPTO_CB) || (defined(WOLFSSL_DEVCRYPTO) && \ (defined(WOLFSSL_DEVCRYPTO_AES) || defined(WOLFSSL_DEVCRYPTO_CBC))) || \ (defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_AES)) @@ -4684,6 +4726,11 @@ int wc_AesGcmSetKey(Aes* aes, const byte* key, word32 len) if (haveAESNI) return ret; #endif /* WOLFSSL_AESNI */ + #if defined(WOLFSSL_SECO_CAAM) + if (aes->devId == WOLFSSL_SECO_DEVID) { + return ret; + } + #endif /* WOLFSSL_SECO_CAAM */ #if !defined(FREESCALE_LTC_AES_GCM) if (ret == 0) @@ -10667,6 +10714,14 @@ static WARN_UNUSED_RESULT int _AesEcbEncrypt( { word32 blocks = sz / AES_BLOCK_SIZE; +#ifdef WOLF_CRYPTO_CB + if (aes->devId != INVALID_DEVID) { + int ret = wc_CryptoCb_AesEcbEncrypt(aes, out, in, sz); + if (ret != CRYPTOCB_UNAVAILABLE) + return ret; + /* fall-through when unavailable */ + } +#endif #ifdef WOLFSSL_IMXRT_DCP if (aes->keylen == 16) return DCPAesEcbEncrypt(aes, out, in, sz); @@ -10687,6 +10742,14 @@ static WARN_UNUSED_RESULT int _AesEcbDecrypt( { word32 blocks = sz / AES_BLOCK_SIZE; +#ifdef WOLF_CRYPTO_CB + if (aes->devId != INVALID_DEVID) { + int ret = wc_CryptoCb_AesEcbDecrypt(aes, out, in, sz); + if (ret != CRYPTOCB_UNAVAILABLE) + return ret; + /* fall-through when unavailable */ + } +#endif #ifdef WOLFSSL_IMXRT_DCP if (aes->keylen == 16) return DCPAesEcbDecrypt(aes, out, in, sz); diff --git a/wolfcrypt/src/cmac.c b/wolfcrypt/src/cmac.c index 1b675d7cf..d9bcd411c 100644 --- a/wolfcrypt/src/cmac.c +++ b/wolfcrypt/src/cmac.c @@ -28,6 +28,9 @@ #ifdef WOLFSSL_QNX_CAAM #include #endif +#if defined(WOLFSSL_HASH_KEEP) +#include +#endif #if defined(WOLFSSL_CMAC) && !defined(NO_AES) && defined(WOLFSSL_AES_DIRECT) @@ -56,6 +59,18 @@ #include #endif +#ifdef WOLFSSL_HASH_KEEP +/* Some hardware have issues with update, this function stores the data to be + * hashed into an array. Once ready, the Final operation is called on all of the + * data to be hashed at once. + * returns 0 on success + */ +int wc_CMAC_Grow(Cmac* cmac, const byte* in, int inSz) +{ + return _wc_Hash_Grow(&cmac->msg, &cmac->used, &cmac->len, in, inSz, NULL); +} +#endif /* WOLFSSL_HASH_KEEP */ + /* Used by AES-SIV. See aes.c. */ void ShiftAndXorRb(byte* out, byte* in) @@ -86,7 +101,7 @@ int wc_InitCmac_ex(Cmac* cmac, const byte* key, word32 keySz, (void)unused; (void)heap; - if (cmac == NULL || keySz == 0 || type != WC_CMAC_AES) { + if (cmac == NULL || type != WC_CMAC_AES) { return BAD_FUNC_ARG; } @@ -107,7 +122,7 @@ int wc_InitCmac_ex(Cmac* cmac, const byte* key, word32 keySz, (void)devId; #endif - if (key == NULL) { + if (key == NULL || keySz == 0) { return BAD_FUNC_ARG; } @@ -226,6 +241,12 @@ int wc_CmacFinal(Cmac* cmac, byte* out, word32* outSz) XMEMCPY(out, cmac->digest, *outSz); } +#if defined(WOLFSSL_HASH_KEEP) + if (cmac->msg != NULL) { + XFREE(cmac->msg, cmac->heap, DYNAMIC_TYPE_TMP_BUFFER); + cmac->msg = NULL; + } +#endif wc_AesFree(&cmac->aes); ForceZero(cmac, sizeof(Cmac)); diff --git a/wolfcrypt/src/cryptocb.c b/wolfcrypt/src/cryptocb.c index b06ef2552..dc4ccaddb 100644 --- a/wolfcrypt/src/cryptocb.c +++ b/wolfcrypt/src/cryptocb.c @@ -727,6 +727,71 @@ int wc_CryptoCb_AesCbcDecrypt(Aes* aes, byte* out, return wc_CryptoCb_TranslateErrorCode(ret); } #endif /* HAVE_AES_CBC */ +#ifdef HAVE_AES_ECB +int wc_CryptoCb_AesEcbEncrypt(Aes* aes, byte* out, + const byte* in, word32 sz) +{ + int ret = CRYPTOCB_UNAVAILABLE; + CryptoCb* dev; + + /* locate registered callback */ + if (aes) { + dev = wc_CryptoCb_FindDevice(aes->devId); + } + else { + /* locate first callback and try using it */ + dev = wc_CryptoCb_FindDeviceByIndex(0); + } + + if (dev && dev->cb) { + wc_CryptoInfo cryptoInfo; + XMEMSET(&cryptoInfo, 0, sizeof(cryptoInfo)); + cryptoInfo.algo_type = WC_ALGO_TYPE_CIPHER; + cryptoInfo.cipher.type = WC_CIPHER_AES_ECB; + cryptoInfo.cipher.enc = 1; + cryptoInfo.cipher.aesecb.aes = aes; + cryptoInfo.cipher.aesecb.out = out; + cryptoInfo.cipher.aesecb.in = in; + cryptoInfo.cipher.aesecb.sz = sz; + + ret = dev->cb(dev->devId, &cryptoInfo, dev->ctx); + } + + return wc_CryptoCb_TranslateErrorCode(ret); +} + +int wc_CryptoCb_AesEcbDecrypt(Aes* aes, byte* out, + const byte* in, word32 sz) +{ + int ret = CRYPTOCB_UNAVAILABLE; + CryptoCb* dev; + + /* locate registered callback */ + if (aes) { + dev = wc_CryptoCb_FindDevice(aes->devId); + } + else { + /* locate first callback and try using it */ + dev = wc_CryptoCb_FindDeviceByIndex(0); + } + + if (dev && dev->cb) { + wc_CryptoInfo cryptoInfo; + XMEMSET(&cryptoInfo, 0, sizeof(cryptoInfo)); + cryptoInfo.algo_type = WC_ALGO_TYPE_CIPHER; + cryptoInfo.cipher.type = WC_CIPHER_AES_ECB; + cryptoInfo.cipher.enc = 0; + cryptoInfo.cipher.aesecb.aes = aes; + cryptoInfo.cipher.aesecb.out = out; + cryptoInfo.cipher.aesecb.in = in; + cryptoInfo.cipher.aesecb.sz = sz; + + ret = dev->cb(dev->devId, &cryptoInfo, dev->ctx); + } + + return wc_CryptoCb_TranslateErrorCode(ret); +} +#endif /* HAVE_AES_ECB */ #endif /* !NO_AES */ #ifndef NO_DES3 @@ -1051,4 +1116,18 @@ int wc_CryptoCb_Cmac(Cmac* cmac, const byte* key, word32 keySz, } #endif +/* returns the default dev id for the current build */ +int wc_CryptoCb_DefaultDevID() +{ + int ret; + + /* conditional macro selection based on build */ +#ifdef WOLFSSL_CAAM_DEVID + ret = WOLFSSL_CAAM_DEVID; +#else + ret = INVALID_DEVID; +#endif + + return ret; +} #endif /* WOLF_CRYPTO_CB */ diff --git a/wolfcrypt/src/ecc.c b/wolfcrypt/src/ecc.c index 28e8013eb..d85ed9e4e 100644 --- a/wolfcrypt/src/ecc.c +++ b/wolfcrypt/src/ecc.c @@ -185,7 +185,7 @@ ECC Curve Sizes: #include #endif -#if defined(WOLFSSL_QNX_CAAM) +#if defined(WOLFSSL_CAAM) #include #endif @@ -9184,9 +9184,10 @@ static int _ecc_validate_public_key(ecc_key* key, int partial, int priv) XMEMSET(b, 0, sizeof(mp_int)); #endif - #ifdef WOLFSSL_QNX_CAAM - /* NIST P256 keys can be black encrypted ones */ - if (key->blackKey > 0 && wc_ecc_size(key) == 32) { + #ifdef WOLFSSL_CAAM + /* keys can be black encrypted ones which can not be checked like plain text + * keys */ + if (key->blackKey > 0) { /* encrypted key was used */ #ifdef WOLFSSL_SMALL_STACK XFREE(b, key->heap, DYNAMIC_TYPE_ECC); @@ -9610,6 +9611,13 @@ int wc_ecc_export_ex(ecc_key* key, byte* qx, word32* qxLen, /* Hardware cannot export private portion */ return NOT_COMPILED_IN; #else + #if defined(WOLFSSL_SECO_CAAM) + if (key->blackKey > 0 && key->devId == WOLFSSL_SECO_DEVID) { + /* Hardware cannot export private portion */ + WOLFSSL_MSG("Can not export private key from HSM"); + return NOT_COMPILED_IN; + } + #endif #ifdef WOLFSSL_QNX_CAAM if (encType == WC_TYPE_BLACK_KEY) { if (key->blackKey > 0) { diff --git a/wolfcrypt/src/hash.c b/wolfcrypt/src/hash.c index 30b382e60..282c39f86 100644 --- a/wolfcrypt/src/hash.c +++ b/wolfcrypt/src/hash.c @@ -1706,3 +1706,30 @@ int wc_HashGetFlags(wc_HashAlg* hash, enum wc_HashType type, word32* flags) #endif /* !NO_HASH_WRAPPER */ +#ifdef WOLFSSL_HASH_KEEP +int _wc_Hash_Grow(byte** msg, word32* used, word32* len, const byte* in, + int inSz, void* heap) +{ + if (*len < *used + inSz) { + if (*msg == NULL) { + *msg = (byte*)XMALLOC(*used + inSz, heap, DYNAMIC_TYPE_TMP_BUFFER); + } + else { + byte* pt = (byte*)XREALLOC(*msg, *used + inSz, heap, + DYNAMIC_TYPE_TMP_BUFFER); + if (pt == NULL) { + return MEMORY_E; + } + *msg = pt; + } + if (*msg == NULL) { + return MEMORY_E; + } + *len = *used + inSz; + } + XMEMCPY(*msg + *used, in, inSz); + *used += inSz; + return 0; +} +#endif /* WOLFSSL_HASH_KEEP */ + diff --git a/wolfcrypt/src/hmac.c b/wolfcrypt/src/hmac.c index 3e65cc343..7cb64e3b6 100644 --- a/wolfcrypt/src/hmac.c +++ b/wolfcrypt/src/hmac.c @@ -1010,6 +1010,9 @@ int wc_HmacInit(Hmac* hmac, void* heap, int devId) hmac->devId = devId; hmac->devCtx = NULL; #endif +#if defined(WOLFSSL_DEVCRYPTO_HMAC) + hmac->ctx.cfd = -1; +#endif #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_HMAC) ret = wolfAsync_DevCtxInit(&hmac->asyncDev, WOLFSSL_ASYNC_MARKER_HMAC, diff --git a/wolfcrypt/src/include.am b/wolfcrypt/src/include.am index 7f25d17d7..d2bdf734d 100644 --- a/wolfcrypt/src/include.am +++ b/wolfcrypt/src/include.am @@ -77,9 +77,15 @@ EXTRA_DIST += wolfcrypt/src/port/ti/ti-aes.c \ wolfcrypt/src/port/caam/caam_sha.c \ wolfcrypt/src/port/caam/caam_doc.pdf \ wolfcrypt/src/port/caam/wolfcaam_init.c \ + wolfcrypt/src/port/caam/wolfcaam_seco.c \ wolfcrypt/src/port/caam/wolfcaam_qnx.c \ + wolfcrypt/src/port/caam/wolfcaam_x25519.c \ wolfcrypt/src/port/caam/wolfcaam_ecdsa.c \ wolfcrypt/src/port/caam/wolfcaam_cmac.c \ + wolfcrypt/src/port/caam/wolfcaam_hash.c \ + wolfcrypt/src/port/caam/wolfcaam_rsa.c \ + wolfcrypt/src/port/caam/wolfcaam_hmac.c \ + wolfcrypt/src/port/caam/wolfcaam_aes.c \ wolfcrypt/src/port/silabs/silabs_aes.c \ wolfcrypt/src/port/silabs/silabs_ecc.c \ wolfcrypt/src/port/silabs/silabs_hash.c \ @@ -130,6 +136,10 @@ src_libwolfssl_la_SOURCES += wolfcrypt/src/wc_pkcs11.c endif if BUILD_DEVCRYPTO +src_libwolfssl_la_SOURCES += wolfcrypt/src/port/devcrypto/devcrypto_ecdsa.c +src_libwolfssl_la_SOURCES += wolfcrypt/src/port/devcrypto/devcrypto_x25519.c +src_libwolfssl_la_SOURCES += wolfcrypt/src/port/devcrypto/devcrypto_rsa.c +src_libwolfssl_la_SOURCES += wolfcrypt/src/port/devcrypto/devcrypto_hmac.c src_libwolfssl_la_SOURCES += wolfcrypt/src/port/devcrypto/devcrypto_hash.c src_libwolfssl_la_SOURCES += wolfcrypt/src/port/devcrypto/devcrypto_aes.c src_libwolfssl_la_SOURCES += wolfcrypt/src/port/devcrypto/wc_devcrypto.c @@ -167,8 +177,14 @@ endif if BUILD_CAAM src_libwolfssl_la_SOURCES += wolfcrypt/src/port/caam/wolfcaam_init.c src_libwolfssl_la_SOURCES += wolfcrypt/src/port/caam/wolfcaam_qnx.c +src_libwolfssl_la_SOURCES += wolfcrypt/src/port/caam/wolfcaam_seco.c +src_libwolfssl_la_SOURCES += wolfcrypt/src/port/caam/wolfcaam_x25519.c src_libwolfssl_la_SOURCES += wolfcrypt/src/port/caam/wolfcaam_ecdsa.c src_libwolfssl_la_SOURCES += wolfcrypt/src/port/caam/wolfcaam_cmac.c +src_libwolfssl_la_SOURCES += wolfcrypt/src/port/caam/wolfcaam_aes.c +src_libwolfssl_la_SOURCES += wolfcrypt/src/port/caam/wolfcaam_hash.c +src_libwolfssl_la_SOURCES += wolfcrypt/src/port/caam/wolfcaam_rsa.c +src_libwolfssl_la_SOURCES += wolfcrypt/src/port/caam/wolfcaam_hmac.c endif if BUILD_SE050 diff --git a/wolfcrypt/src/port/caam/wolfcaam_aes.c b/wolfcrypt/src/port/caam/wolfcaam_aes.c new file mode 100644 index 000000000..23fecb2e8 --- /dev/null +++ b/wolfcrypt/src/port/caam/wolfcaam_aes.c @@ -0,0 +1,270 @@ +/* wolfcaam_aes.c + * + * Copyright (C) 2006-2021 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + +#ifdef HAVE_CONFIG_H + #include +#endif + +#include + +#if (WOLFSSL_CAAM) && !defined(NO_AES) + +#include +#include +#include +#include + +/* return 0 on success */ +static int wc_CAAM_AesAeadCommon(Aes* aes, const byte* in, byte* out, word32 sz, + const byte* nonce, word32 nonceSz, byte* authTag, word32 authTagSz, + const byte* authIn, word32 authInSz, int dir, int type) +{ + CAAM_BUFFER buf[7]; + int ret, idx = 0; + word32 arg[4]; + word32 keySz; + + if (aes == NULL) { + return BAD_FUNC_ARG; + } + + if (wc_AesGetKeySize(aes, &keySz) != 0 && aes->blackKey == 0) { + return BAD_FUNC_ARG; + } + + buf[idx].BufferType = DataBuffer; + buf[idx].TheAddress = (CAAM_ADDRESS)aes->key; + buf[idx].Length = keySz; + idx++; + + buf[idx].BufferType = DataBuffer; + buf[idx].TheAddress = (CAAM_ADDRESS)nonce; + buf[idx].Length = nonceSz; + idx++; + + buf[idx].BufferType = DataBuffer; + buf[idx].TheAddress = (CAAM_ADDRESS)in; + buf[idx].Length = sz; + idx++; + + buf[idx].BufferType = DataBuffer; + buf[idx].TheAddress = (CAAM_ADDRESS)out; + buf[idx].Length = sz; + idx++; + + buf[idx].BufferType = DataBuffer; + buf[idx].TheAddress = (CAAM_ADDRESS)authTag; + buf[idx].Length = authTagSz; + idx++; + + buf[idx].BufferType = DataBuffer | LastBuffer; + buf[idx].TheAddress = (CAAM_ADDRESS)authIn; + buf[idx].Length = authInSz; + idx++; + + arg[0] = dir; + arg[1] = keySz; + arg[2] = sz; + arg[3] = aes->blackKey; + + if ((ret = wc_caamAddAndWait(buf, idx, arg, type)) != 0) { + WOLFSSL_MSG("Error with CAAM AES CCM operation"); + return ret; + } + + return 0; +} + + +/* plaintext in ciphertext and mac out + * return 0 on success + */ +int wc_CAAM_AesCcmEncrypt(Aes* aes, const byte* in, byte* out, word32 sz, + const byte* nonce, word32 nonceSz, byte* authTag, word32 authTagSz, + const byte* authIn, word32 authInSz) +{ + return wc_CAAM_AesAeadCommon(aes, in, out, sz, nonce, nonceSz, authTag, + authTagSz, authIn, authInSz, CAAM_ENC, CAAM_AESCCM); +} + + +/* ciphertext in plaintext out + * return 0 on success + */ +int wc_CAAM_AesCcmDecrypt(Aes* aes, const byte* in, byte* out, word32 sz, + const byte* nonce, word32 nonceSz, const byte* authTag, + word32 authTagSz, const byte* authIn, word32 authInSz) +{ + return wc_CAAM_AesAeadCommon(aes, in, out, sz, nonce, nonceSz, + (byte*)authTag, authTagSz, authIn, authInSz, CAAM_DEC, CAAM_AESCCM); +} + + +int wc_CAAM_AesGcmEncrypt(Aes* aes, const byte* in, byte* out, word32 sz, + const byte* nonce, word32 nonceSz, byte* authTag, word32 authTagSz, + const byte* authIn, word32 authInSz) +{ + return wc_CAAM_AesAeadCommon(aes, in, out, sz, nonce, nonceSz, authTag, + authTagSz, authIn, authInSz, CAAM_ENC, CAAM_AESGCM); +} + + +int wc_CAAM_AesGcmDecrypt(Aes* aes, const byte* in, byte* out, word32 sz, + const byte* nonce, word32 nonceSz, const byte* authTag, + word32 authTagSz, const byte* authIn, word32 authInSz) +{ + return wc_CAAM_AesAeadCommon(aes, in, out, sz, nonce, nonceSz, + (byte*)authTag, authTagSz, authIn, authInSz, CAAM_DEC, CAAM_AESGCM); +} + + +static int wc_CAAM_AesCbcCommon(Aes* aes, byte* out, const byte* in, word32 sz, + int dir) +{ + word32 blocks; + + if (aes == NULL || out == NULL || in == NULL) { + return BAD_FUNC_ARG; + } + + blocks = sz / AES_BLOCK_SIZE; + + if (blocks > 0) { + CAAM_BUFFER buf[4]; + word32 arg[4]; + word32 keySz; + int ret; + + if (wc_AesGetKeySize(aes, &keySz) != 0 && aes->blackKey == 0) { + return BAD_FUNC_ARG; + } + + /* Set buffers for key, cipher text, and plain text */ + buf[0].BufferType = DataBuffer; + buf[0].TheAddress = (CAAM_ADDRESS)aes->key; + buf[0].Length = keySz; + + buf[1].BufferType = DataBuffer; + buf[1].TheAddress = (CAAM_ADDRESS)aes->reg; + buf[1].Length = AES_BLOCK_SIZE; + + buf[2].BufferType = DataBuffer; + buf[2].TheAddress = (CAAM_ADDRESS)in; + buf[2].Length = blocks * AES_BLOCK_SIZE; + + buf[3].BufferType = DataBuffer | LastBuffer; + buf[3].TheAddress = (CAAM_ADDRESS)out; + buf[3].Length = blocks * AES_BLOCK_SIZE; + + arg[0] = dir; + arg[1] = keySz; + arg[2] = blocks * AES_BLOCK_SIZE; + arg[3] = aes->blackKey; + + if ((ret = wc_caamAddAndWait(buf, 4, arg, CAAM_AESCBC)) != 0) { + WOLFSSL_MSG("Error with CAAM AES CBC operation"); + return ret; + } + } + + return 0; +} + +int wc_CAAM_AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz) +{ + return wc_CAAM_AesCbcCommon(aes, out, in, sz, CAAM_ENC); +} + + +int wc_CAAM_AesCbcDecrypt(Aes* aes, byte* out, const byte* in, word32 sz) +{ + return wc_CAAM_AesCbcCommon(aes, out, in, sz, CAAM_DEC); +} + +#if defined(HAVE_AES_ECB) +static int wc_CAAM_AesEcbCommon(Aes* aes, byte* out, const byte* in, word32 sz, + int dir) +{ + word32 blocks; + CAAM_BUFFER buf[4]; + word32 arg[4]; + word32 keySz = 0; + int ret; + int idx = 0; + + if (aes == NULL || out == NULL || in == NULL) { + return BAD_FUNC_ARG; + } + + blocks = sz / AES_BLOCK_SIZE; + + if (wc_AesGetKeySize(aes, &keySz) != 0 && aes->blackKey == 0) { + return BAD_FUNC_ARG; + } + + /* Set buffers for key, cipher text, and plain text */ + buf[idx].BufferType = DataBuffer; + buf[idx].TheAddress = (CAAM_ADDRESS)aes->key; + buf[idx].Length = keySz; + idx++; + + buf[idx].BufferType = DataBuffer; + buf[idx].TheAddress = (CAAM_ADDRESS)aes->reg; + buf[idx].Length = 0; /* NO IV */ + idx++; + + buf[idx].BufferType = DataBuffer; + buf[idx].TheAddress = (CAAM_ADDRESS)in; + buf[idx].Length = blocks * AES_BLOCK_SIZE; + idx++; + + buf[idx].BufferType = DataBuffer | LastBuffer; + buf[idx].TheAddress = (CAAM_ADDRESS)out; + buf[idx].Length = blocks * AES_BLOCK_SIZE; + idx++; + + arg[0] = dir; + arg[1] = keySz; + arg[2] = blocks * AES_BLOCK_SIZE; + arg[3] = aes->blackKey; + + if ((ret = wc_caamAddAndWait(buf, idx, arg, CAAM_AESECB)) != 0) { + WOLFSSL_MSG("Error with CAAM AES ECB encrypt"); + return ret; + } + + return 0; +} + + +/* is assumed that input size is a multiple of AES_BLOCK_SIZE */ +int wc_CAAM_AesEcbEncrypt(Aes* aes, byte* out, const byte* in, word32 sz) +{ + return wc_CAAM_AesEcbCommon(aes, out, in, sz, CAAM_ENC); +} + + +int wc_CAAM_AesEcbDecrypt(Aes* aes, byte* out, const byte* in, word32 sz) +{ + return wc_CAAM_AesEcbCommon(aes, out, in, sz, CAAM_DEC); +} +#endif /* HAVE_AES_ECB */ +#endif /* WOLFSSL_CAAM && !NO_AES */ diff --git a/wolfcrypt/src/port/caam/wolfcaam_cmac.c b/wolfcrypt/src/port/caam/wolfcaam_cmac.c index 3d44c8a35..b5c56059a 100644 --- a/wolfcrypt/src/port/caam/wolfcaam_cmac.c +++ b/wolfcrypt/src/port/caam/wolfcaam_cmac.c @@ -25,7 +25,7 @@ #include -#if defined(WOLFSSL_QNX_CAAM) && defined(WOLFSSL_CMAC) +#if defined(WOLFSSL_CAAM) && defined(WOLFSSL_CMAC) #include #include @@ -52,15 +52,20 @@ int wc_CAAM_Cmac(Cmac* cmac, const byte* key, word32 keySz, const byte* in, return BAD_FUNC_ARG; } + if (out != NULL && outSz == NULL) { + return BAD_FUNC_ARG; + } + if (key != NULL || ctx != NULL) { XMEMSET(&cmac->aes, 0, sizeof(Aes)); - if (ctx != NULL) { - cmac->blackKey = 1; - XMEMCPY((byte*)cmac->aes.key, (byte*)ctx, keySz + 16); - } - else { - cmac->blackKey = 0; - XMEMCPY((byte*)cmac->aes.key, (byte*)key, keySz); + if (cmac->blackKey == 0) { + if (ctx != NULL) { + cmac->blackKey = 1; + XMEMCPY((byte*)cmac->aes.key, (byte*)ctx, keySz + 16); + } + else { + XMEMCPY((byte*)cmac->aes.key, (byte*)key, keySz); + } } cmac->keylen = keySz; cmac->initialized = 0; @@ -78,6 +83,12 @@ int wc_CAAM_Cmac(Cmac* cmac, const byte* key, word32 keySz, const byte* in, idx++; if (in != NULL) { + #ifdef WOLFSSL_HASH_KEEP + if (wc_CMAC_Grow(cmac, in, inSz) != 0) { + WOLFSSL_MSG("Error growing CMAC buffer"); + return -1; + } + #else args[0] |= CAAM_ALG_UPDATE; /* first take care of any left overs */ @@ -123,17 +134,24 @@ int wc_CAAM_Cmac(Cmac* cmac, const byte* key, word32 keySz, const byte* in, pt += buf[idx].Length; idx++; } - + #endif } if (out != NULL) { + #ifdef WOLFSSL_HASH_KEEP + if (cmac->msg != NULL) { + buf[idx].TheAddress = (CAAM_ADDRESS)cmac->msg; + buf[idx].Length = cmac->used; + idx++; + } + #else /* handle any leftovers */ if (cmac->bufferSz > 0) { buf[idx].TheAddress = (CAAM_ADDRESS)cmac->buffer; buf[idx].Length = cmac->bufferSz; idx++; } - + #endif args[0] |= CAAM_ALG_FINAL; blocks++; /* always run on final call */ } @@ -161,12 +179,20 @@ int wc_CAAM_Cmac(Cmac* cmac, const byte* key, word32 keySz, const byte* in, /* store leftovers */ if (sz > 0) { - word32 add = min(sz, AES_BLOCK_SIZE - cmac->bufferSz); + word32 add = (sz < (int)(AES_BLOCK_SIZE - cmac->bufferSz))? + (word32)sz : + (AES_BLOCK_SIZE - cmac->bufferSz); + + if (pt == NULL) { + return MEMORY_E; + } XMEMCPY(&cmac->buffer[cmac->bufferSz], pt, add); cmac->bufferSz += add; } + (void)scratch; return 0; } -#endif /* WOLFSSL_QNX_CAAM && WOLFSSL_CMAC */ +#endif /* WOLFSSL_CAAM && WOLFSSL_CMAC */ + diff --git a/wolfcrypt/src/port/caam/wolfcaam_ecdsa.c b/wolfcrypt/src/port/caam/wolfcaam_ecdsa.c index 8a6e74140..83cdba955 100644 --- a/wolfcrypt/src/port/caam/wolfcaam_ecdsa.c +++ b/wolfcrypt/src/port/caam/wolfcaam_ecdsa.c @@ -25,7 +25,7 @@ #include -#if defined(WOLFSSL_QNX_CAAM) && defined(HAVE_ECC) +#if defined(WOLFSSL_CAAM) && defined(HAVE_ECC) #include #include @@ -47,6 +47,199 @@ #include #endif +#if defined(WOLFSSL_DEVCRYPTO_ECDSA) +/* offload calls through devcrypto support */ + + +/* create signature using CAAM + * returns MP_OKAY on success + */ +static int wc_CAAM_DevEccSign(const byte* in, int inlen, byte* out, + word32* outlen, WC_RNG *rng, ecc_key *key) +{ + const ecc_set_type* dp; + int ret, keySz; + byte r[MAX_ECC_BYTES] = {0}; + byte s[MAX_ECC_BYTES] = {0}; + + byte pk[MAX_ECC_BYTES] = {0}; + + (void)rng; + if (key->dp != NULL) { + dp = key->dp; + } + else { + dp = wc_ecc_get_curve_params(key->idx); + } + + if (dp->id != ECC_SECP256R1 && dp->id != ECC_SECP384R1) { + WOLFSSL_MSG("Limiting CAAM to P256 and P384 for now"); + return CRYPTOCB_UNAVAILABLE; + } + keySz = wc_ecc_size(key); + + /* private key */ + if (mp_to_unsigned_bin_len(&key->k, pk, keySz) != MP_OKAY) { + return MP_TO_E; + } + + ret = wc_DevCryptoEccSign(dp->id, key->blackKey, pk, keySz, in, inlen, + r, keySz, s, keySz); + + /* convert signature from raw bytes to signature format */ + if (ret == 0) { + mp_int mpr, mps; + + mp_init(&mpr); + mp_init(&mps); + + mp_read_unsigned_bin(&mpr, r, keySz); + mp_read_unsigned_bin(&mps, s, keySz); + + ret = StoreECC_DSA_Sig(out, outlen, &mpr, &mps); + mp_free(&mpr); + mp_free(&mps); + if (ret != 0) { + WOLFSSL_MSG("Issue converting to signature\n"); + return -1; + } + } + + return ret; +} + + +/* verify with individual r and s signature parts + * returns MP_OKAY on success and sets 'res' to 1 if verified + */ +static int wc_CAAM_DevEccVerify_ex(mp_int* r, mp_int *s, const byte* hash, + word32 hashlen, int* res, ecc_key* key) +{ + const ecc_set_type* dp; + int ret; + int keySz; + + byte rbuf[MAX_ECC_BYTES] = {0}; + byte sbuf[MAX_ECC_BYTES] = {0}; + + byte qx[MAX_ECC_BYTES] = {0}; + byte qy[MAX_ECC_BYTES] = {0}; + byte qxy[MAX_ECC_BYTES * 2] = {0}; + word32 qxLen, qyLen; + + if (key->dp != NULL) { + dp = key->dp; + } + else { + dp = wc_ecc_get_curve_params(key->idx); + } + + /* Wx,y public key */ + keySz = wc_ecc_size(key); + qxLen = qyLen = MAX_ECC_BYTES; + wc_ecc_export_public_raw(key, qx, &qxLen, qy, &qyLen); + XMEMCPY(qxy, qx, qxLen); + XMEMCPY(qxy+qxLen, qy, qyLen); + + if (mp_to_unsigned_bin_len(r, rbuf, keySz) != MP_OKAY) { + return MP_TO_E; + } + if (mp_to_unsigned_bin_len(s, sbuf, keySz) != MP_OKAY) { + return MP_TO_E; + } + ret = wc_DevCryptoEccVerify(dp->id, qxy, qxLen + qyLen, hash, hashlen, + rbuf, keySz, sbuf, keySz); + + *res = 0; + if (ret == 0) + *res = 1; + + return ret; +} + + +/* Does ECDH operation using CAAM and returns MP_OKAY on success */ +static int wc_CAAM_DevEcdh(ecc_key* private_key, ecc_key* public_key, byte* out, + word32* outlen) +{ + const ecc_set_type* dp; + int ret, keySz; + + byte pk[MAX_ECC_BYTES] = {0}; + byte qx[MAX_ECC_BYTES] = {0}; + byte qy[MAX_ECC_BYTES] = {0}; + byte qxy[MAX_ECC_BYTES * 2] = {0}; + word32 qxSz, qySz; + + if (private_key->dp != NULL) { + dp = private_key->dp; + } + else { + dp = wc_ecc_get_curve_params(private_key->idx); + } + + keySz = wc_ecc_size(private_key); + if (*outlen < (word32)keySz) { + WOLFSSL_MSG("out buffer is to small"); + return BUFFER_E; + } + + /* public key */ + qxSz = qySz = MAX_ECC_BYTES; + wc_ecc_export_public_raw(public_key, qx, &qxSz, qy, &qySz); + XMEMCPY(qxy, qx, qxSz); + XMEMCPY(qxy+qxSz, qy, qySz); + + /* private key */ + if (mp_to_unsigned_bin_len(&private_key->k, pk, keySz) != MP_OKAY) { + WOLFSSL_MSG("error getting private key buffer"); + return MP_TO_E; + } + + ret = wc_DevCryptoEccEcdh(dp->id, private_key->blackKey, pk, keySz, + qxy, qxSz + qySz, out, *outlen); + if (ret == 0) { + *outlen = keySz; + } + return ret; +} + + +#ifdef WOLFSSL_KEY_GEN +/* [ private black key ] [ x , y ] */ +static int wc_CAAM_DevMakeEccKey(WC_RNG* rng, int keySize, ecc_key* key, + int curveId) +{ + int ret; + int blackKey = 1; /* default to using black encrypted keys */ + + byte s[MAX_ECC_BYTES] = {0}; + byte xy[MAX_ECC_BYTES*2] = {0}; + + key->type = ECC_PRIVATEKEY; + + /* if set to default curve then assume SECP256R1 */ + if (keySize == 32 && curveId == ECC_CURVE_DEF) curveId = ECC_SECP256R1; + + if (curveId != ECC_SECP256R1 && + curveId != ECC_SECP384R1) { + return CRYPTOCB_UNAVAILABLE; + } + + ret = wc_DevCryptoEccKeyGen(curveId, blackKey, s, keySize, xy, keySize*2); + if (wc_ecc_import_unsigned(key, xy, xy + keySize, s, curveId) != 0) { + WOLFSSL_MSG("issue importing key"); + return -1; + } + key->blackKey = blackKey; + + (void)rng; + return ret; +} +#endif /* WOLFSSL_KEY_GEN */ + +#endif /* WOLFSSL_DEVCRYPTO_ECDSA */ + /* helper function get the ECDSEL value, this is a value that signals the * hardware to use preloaded curve parameters */ @@ -88,7 +281,7 @@ static word32 GetECDSEL(int curveId, word32 PD_BIT) * returns MP_OKAY on success */ int wc_CAAM_EccSign(const byte* in, int inlen, byte* out, word32* outlen, - WC_RNG *rng, ecc_key *key) + WC_RNG *rng, ecc_key *key, int devId) { const ecc_set_type* dp; word32 args[4] = {0}; @@ -98,9 +291,14 @@ int wc_CAAM_EccSign(const byte* in, int inlen, byte* out, word32* outlen, byte r[MAX_ECC_BYTES] = {0}; byte s[MAX_ECC_BYTES] = {0}; word32 idx = 0; - byte pk[MAX_ECC_BYTES] = {0}; +#if defined(WOLFSSL_DEVCRYPTO_ECDSA) + if (devId == WOLFSSL_CAAM_DEVID) { + return wc_CAAM_DevEccSign(in, inlen, out, outlen, rng, key); + } +#endif + (void)rng; if (key->dp != NULL) { dp = key->dp; @@ -109,8 +307,8 @@ int wc_CAAM_EccSign(const byte* in, int inlen, byte* out, word32* outlen, dp = wc_ecc_get_curve_params(key->idx); } - if (dp->id != ECC_SECP256R1) { - WOLFSSL_MSG("Limiting CAAM to P256 for now"); + if (dp->id != ECC_SECP256R1 && dp->id != ECC_SECP384R1) { + WOLFSSL_MSG("Limiting CAAM to P256/P384 for now"); return CRYPTOCB_UNAVAILABLE; } @@ -164,12 +362,12 @@ int wc_CAAM_EccSign(const byte* in, int inlen, byte* out, word32* outlen, /* convert signature from raw bytes to signature format */ { mp_int mpr, mps; - + mp_init(&mpr); mp_init(&mps); - - mp_read_unsigned_bin(&mpr, r, 32); - mp_read_unsigned_bin(&mps, s, 32); + + mp_read_unsigned_bin(&mpr, r, keySz); + mp_read_unsigned_bin(&mps, s, keySz); ret = StoreECC_DSA_Sig(out, outlen, &mpr, &mps); mp_free(&mpr); @@ -180,6 +378,7 @@ int wc_CAAM_EccSign(const byte* in, int inlen, byte* out, word32* outlen, } } + (void)devId; return MP_OKAY; } @@ -214,9 +413,9 @@ static int wc_CAAM_EccVerify_ex(mp_int* r, mp_int *s, const byte* hash, dp = wc_ecc_get_curve_params(key->idx); } - /* right now only support P256 @TODO */ - if (dp->id != ECC_SECP256R1) { - WOLFSSL_MSG("Only support P256 verify with CAAM for now"); + /* right now only support P256/P384 @TODO */ + if (dp->id != ECC_SECP256R1 && dp->id != ECC_SECP384R1) { + WOLFSSL_MSG("Only support P256 and P384 verify with CAAM for now"); return CRYPTOCB_UNAVAILABLE; } @@ -287,25 +486,34 @@ static int wc_CAAM_EccVerify_ex(mp_int* r, mp_int *s, const byte* hash, * returns MP_OKAY on success */ int wc_CAAM_EccVerify(const byte* sig, word32 siglen, const byte* hash, - word32 hashlen, int* res, ecc_key* key) + word32 hashlen, int* res, ecc_key* key, int devId) { int ret; mp_int r, s; ret = DecodeECC_DSA_Sig(sig, siglen, &r, &s); if (ret == 0) { - ret = wc_CAAM_EccVerify_ex(&r, &s, hash, hashlen, res, key); + #if defined(WOLFSSL_DEVCRYPTO_ECDSA) + if (devId == WOLFSSL_CAAM_DEVID) { + ret = wc_CAAM_DevEccVerify_ex(&r, &s, hash, hashlen, res, key); + } + else + #endif + { + ret = wc_CAAM_EccVerify_ex(&r, &s, hash, hashlen, res, key); + } mp_free(&r); mp_free(&s); } + (void)devId; return ret; } /* Does ECDH operation using CAAM and returns MP_OKAY on success */ int wc_CAAM_Ecdh(ecc_key* private_key, ecc_key* public_key, byte* out, - word32* outlen) + word32* outlen, int devId) { const ecc_set_type* dp; word32 args[4] = {0}; @@ -320,6 +528,12 @@ int wc_CAAM_Ecdh(ecc_key* private_key, ecc_key* public_key, byte* out, byte qxy[MAX_ECC_BYTES * 2] = {0}; word32 qxSz, qySz; +#if defined(WOLFSSL_DEVCRYPTO_ECDSA) + if (devId == WOLFSSL_CAAM_DEVID) { + return wc_CAAM_DevEcdh(private_key, public_key, out, outlen); + } +#endif + if (private_key->dp != NULL) { dp = private_key->dp; } @@ -388,6 +602,7 @@ int wc_CAAM_Ecdh(ecc_key* private_key, ecc_key* public_key, byte* out, args[2] = ecdsel; args[3] = keySz; ret = wc_caamAddAndWait(buf, idx, args, CAAM_ECDSA_ECDH); + (void)devId; if (ret == 0) { *outlen = keySz; return MP_OKAY; @@ -398,8 +613,10 @@ int wc_CAAM_Ecdh(ecc_key* private_key, ecc_key* public_key, byte* out, } +#ifdef WOLFSSL_KEY_GEN /* [ private black key ] [ x , y ] */ -int wc_CAAM_MakeEccKey(WC_RNG* rng, int keySize, ecc_key* key, int curveId) +int wc_CAAM_MakeEccKey(WC_RNG* rng, int keySize, ecc_key* key, int curveId, + int devId) { word32 args[4] = {0}; CAAM_BUFFER buf[2] = {0}; @@ -410,13 +627,18 @@ int wc_CAAM_MakeEccKey(WC_RNG* rng, int keySize, ecc_key* key, int curveId) byte s[MAX_ECC_BYTES] = {0}; byte xy[MAX_ECC_BYTES*2] = {0}; +#if defined(WOLFSSL_DEVCRYPTO_ECDSA) + if (devId == WOLFSSL_CAAM_DEVID) { + return wc_CAAM_DevMakeEccKey(rng, keySize, key, curveId); + } +#endif key->type = ECC_PRIVATEKEY; /* if set to default curve then assume SECP256R1 */ if (keySize == 32 && curveId == ECC_CURVE_DEF) curveId = ECC_SECP256R1; - if (curveId != ECC_SECP256R1) { - /* currently only implemented P256 support */ + if (curveId != ECC_SECP256R1 && curveId != ECC_SECP384R1) { + /* currently only implemented P256/P384 support */ return CRYPTOCB_UNAVAILABLE; } @@ -427,6 +649,7 @@ int wc_CAAM_MakeEccKey(WC_RNG* rng, int keySize, ecc_key* key, int curveId) } (void)rng; + (void)devId; buf[0].TheAddress = (CAAM_ADDRESS)s; buf[0].Length = keySize; @@ -437,10 +660,17 @@ int wc_CAAM_MakeEccKey(WC_RNG* rng, int keySize, ecc_key* key, int curveId) args[1] = ecdsel; ret = wc_caamAddAndWait(buf, 2, args, CAAM_ECDSA_KEYPAIR); - if (args[0] == 1 && ret == 0) { + if (args[0] == 1 && ret == 0) { key->blackKey = (word32)buf[0].TheAddress; + #if defined(WOLFSSL_SECO_CAAM) + if (wc_ecc_import_unsigned(key, xy, xy + keySize, NULL, curveId) != 0) { + WOLFSSL_MSG("issue importing public key"); + return -1; + } + #else key->securePubKey = (word32)buf[1].TheAddress; key->partNum = args[2]; + #endif return MP_OKAY; } if (args[0] == 0 && ret == 0) { @@ -453,6 +683,7 @@ int wc_CAAM_MakeEccKey(WC_RNG* rng, int keySize, ecc_key* key, int curveId) } return -1; } +#endif /* WOLFSSL_KEY_GEN */ /* if dealing with a black encrypted key then it can not be checked */ diff --git a/wolfcrypt/src/port/caam/wolfcaam_hash.c b/wolfcrypt/src/port/caam/wolfcaam_hash.c new file mode 100644 index 000000000..823881a68 --- /dev/null +++ b/wolfcrypt/src/port/caam/wolfcaam_hash.c @@ -0,0 +1,421 @@ +/* wolfcaam_hash.c + * + * Copyright (C) 2006-2021 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + +#ifdef HAVE_CONFIG_H + #include +#endif + +#include + +#if defined(WOLFSSL_CAAM) && defined(WOLFSSL_CAAM_HASH) + +#include +#include + +#if defined(__INTEGRITY) || defined(INTEGRITY) +#include +#endif +#include +#include + +#if defined(WOLFSSL_CAAM_DEBUG) || defined(WOLFSSL_CAAM_PRINT) +#include +#endif + +#ifndef NO_SHA +#include +#endif + +#if !defined(NO_SHA256) || defined(WOLFSSL_SHA224) +#include +#endif + +#if defined(WOLFSSL_SHA384) || defined(WOLFSSL_SHA512) +#include +#endif + +#ifndef NO_MD5 +#include +#endif + +#ifndef WC_CAAM_CTXLEN + #define WC_CAAM_CTXLEN 0 +#endif + +/****************************************************************************** + Common Code Between SHA Functions + ****************************************************************************/ + +#ifndef WOLFSSL_HASH_KEEP +static int _InitSha(byte* ctx, word32 ctxSz, void* heap, int devId, + word32 type) +{ + CAAM_BUFFER buf[1]; + word32 arg[4]; + int ret; + + /* Set buffer for context */ + buf[0].BufferType = DataBuffer | LastBuffer; + buf[0].TheAddress = (CAAM_ADDRESS)ctx; + buf[0].Length = ctxSz + WC_CAAM_CTXLEN; +#if defined(__INTEGRITY) || defined(INTEGRITY) + buf[0].Transferred = 0; +#endif + + arg[0] = CAAM_ALG_INIT; + arg[1] = ctxSz + WC_CAAM_CTXLEN; + arg[2] = (word32)devId; + + if ((ret = wc_caamAddAndWait(buf, arg, type)) != 0) { + WOLFSSL_MSG("Error with CAAM SHA init"); + return ret; + } + + return 0; +} + + +static int _ShaUpdate(wc_Sha* sha, const byte* data, word32 len, word32 digestSz, + word32 type) +{ + CAAM_BUFFER buf[2]; + word32 arg[4]; + int ret; + byte* local; + + if (sha == NULL ||(data == NULL && len > 0)) { + return BAD_FUNC_ARG; + } + + if (len == 0) return 0; /* nothing to do */ + + local = (byte*)sha->buffer; + /* check for filling out existing buffer */ + if (sha->buffLen > 0) { + word32 add = min(len, WC_CAAM_HASH_BLOCK - sha->buffLen); + XMEMCPY(&local[sha->buffLen], data, add); + + sha->buffLen += add; + data += add; + len -= add; + + if (sha->buffLen == WC_CAAM_HASH_BLOCK) { + /* Set buffer for context */ + buf[0].BufferType = DataBuffer; + buf[0].TheAddress = (CAAM_ADDRESS)sha->ctx; + buf[0].Length = digestSz + WC_CAAM_CTXLEN; + #if defined(__INTEGRITY) || defined(INTEGRITY) + buf[0].Transferred = 0; + #endif + + /* data to update with */ + buf[1].BufferType = DataBuffer | LastBuffer; + buf[1].TheAddress = (CAAM_ADDRESS)sha->buffer; + buf[1].Length = sha->buffLen; + #if defined(__INTEGRITY) || defined(INTEGRITY) + buf[1].Transferred = 0; + #endif + + arg[0] = CAAM_ALG_UPDATE; + arg[1] = digestSz + WC_CAAM_CTXLEN; + + if ((ret = wc_caamAddAndWait(buf, arg, type)) != 0) { + WOLFSSL_MSG("Error with CAAM SHA update"); + return ret; + } + sha->buffLen = 0; /* cleared out buffer */ + } + } + + /* check if multiple full blocks can be done */ + if (len >= WC_CAAM_HASH_BLOCK) { + word32 sz = len / WC_CAAM_HASH_BLOCK; + sz = sz * WC_CAAM_HASH_BLOCK; + + /* Set buffer for context */ + buf[0].BufferType = DataBuffer; + buf[0].TheAddress = (CAAM_ADDRESS)sha->ctx; + buf[0].Length = digestSz + WC_CAAM_CTXLEN; + #if defined(__INTEGRITY) || defined(INTEGRITY) + buf[0].Transferred = 0; + #endif + + /* data to update with */ + buf[1].BufferType = DataBuffer | LastBuffer; + buf[1].TheAddress = (CAAM_ADDRESS)data; + buf[1].Length = sz; + #if defined(__INTEGRITY) || defined(INTEGRITY) + buf[1].Transferred = 0; + #endif + + arg[0] = CAAM_ALG_UPDATE; + arg[1] = digestSz + WC_CAAM_CTXLEN; + + if ((ret = wc_caamAddAndWait(buf, arg, type)) != 0) { + WOLFSSL_MSG("Error with CAAM SHA update"); + return ret; + } + + len -= sz; + data += sz; + } + + /* check for left overs */ + if (len > 0) { + word32 add = min(len, WC_CAAM_HASH_BLOCK - sha->buffLen); + XMEMCPY(&local[sha->buffLen], data, add); + sha->buffLen += add; + } + + return 0; +} +#endif /* !WOLFSSL_HASH_KEEP */ + + +static int _ShaFinal(byte* ctx, word32 ctxSz, byte* in, word32 inSz, byte* out, + word32 type) +{ + CAAM_BUFFER buf[2]; + word32 arg[4]; + int ret; + + if (ctx == NULL || out == NULL) { + return BAD_FUNC_ARG; + } + + /* Set buffer for context */ + buf[0].BufferType = DataBuffer; + buf[0].TheAddress = (CAAM_ADDRESS)ctx; + buf[0].Length = ctxSz; +#if defined(__INTEGRITY) || defined(INTEGRITY) + buf[0].Transferred = 0; +#endif + + /* add any potential left overs */ + buf[1].BufferType = DataBuffer | LastBuffer; + buf[1].TheAddress = (CAAM_ADDRESS)in; + buf[1].Length = inSz; +#if defined(__INTEGRITY) || defined(INTEGRITY) + buf[1].Transferred = 0; +#endif + + arg[0] = CAAM_ALG_FINAL; + arg[1] = ctxSz + WC_CAAM_CTXLEN; + + if ((ret = wc_caamAddAndWait(buf, 2, arg, type)) != 0) { + WOLFSSL_MSG("Error with CAAM SHA Final"); + return ret; + } + XMEMCPY(out, ctx, ctxSz); + + return 0; +} + + +/****************************************************************************** + SHA 1 + ****************************************************************************/ +#if !defined(NO_SHA) +int wc_CAAM_ShaHash(wc_Sha* sha, const byte* in, word32 inSz, byte* digest) +{ + int ret = 0; + + /* in the case of update's just store up all data */ + if (in != NULL) { + #ifdef WOLFSSL_HASH_KEEP + ret = _wc_Sha_Grow(&(sha->msg), &(sha->used), &(sha->len), in, + inSz, sha->heap); + #else + ret = _ShaUpdate(sha, data, len, SHA_DIGEST_SIZE, CAAM_SHA); + #endif + } + + if (digest != NULL) { + #ifdef WOLFSSL_HASH_KEEP + int devId = sha->devId; + void* heap = sha->heap; + + ret = _ShaFinal((byte*)sha->digest, SHA_DIGEST_SIZE, sha->msg, + sha->used, digest, CAAM_SHA); + + wc_ShaFree(sha); + wc_InitSha_ex(sha, heap, devId); + #else + ret = _ShaFinal((byte*)sha->digest, SHA_DIGEST_SIZE, + sha->buffer, sha->bufferLen, digest, CAAM_SHA); + #endif + } + return ret; +} +#endif /* !NO_SHA */ + + +/****************************************************************************** + SHA 224 + ****************************************************************************/ +#ifdef WOLFSSL_SHA224 +int wc_CAAM_Sha224Hash(wc_Sha224* sha224, const byte* in, word32 inSz, + byte* digest) +{ + int ret = 0; + + /* in the case of update's just store up all data */ + if (in != NULL) { + #ifdef WOLFSSL_HASH_KEEP + ret = wc_Sha224_Grow(sha224, in, inSz); + #else + ret = _ShaUpdate(sha224, data, len, SHA224_DIGEST_SIZE, CAAM_SHA224); + #endif + } + + if (digest != NULL) { + #ifdef WOLFSSL_HASH_KEEP + int devId = sha224->devId; + void* heap = sha224->heap; + + ret = _ShaFinal((byte*)sha224->digest, SHA224_DIGEST_SIZE, sha224->msg, + sha224->used, digest, CAAM_SHA224); + wc_Sha224Free(sha224); + wc_InitSha224_ex(sha224, heap, devId); + #else + ret = _ShaFinal((byte*)sha224->digest, SHA224_DIGEST_SIZE, + sha224->buffer, sha224->bufferLen, digest, CAAM_SHA224); + #endif + } + return ret; +} +#endif /* WOLFSSL_SHA224 */ + + +/****************************************************************************** + SHA 256 + ****************************************************************************/ +#if !defined(NO_SHA256) +int wc_CAAM_Sha256Hash(wc_Sha256* sha256, const byte* in, word32 inSz, + byte* digest) +{ + int ret = 0; + + /* in the case of update's just store up all data */ + if (in != NULL) { + #ifdef WOLFSSL_HASH_KEEP + ret = wc_Sha256_Grow(sha256, in, inSz); + #else + ret = _ShaUpdate(sha256, data, len, SHA256_DIGEST_SIZE, CAAM_SHA256); + #endif + } + + if (digest != NULL) { + #ifdef WOLFSSL_HASH_KEEP + int devId = sha256->devId; + void* heap = sha256->heap; + + ret = _ShaFinal((byte*)sha256->digest, SHA256_DIGEST_SIZE, sha256->msg, + sha256->used, digest, CAAM_SHA256); + + wc_Sha256Free(sha256); + wc_InitSha256_ex(sha256, heap, devId); + #else + ret = _ShaFinal((byte*)sha256->digest, SHA256_DIGEST_SIZE, + sha256->buffer, sha256->bufferLen, digest, CAAM_SHA256); + #endif + } + return ret; +} +#endif /* !NO_SHA256 */ + + +/****************************************************************************** + SHA 384 + ****************************************************************************/ +#ifdef WOLFSSL_SHA384 +int wc_CAAM_Sha384Hash(wc_Sha384* sha384, const byte* in, word32 inSz, + byte* digest) +{ + int ret = 0; + + /* in the case of update's just store up all data */ + if (in != NULL) { + #ifdef WOLFSSL_HASH_KEEP + ret = wc_Sha384_Grow(sha384, in, inSz); + #else + ret = _ShaUpdate(sha384, data, len, SHA384_DIGEST_SIZE, CAAM_SHA384); + #endif + } + + if (digest != NULL) { + #ifdef WOLFSSL_HASH_KEEP + int devId = sha384->devId; + void* heap = sha384->heap; + + ret = _ShaFinal((byte*)sha384->digest, SHA384_DIGEST_SIZE, sha384->msg, + sha384->used, digest, CAAM_SHA384); + wc_Sha384Free(sha384); + wc_InitSha384_ex(sha384, heap, devId); + #else + ret = _ShaFinal((byte*)sha384->digest, SHA384_DIGEST_SIZE, + sha384->buffer, sha384->bufferLen, digest, CAAM_SHA384); + #endif + } + return ret; +} +#endif /* WOLFSSL_SHA384 */ + + + +/****************************************************************************** + SHA 512 + ****************************************************************************/ +#ifdef WOLFSSL_SHA512 +int wc_CAAM_Sha512Hash(wc_Sha512* sha512, const byte* in, word32 inSz, + byte* digest) +{ + int ret = 0; + + /* in the case of update's just store up all data */ + if (in != NULL) { + #ifdef WOLFSSL_HASH_KEEP + ret = wc_Sha512_Grow(sha512, in, inSz); + #else + ret = _ShaUpdate(sha512, data, len, SHA512_DIGEST_SIZE, CAAM_SHA512); + #endif + } + + if (digest != NULL) { + #ifdef WOLFSSL_HASH_KEEP + int devId = sha512->devId; + void* heap = sha512->heap; + + ret = _ShaFinal((byte*)sha512->digest, SHA512_DIGEST_SIZE, sha512->msg, + sha512->used, digest, CAAM_SHA512); + wc_Sha512Free(sha512); + wc_InitSha512_ex(sha512, heap, devId); + #else + ret = _ShaFinal((byte*)sha512->digest, SHA512_DIGEST_SIZE, + sha512->buffer, sha512->bufferLen, digest, CAAM_SHA512); + #endif + } + return ret; +} +#endif /* WOLFSSL_SHA512 */ + +#endif /* WOLFSSL_CAAM && WOLFSSL_CAAM_HASH */ + diff --git a/wolfcrypt/src/port/caam/wolfcaam_hmac.c b/wolfcrypt/src/port/caam/wolfcaam_hmac.c new file mode 100644 index 000000000..a45639dd0 --- /dev/null +++ b/wolfcrypt/src/port/caam/wolfcaam_hmac.c @@ -0,0 +1,100 @@ +/* wolfcaam_hmac.c + * + * Copyright (C) 2006-2021 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + +#ifdef HAVE_CONFIG_H + #include +#endif + +#include + +#if defined(WOLFSSL_CAAM) && !defined(NO_HMAC) && defined(WOLFSSL_CAAM_HMAC) + +#include +#include + +#ifdef NO_INLINE + #include +#else + #define WOLFSSL_MISC_INCLUDED + #include +#endif + +#include +#include +#include + +#if defined(WOLFSSL_CAAM_DEBUG) || defined(WOLFSSL_CAAM_PRINT) +#include +#endif + +#if defined(WOLFSSL_DEVCRYPTO_HMAC) +#include + +/* HSM lib does not support HMAC with QXP board, use devcrypto instead */ +int wc_CAAM_Hmac(Hmac* hmac, int macType, const byte* msg, int msgSz, + byte* digest) +{ + int ret = 0; + + if (hmac->ctx.cfd == -1 && hmac->keyLen > 0) { + ret = wc_DevCrypto_HmacSetKey(hmac, macType, hmac->keyRaw, + hmac->keyLen); + if (ret != 0) { + WOLFSSL_MSG("Error with set key"); + if (ret == HASH_TYPE_E) { + ret = CRYPTOCB_UNAVAILABLE; /* that hash type is not supported*/ + } + } + } + + if (ret == 0 && msgSz > 0) { + ret = wc_DevCrypto_HmacUpdate(hmac, msg, msgSz); + if (ret != 0) { + WOLFSSL_MSG("Issue with hmac update"); + } + } + + if (ret == 0 && digest != NULL) { + ret = wc_DevCrypto_HmacFinal(hmac, digest); + if (ret != 0) { + WOLFSSL_MSG("Issue with hmac final"); + } + else { + wc_DevCrypto_HmacFree(hmac); + } + } + return ret; +} +#else +int wc_CAAM_Hmac(Hmac* hmac, int macType, const byte* msg, int msgSz, + byte* digest) +{ + (void)hmac; + (void)macType; + (void)msg; + (void)msgSz; + (void)digest; + return CRYPTOCB_UNAVAILABLE; +} +#endif /* WOLFSSL_DEVCRYPTO_HMAC */ + +#endif + diff --git a/wolfcrypt/src/port/caam/wolfcaam_init.c b/wolfcrypt/src/port/caam/wolfcaam_init.c index 83257a3f8..4661f91bd 100644 --- a/wolfcrypt/src/port/caam/wolfcaam_init.c +++ b/wolfcrypt/src/port/caam/wolfcaam_init.c @@ -25,7 +25,8 @@ #include #if defined(WOLFSSL_IMX6_CAAM) || defined(WOLFSSL_IMX6_CAAM_RNG) || \ - defined(WOLFSSL_IMX6UL_CAAM) || defined(WOLFSSL_IMX6_CAAM_BLOB) + defined(WOLFSSL_IMX6UL_CAAM) || defined(WOLFSSL_IMX6_CAAM_BLOB) || \ + defined(WOLFSSL_SECO_CAAM) #include #include @@ -69,66 +70,265 @@ static int wc_CAAM_router(int devId, wc_CryptoInfo* info, void* ctx) int ret = CRYPTOCB_UNAVAILABLE; (void)ctx; - (void)devId; switch (info->algo_type) { case WC_ALGO_TYPE_PK: switch (info->pk.type) { + #if defined(HAVE_ECC) && defined(WOLFSSL_CAAM_ECC) case WC_PK_TYPE_ECDSA_SIGN: ret = wc_CAAM_EccSign(info->pk.eccsign.in, info->pk.eccsign.inlen, info->pk.eccsign.out, info->pk.eccsign.outlen, info->pk.eccsign.rng, - info->pk.eccsign.key); + info->pk.eccsign.key, devId); break; case WC_PK_TYPE_ECDSA_VERIFY: ret = wc_CAAM_EccVerify(info->pk.eccverify.sig, info->pk.eccverify.siglen, info->pk.eccverify.hash, info->pk.eccverify.hashlen, info->pk.eccverify.res, - info->pk.eccverify.key); + info->pk.eccverify.key, devId); break; + #ifdef WOLFSSL_KEY_GEN case WC_PK_TYPE_EC_KEYGEN: ret = wc_CAAM_MakeEccKey(info->pk.eckg.rng, info->pk.eckg.size, info->pk.eckg.key, - info->pk.eckg.curveId); + info->pk.eckg.curveId, devId); break; + #endif /* WOLFSSL_KEY_GEN */ case WC_PK_TYPE_ECDH: ret = wc_CAAM_Ecdh(info->pk.ecdh.private_key, - info->pk.ecdh.public_key, info->pk.ecdh.out, - info->pk.ecdh.outlen); + info->pk.ecdh.public_key, + info->pk.ecdh.out, + info->pk.ecdh.outlen, devId); break; case WC_PK_TYPE_EC_CHECK_PRIV_KEY: ret = wc_CAAM_EccCheckPrivKey(info->pk.ecc_check.key, - info->pk.ecc_check.pubKey, - info->pk.ecc_check.pubKeySz); - break; + info->pk.ecc_check.pubKey, + info->pk.ecc_check.pubKeySz); + break; + #endif /* HAVE_ECC && WOLFSSL_CAAM_ECC */ + #if !defined(NO_RSA) && defined(WOLFSSL_DEVCRYPTO_RSA) + case WC_PK_TYPE_RSA: + ret = wc_CAAM_Rsa(info->pk.rsa.in, + info->pk.rsa.inLen, + info->pk.rsa.out, + info->pk.rsa.outLen, + info->pk.rsa.type, + info->pk.rsa.key, + info->pk.rsa.rng); + break; + #ifdef WOLFSSL_KEY_GEN + case WC_PK_TYPE_RSA_KEYGEN: + ret = wc_CAAM_MakeRsaKey(info->pk.rsakg.key, + info->pk.rsakg.size, + info->pk.rsakg.e, + info->pk.rsakg.rng); + break; + #endif + #endif /* !NO_RSA */ + #if defined(HAVE_CURVE25519) && defined(WOLFSSL_CAAM_CURVE25519) + case WC_PK_TYPE_CURVE25519_KEYGEN: + ret = wc_CAAM_MakeCurve25519Key(info->pk.curve25519kg.key, + info->pk.curve25519kg.size, + info->pk.curve25519kg.rng); + break; + + case WC_PK_TYPE_CURVE25519: + ret = wc_CAAM_Curve25519(info->pk.curve25519.out, + info->pk.curve25519.outlen, + info->pk.curve25519.private_key, + info->pk.curve25519.public_key, + info->pk.curve25519.endian); + break; + #endif /* HAVE_CURVE25519 && WOLFSSL_CAAM_CURVE25519 */ default: WOLFSSL_MSG("unsupported public key operation"); } break; case WC_ALGO_TYPE_CMAC: + #ifdef WOLFSSL_CAAM_CMAC + #ifdef WOLFSSL_SECO_CAAM + if (devId != WOLFSSL_SECO_DEVID) + break; + #endif #if defined(WOLFSSL_CMAC) && !defined(NO_AES) && \ defined(WOLFSSL_AES_DIRECT) - ret = wc_CAAM_Cmac(info->cmac.cmac, info->cmac.key, - info->cmac.keySz, info->cmac.in, info->cmac.inSz, - info->cmac.out, info->cmac.outSz, info->cmac.type, - info->cmac.ctx); + ret = wc_CAAM_Cmac(info->cmac.cmac, + info->cmac.key, + info->cmac.keySz, + info->cmac.in, + info->cmac.inSz, + info->cmac.out, + info->cmac.outSz, + info->cmac.type, + info->cmac.ctx); #else WOLFSSL_MSG("CMAC not compiled in"); ret = NOT_COMPILED_IN; #endif + #endif /* WOLFSSL_CAAM_CMAC */ break; - case WC_ALGO_TYPE_NONE: case WC_ALGO_TYPE_HASH: + #ifdef WOLFSSL_CAAM_HASH + #ifdef WOLFSSL_SECO_CAAM + switch(info->hash.type) { + #ifdef WOLFSSL_SHA224 + case WC_HASH_TYPE_SHA224: + ret = wc_CAAM_Sha224Hash(info->hash.sha224, + info->hash.in, + info->hash.inSz, + info->hash.digest); + break; + #endif + + case WC_HASH_TYPE_SHA256: + ret = wc_CAAM_Sha256Hash(info->hash.sha256, + info->hash.in, + info->hash.inSz, + info->hash.digest); + break; + + case WC_HASH_TYPE_SHA384: + ret = wc_CAAM_Sha384Hash(info->hash.sha384, + info->hash.in, + info->hash.inSz, + info->hash.digest); + break; + + case WC_HASH_TYPE_SHA512: + ret = wc_CAAM_Sha512Hash(info->hash.sha512, + info->hash.in, + info->hash.inSz, + info->hash.digest); + break; + + default: + WOLFSSL_MSG("Unknown or unsupported hash type"); + ret = CRYPTOCB_UNAVAILABLE; + } + #endif + #endif /* WOLFSSL_CAAM_HASH */ + break; + + case WC_ALGO_TYPE_HMAC: + #if defined(WOLFSSL_CAAM_HMAC) + ret = wc_CAAM_Hmac(info->hmac.hmac, + info->hmac.macType, + info->hmac.in, info->hmac.inSz, + info->hmac.digest); + #endif + break; + case WC_ALGO_TYPE_CIPHER: + #ifdef WOLFSSL_CAAM_CIPHER + #ifdef WOLFSSL_SECO_CAAM + if (devId != WOLFSSL_SECO_DEVID) + break; /* only call to SECO if using WOLFSSL_SECO_DEVID */ + #endif + switch (info->cipher.type) { + #if defined(HAVE_AESCCM) + case WC_CIPHER_AES_CCM: + if (info->cipher.enc == 1) { + ret = wc_CAAM_AesCcmEncrypt( + info->cipher.aesccm_enc.aes, + info->cipher.aesccm_enc.in, + info->cipher.aesccm_enc.out, + info->cipher.aesccm_enc.sz, + info->cipher.aesccm_enc.nonce, + info->cipher.aesccm_enc.nonceSz, + info->cipher.aesccm_enc.authTag, + info->cipher.aesccm_enc.authTagSz, + info->cipher.aesccm_enc.authIn, + info->cipher.aesccm_enc.authInSz); + } + else { + ret = wc_CAAM_AesCcmDecrypt( + info->cipher.aesccm_dec.aes, + info->cipher.aesccm_dec.in, + info->cipher.aesccm_dec.out, + info->cipher.aesccm_dec.sz, + info->cipher.aesccm_dec.nonce, + info->cipher.aesccm_dec.nonceSz, + info->cipher.aesccm_dec.authTag, + info->cipher.aesccm_dec.authTagSz, + info->cipher.aesccm_dec.authIn, + info->cipher.aesccm_dec.authInSz); + } + break; + #endif /* HAVE_AESCCM */ + #if defined(HAVE_AESGCM) + case WC_CIPHER_AES_GCM: + if (info->cipher.enc == 1) { + ret = wc_CAAM_AesGcmEncrypt( + info->cipher.aesgcm_enc.aes, + info->cipher.aesgcm_enc.in, + info->cipher.aesgcm_enc.out, + info->cipher.aesgcm_enc.sz, + info->cipher.aesgcm_enc.iv, + info->cipher.aesgcm_enc.ivSz, + info->cipher.aesgcm_enc.authTag, + info->cipher.aesgcm_enc.authTagSz, + info->cipher.aesgcm_enc.authIn, + info->cipher.aesgcm_enc.authInSz); + } + else { + ret = wc_CAAM_AesGcmDecrypt( + info->cipher.aesgcm_dec.aes, + info->cipher.aesgcm_dec.in, + info->cipher.aesgcm_dec.out, + info->cipher.aesgcm_dec.sz, + info->cipher.aesgcm_dec.iv, + info->cipher.aesgcm_dec.ivSz, + info->cipher.aesgcm_dec.authTag, + info->cipher.aesgcm_dec.authTagSz, + info->cipher.aesgcm_dec.authIn, + info->cipher.aesgcm_dec.authInSz); + } + break; + #endif /* HAVE_AESGCM */ + + case WC_CIPHER_AES_CBC: + if (info->cipher.enc == 1) { + ret = wc_CAAM_AesCbcEncrypt(info->cipher.aescbc.aes, + info->cipher.aescbc.out, + info->cipher.aescbc.in, + info->cipher.aescbc.sz); + } + else { + ret = wc_CAAM_AesCbcDecrypt(info->cipher.aescbc.aes, + info->cipher.aescbc.out, + info->cipher.aescbc.in, + info->cipher.aescbc.sz); + } + break; + + #if defined(HAVE_AES_ECB) + case WC_CIPHER_AES_ECB: + if (info->cipher.enc == 1) { + ret = wc_CAAM_AesEcbEncrypt(info->cipher.aesecb.aes, + info->cipher.aesecb.out, + info->cipher.aesecb.in, + info->cipher.aesecb.sz); + } + else { + ret = wc_CAAM_AesEcbDecrypt(info->cipher.aesecb.aes, + info->cipher.aesecb.out, + info->cipher.aesecb.in, + info->cipher.aesecb.sz); + } + #endif /* HAVE_AES_ECB */ + } + #endif /* WOLFSSL_CAAM_CIPHER */ + break; + case WC_ALGO_TYPE_RNG: case WC_ALGO_TYPE_SEED: - case WC_ALGO_TYPE_HMAC: + case WC_ALGO_TYPE_NONE: default: /* Not implemented yet with CAAM */ ret = CRYPTOCB_UNAVAILABLE; @@ -144,6 +344,7 @@ static int wc_CAAM_router(int devId, wc_CryptoInfo* info, void* ctx) */ int wc_caamInit(void) { + int ret = 0; WOLFSSL_MSG("Starting interface with CAAM driver"); if (CAAM_INIT_INTERFACE() != 0) { WOLFSSL_MSG("Error initializing CAAM"); @@ -194,8 +395,15 @@ int wc_caamInit(void) #endif #endif - return wc_CryptoDev_RegisterDevice(WOLFSSL_CAAM_DEVID, wc_CAAM_router, +#ifdef WOLFSSL_SECO_CAAM + ret = wc_CryptoDev_RegisterDevice(WOLFSSL_SECO_DEVID, wc_CAAM_router, NULL); +#endif + if (ret == 0) { + ret = wc_CryptoDev_RegisterDevice(WOLFSSL_CAAM_DEVID, wc_CAAM_router, + NULL); + } + return ret; } @@ -207,7 +415,7 @@ int wc_caamFree(void) } -#ifndef WOLFSSL_QNX_CAAM +#if defined(__INTEGRITY) || defined(INTEGRITY) word32 wc_caamReadRegister(word32 reg) { word32 out = 0; @@ -251,7 +459,7 @@ int wc_caamAddAndWait(CAAM_BUFFER* buf, int sz, word32 arg[4], word32 type) static int wait = 0; #endif -#ifndef WOLFSSL_QNX_CAAM +#if defined(__INTEGRITY) || defined(INTEGRITY) if (caam == NULLIODevice) { WOLFSSL_MSG("Error CAAM IODevice not found! Bad password?"); return WC_HW_E; diff --git a/wolfcrypt/src/port/caam/wolfcaam_rsa.c b/wolfcrypt/src/port/caam/wolfcaam_rsa.c new file mode 100644 index 000000000..339cd295c --- /dev/null +++ b/wolfcrypt/src/port/caam/wolfcaam_rsa.c @@ -0,0 +1,106 @@ +/* wolfcaam_rsa.c + * + * Copyright (C) 2006-2021 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + +#ifdef HAVE_CONFIG_H + #include +#endif + +#include + +#if defined(WOLFSSL_CAAM) && !defined(NO_RSA) + +#include +#include + +#ifdef NO_INLINE + #include +#else + #define WOLFSSL_MISC_INCLUDED + #include +#endif + +#include +#include + +#if defined(WOLFSSL_CAAM_DEBUG) || defined(WOLFSSL_CAAM_PRINT) +#include +#endif + +#if defined(WOLFSSL_DEVCRYPTO_RSA) +#include + +/* HSM lib does not support RSA with QXP board, use devcrypto instead */ +int wc_CAAM_Rsa(const byte* in, word32 inLen, byte* out, word32* outLen, + int type, RsaKey* key, WC_RNG* rng) +{ + int ret = -1; + + switch (type) { + case RSA_PUBLIC_ENCRYPT: + case RSA_PRIVATE_ENCRYPT: + ret = wc_DevCrypto_RsaEncrypt(in, inLen, out, outLen, key, type); + break; + + case RSA_PUBLIC_DECRYPT: + case RSA_PRIVATE_DECRYPT: + ret = wc_DevCrypto_RsaDecrypt(in, inLen, out, *outLen, key, type); + } + (void)rng; + + return ret; +} + +#ifdef WOLFSSL_KEY_GEN +int wc_CAAM_MakeRsaKey(RsaKey* key, int size, long e, WC_RNG* rng) +{ + return wc_DevCrypto_MakeRsaKey(key, size, e, rng); +} +#endif + +#else +int wc_CAAM_Rsa(const byte* in, word32 inLen, byte* out, word32* outLen, + int type, RsaKey* key, WC_RNG* rng) +{ + (void)in; + (void)inLen; + (void)out; + (void)outLen; + (void)type; + (void)key; + (void)rng; + return CRYPTOCB_UNAVAILABLE; +} + +#ifdef WOLFSSL_KEY_GEN +int wc_CAAM_MakeRsaKey(RsaKey* key, int size, long e, WC_RNG* rng) +{ + (void)size; + (void)e; + (void)key; + (void)rng; + return CRYPTOCB_UNAVAILABLE; +} +#endif +#endif /* WOLFSSL_DEVCRYPTO_RSA */ + +#endif + + diff --git a/wolfcrypt/src/port/caam/wolfcaam_seco.c b/wolfcrypt/src/port/caam/wolfcaam_seco.c new file mode 100644 index 000000000..63d7003ee --- /dev/null +++ b/wolfcrypt/src/port/caam/wolfcaam_seco.c @@ -0,0 +1,1406 @@ +/* wolfcaam_seco.c + * + * Copyright (C) 2006-2021 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + +#ifdef HAVE_CONFIG_H + #include +#endif + +#include + +#if defined(WOLFSSL_SECO_CAAM) + +#include +#include + +#include +#include +#include + +#include +#include + +#define MAX_SECO_TIMEOUT 1000 + +wolfSSL_Mutex caamMutex; +static pthread_t tid; +static uint32_t nvm_status = 0; +static hsm_hdl_t hsm_session; +static hsm_hdl_t key_store_hdl; +static int wc_TranslateHSMError(int current, hsm_err_t err); + +static void* hsm_storage_init(void* args) +{ + seco_nvm_manager(NVM_FLAGS_HSM, &nvm_status); + (void)args; + return NULL; +} + + +/* return 0 on success */ +int wc_SECOInitInterface() +{ + int i; + open_session_args_t session_args; + hsm_err_t err; + + nvm_status = NVM_STATUS_UNDEF; + if (wc_InitMutex(&caamMutex) != 0) { + WOLFSSL_MSG("Could not init mutex"); + return -1; + } + + (void)pthread_create(&tid, NULL, hsm_storage_init, NULL); + + /* wait for NVM to be ready for SECO */ + for (i = 0 ; i < MAX_SECO_TIMEOUT && nvm_status <= NVM_STATUS_STARTING; + i++) { + usleep(1000); + } + if (i == MAX_SECO_TIMEOUT) { + WOLFSSL_MSG("Timed out waiting for SECO setup"); + return -1; + } + + if (nvm_status == NVM_STATUS_STOPPED) { + WOLFSSL_MSG("Error with SECO setup"); + return -1; + } + + session_args.session_priority = 0; + session_args.operating_mode = 0; + + err = hsm_open_session(&session_args, &hsm_session); + if (err != HSM_NO_ERROR) { + WOLFSSL_MSG("Error with HSM session open"); + return -1; + } + WOLFSSL_MSG("SECO HSM setup done"); + + return 0; +} + + +void wc_SECOFreeInterface() +{ + hsm_err_t err; + + err = hsm_close_session(hsm_session); + if (err != HSM_NO_ERROR) { + WOLFSSL_MSG("Error with HSM session close"); + } + + + if (nvm_status != NVM_STATUS_STOPPED) { + if (pthread_cancel(tid) != 0) { + WOLFSSL_MSG("SECO HSM thread shutdown failed"); + } + } + + seco_nvm_close_session(); + WOLFSSL_MSG("SECO HSM shutdown"); + + wc_FreeMutex(&caamMutex); +} + +/* open the key management HSM handle + * return 0 on success + */ +int wc_SECO_OpenHSM(word32 keyStoreId, word32 nonce, word16 maxUpdates, + byte flag) +{ + hsm_err_t err; + open_svc_key_store_args_t key_store_args; + + XMEMSET(&key_store_args, 0, sizeof(open_svc_key_store_args_t)); + key_store_args.key_store_identifier = keyStoreId, + key_store_args.authentication_nonce = nonce; + key_store_args.max_updates_number = maxUpdates; + switch (flag) { + case CAAM_KEYSTORE_CREATE: + key_store_args.flags = HSM_SVC_KEY_STORE_FLAGS_CREATE; + break; + case CAAM_KEYSTORE_UPDATE: + #ifdef HSM_SVC_KEY_STORE_FLAGS_UPDATE + key_store_args.flags = HSM_SVC_KEY_STORE_FLAGS_UPDATE; + #else + key_store_args.flags = 0; + #endif + break; + default: + WOLFSSL_MSG("Unknown flag"); + return -1; + } + + err = hsm_open_key_store_service(hsm_session, &key_store_args, + &key_store_hdl); + if (wc_TranslateHSMError(0, err) != Success) { + return -1; + } + else { + return 0; + } +} + + +/* close the key management HSM handle + * return 0 on success + */ +int wc_SECO_CloseHSM() +{ + hsm_err_t err = hsm_close_key_store_service(key_store_hdl); + if (wc_TranslateHSMError(0, err) != Success) { + return -1; + } + else { + return 0; + } +} + + +/* returns error enum found from hsm calls, HSM_NO_ERROR on success */ +static hsm_err_t wc_SECO_RNG(unsigned int args[4], CAAM_BUFFER *buf, int sz) +{ + hsm_hdl_t rng; + hsm_err_t err; + open_svc_rng_args_t svcArgs = {0}; + op_get_random_args_t rngArgs = {0}; + + err = hsm_open_rng_service(hsm_session, &svcArgs, &rng); + + if (err == HSM_NO_ERROR) { + rngArgs.output = (uint8_t*)buf[0].TheAddress; + rngArgs.random_size = (uint32_t)buf[0].Length; + err = hsm_get_random(rng, &rngArgs); + #ifdef DEBUG_SECO + { + uint32_t z; + printf("Pulled rng data from HSM :"); + for (z = 0; z < rngArgs.random_size; z++) + printf("%02X", rngArgs.output[z]); + printf("\n"); + } + #endif + } + + if (err == HSM_NO_ERROR) { + err = hsm_close_rng_service(rng); + } + + (void)args; + (void)sz; + return err; +} + + +static hsm_err_t wc_SECO_Hash(unsigned args[4], CAAM_BUFFER *buf, int sz, + int type) +{ + hsm_hdl_t hash; + hsm_err_t err = HSM_NO_ERROR; + op_hash_one_go_args_t hashArgs = {0}; + open_svc_hash_args_t sessionArgs = {0}; + + if (args[0] != CAAM_ALG_FINAL) { + WOLFSSL_MSG("Only expecting to call the HSM on final"); + err = HSM_GENERAL_ERROR; + } + + if (err == HSM_NO_ERROR) { + err = hsm_open_hash_service(hsm_session, &sessionArgs, &hash); + } + + if (err == HSM_NO_ERROR) { + switch (type) { + case CAAM_SHA224: + hashArgs.algo = HSM_HASH_ALGO_SHA_224; + break; + + case CAAM_SHA256: + hashArgs.algo = HSM_HASH_ALGO_SHA_256; + break; + + case CAAM_SHA384: + hashArgs.algo = HSM_HASH_ALGO_SHA_384; + break; + + case CAAM_SHA512: + hashArgs.algo = HSM_HASH_ALGO_SHA_512; + break; + } + + hashArgs.output = (uint8_t*)buf[0].TheAddress; + hashArgs.output_size = buf[0].Length; + hashArgs.input = (uint8_t*)buf[1].TheAddress; + hashArgs.input_size = buf[1].Length; + + err = hsm_hash_one_go(hash, &hashArgs); + if (err != HSM_NO_ERROR) { + WOLFSSL_MSG("Error with HSM hash call"); + } + + #ifdef DEBUG_SECO + { + word32 z; + printf("hash algo type = %d\n", hashArgs.algo); + printf("\tlength of input data = %d\n", hashArgs.input_size); + printf("\toutput : "); + for (z = 0; z < hashArgs.output_size; z++) + printf("%02X", hashArgs.output[z]); + printf("\n"); + } + #endif + + /* always try to close the hash handle */ + if (hsm_close_hash_service(hash) != HSM_NO_ERROR) { + WOLFSSL_MSG("Error with HSM hash close"); + if (err == HSM_NO_ERROR) { + err = HSM_GENERAL_ERROR; + } + } + } + (void)sz; + return err; +} + + +/* convert ECDSEL type to HSM type + * return 0 on fail + */ +static hsm_key_type_t ECDSELtoHSM(int ecdsel) +{ + switch (ecdsel) { + case CAAM_ECDSA_P192: + case CAAM_ECDSA_P224: + WOLFSSL_MSG("P192 and P224 are not supported"); + break; + + case CAAM_ECDSA_P256: + return CAAM_KEYTYPE_ECDSA_P256; + + case CAAM_ECDSA_P384: + return CAAM_KEYTYPE_ECDSA_P384; + + case CAAM_ECDSA_P521: + return CAAM_KEYTYPE_ECDSA_P521; + } + return 0; +} + + +static hsm_key_type_t KeyTypeToHSM(int keyTypeIn) +{ + hsm_key_type_t ret = 0; + switch (keyTypeIn) { + case CAAM_KEYTYPE_ECDSA_P256: + ret = HSM_KEY_TYPE_ECDSA_NIST_P256; + break; + + case CAAM_KEYTYPE_ECDSA_P384: + ret = HSM_KEY_TYPE_ECDSA_NIST_P384; + break; + + case CAAM_KEYTYPE_ECDSA_P521: + ret = HSM_KEY_TYPE_ECDSA_NIST_P521; + break; + + case CAAM_KEYTYPE_AES128: + ret = HSM_KEY_TYPE_AES_128; + break; + + case CAAM_KEYTYPE_AES192: + ret = HSM_KEY_TYPE_AES_192; + break; + + case CAAM_KEYTYPE_AES256: + ret = HSM_KEY_TYPE_AES_256; + break; + + #ifdef HSM_KEY_TYPE_HMAC_224 + case CAAM_KEYTYPE_HMAC224: + ret = HSM_KEY_TYPE_HMAC_224; + break; + #endif + + #ifdef HSM_KEY_TYPE_HMAC_256 + case CAAM_KEYTYPE_HMAC256: + ret = HSM_KEY_TYPE_HMAC_256; + break; + #endif + + #ifdef HSM_KEY_TYPE_HMAC_384 + case CAAM_KEYTYPE_HMAC384: + ret = HSM_KEY_TYPE_HMAC_384; + break; + #endif + + #ifdef HSM_KEY_TYPE_HMAC_512 + case CAAM_KEYTYPE_HMAC512: + ret = HSM_KEY_TYPE_HMAC_512; + break; + #endif + } + return ret; +} + + +static hsm_key_info_t KeyInfoToHSM(int keyInfoIn) +{ + hsm_key_info_t ret = 0; + + switch (keyInfoIn) { + case CAAM_KEY_PERSISTENT: + ret = HSM_KEY_INFO_PERSISTENT; + break; + + case CAAM_KEY_TRANSIENT: + ret = HSM_KEY_INFO_TRANSIENT; + break; + + case CAAM_KEY_KEK: + ret = HSM_KEY_INFO_KEK; + break; + } + return ret; +} + + +static int KeyFlagsToHSM(int flags) +{ + int ret = 0; + + #ifdef HSM_OP_KEY_GENERATION_FLAGS_UPDATE + if (flags & CAAM_UPDATE_KEY) { + ret = HSM_OP_KEY_GENERATION_FLAGS_UPDATE; + } + #endif + + #ifdef HSM_OP_KEY_GENERATION_FLAGS_CREATE + if (flags & CAAM_GENERATE_KEY) { + ret = HSM_OP_KEY_GENERATION_FLAGS_CREATE; + } + #endif + return ret; +} + + +/* generic generate key with HSM + * return 0 on success + */ +int wc_SECO_GenerateKey(int flags, int group, byte* out, int outSz, + int keyTypeIn, int keyInfoIn, unsigned int* keyIdOut) +{ + hsm_err_t err; + hsm_hdl_t key_mgmt_hdl; + open_svc_key_management_args_t key_mgmt_args; + op_generate_key_args_t key_args; + hsm_key_type_t keyType; + hsm_key_info_t keyInfo; + + if (flags == CAAM_UPDATE_KEY && group != 0) { + WOLFSSL_MSG("Group must be 0 if updating key"); + return BAD_FUNC_ARG; + } + + keyType = KeyTypeToHSM(keyTypeIn); + keyInfo = KeyInfoToHSM(keyInfoIn); + + if (wc_LockMutex(&caamMutex) != 0) { + return BAD_MUTEX_E; + } + + XMEMSET(&key_mgmt_args, 0, sizeof(key_mgmt_args)); + err = hsm_open_key_management_service( + key_store_hdl, &key_mgmt_args, &key_mgmt_hdl); + + /* setup key arguments */ + if (err == HSM_NO_ERROR) { + XMEMSET(&key_args, 0, sizeof(key_args)); + + key_args.key_identifier = keyIdOut; + key_args.out_size = outSz; + key_args.out_key = out; + + /* default to strict operations with key in NVM */ + key_args.flags = KeyFlagsToHSM(flags) | + HSM_OP_KEY_GENERATION_FLAGS_STRICT_OPERATION; + key_args.key_group = group; + key_args.key_info = keyInfo; + key_args.key_type = keyType; + #ifdef DEBUG_SECO + printf("Generating key using:\n"); + printf("\tflags = %d\n", key_args.flags); + printf("\tgroup = %d\n", key_args.key_group); + printf("\tinfo = %d\n", key_args.key_info); + printf("\ttype = %d\n", key_args.key_type); + printf("\tout = %p\n", key_args.out_key); + printf("\toutSZ = %d\n", key_args.out_size); + #endif + err = hsm_generate_key(key_mgmt_hdl, &key_args); + if (err != HSM_NO_ERROR) { + WOLFSSL_MSG("Key generation error"); + } + #ifdef DEBUG_SECO + if (err == HSM_NO_ERROR) { + printf("KeyID generated = %u\n", *key_args.key_identifier); + } + #endif + + /* always try to close key management if open */ + if (hsm_close_key_management_service(key_mgmt_hdl) != HSM_NO_ERROR) { + err = HSM_GENERAL_ERROR; + } + } + else { + WOLFSSL_MSG("Could not open key management"); + } + + wc_UnLockMutex(&caamMutex); + + if (wc_TranslateHSMError(0, err) == Success) { + return 0; + } + else { + return -1; + } +} + + +/* delete a key + * return 0 on success + */ +int wc_SECO_DeleteKey(unsigned int keyId, int group, int keyTypeIn) +{ + hsm_hdl_t key_mgmt_hdl; + open_svc_key_management_args_t key_mgmt_args; + op_manage_key_args_t del_args; + hsm_err_t err; + + XMEMSET(&key_mgmt_args, 0, sizeof(key_mgmt_args)); + err = hsm_open_key_management_service( + key_store_hdl, &key_mgmt_args, &key_mgmt_hdl); + + if (err == HSM_NO_ERROR) { + XMEMSET(&del_args, 0, sizeof(del_args)); + del_args.key_identifier = &keyId; + del_args.flags = HSM_OP_MANAGE_KEY_FLAGS_DELETE; + del_args.key_type = KeyTypeToHSM(keyTypeIn); + del_args.key_group = group; + #ifdef DEBUG_SECO + printf("Trying to delete key:\n"); + printf("\tkeyID : %u\n", keyId); + printf("\tkey type : %d\n", del_args.key_type); + printf("\tkey grp : %d\n", del_args.key_group); + #endif + err = hsm_manage_key(key_mgmt_hdl, &del_args); + + /* always try to close key management if open */ + if (hsm_close_key_management_service(key_mgmt_hdl) != HSM_NO_ERROR) { + err = HSM_GENERAL_ERROR; + } + } + + if (wc_TranslateHSMError(0, err) == Success) { + return 0; + } + else { + return -1; + } +} + + +#if defined(WOLFSSL_CMAC) +void wc_SECO_CMACSetKeyID(Cmac* cmac, int keyId) +{ + cmac->blackKey = keyId; +} + + +int wc_SECO_CMACGetKeyID(Cmac* cmac) +{ + return cmac->blackKey; +} +#endif + +void wc_SECO_AesSetKeyID(Aes* aes, int keyId) +{ + aes->blackKey = keyId; +} + + +int wc_SECO_AesGetKeyID(Aes* aes) +{ + return aes->blackKey; +} + + +/* return 0 on success and fill in out buffer (must be 32 bytes) */ +int wc_SECO_ExportKEK(byte* out, byte outSz, byte isCommon) +{ + hsm_err_t err; + op_export_root_kek_args_t export_args; + + XMEMSET(&export_args, 0, sizeof(export_args)); + + export_args.signed_message = NULL; + export_args.signed_msg_size = 0; + + if (isCommon == 1) { + export_args.flags = HSM_OP_EXPORT_ROOT_KEK_FLAGS_COMMON_KEK; + } + else { + export_args.flags = HSM_OP_EXPORT_ROOT_KEK_FLAGS_UNIQUE_KEK; + } + export_args.out_root_kek = out; + export_args.root_kek_size = outSz; + + err = hsm_export_root_key_encryption_key (hsm_session, &export_args); + if (wc_TranslateHSMError(0, err) != Success) { + return -1; + } + else { + return 0; + } +} + + +/* make a black key using HSM */ +static hsm_err_t wc_SECO_ECDSA_Make(unsigned int args[4], CAAM_BUFFER *buf, + int sz) +{ + hsm_key_type_t keyType; + + (void)sz; + keyType = ECDSELtoHSM(args[1] ^ CAAM_ECDSA_KEYGEN_PD); + if (wc_SECO_GenerateKey(HSM_OP_KEY_GENERATION_FLAGS_CREATE, + 1, + (byte*)buf[1].TheAddress, + buf[1].Length, + keyType, + CAAM_KEY_TRANSIENT, + (word32*)&buf[0].TheAddress) == 0) { + return HSM_NO_ERROR; + } + else { + return HSM_GENERAL_ERROR; + } +} + + +/* sign a message (hash(msg)) using a hsm key */ +static hsm_err_t wc_SECO_ECDSA_Sign(unsigned int args[4], CAAM_BUFFER *buf, + int sz) +{ + hsm_err_t err; + hsm_hdl_t sig_gen_hdl; + open_svc_sign_gen_args_t open_args; + op_generate_sign_args_t sig_args; + byte sigOut[2*MAX_ECC_BYTES]; + + if (args[3] != 32 && args[3] != 48) { + WOLFSSL_MSG("Unexpected key size"); + return BAD_FUNC_ARG; + } + + if (buf[1].Length != (int)args[3]) { + WOLFSSL_MSG("Bad message input size"); + return BAD_FUNC_ARG; + } + + if (wc_LockMutex(&caamMutex) != 0) { + return BAD_MUTEX_E; + } + + XMEMSET(&open_args, 0, sizeof(open_args)); + err = hsm_open_signature_generation_service(key_store_hdl, &open_args, + &sig_gen_hdl); + if (err == HSM_NO_ERROR) { + XMEMSET(&sig_args, 0, sizeof(sig_args)); + sig_args.key_identifier = buf[0].TheAddress; + sig_args.message = (uint8_t*)buf[1].TheAddress; + sig_args.message_size = buf[1].Length; + sig_args.signature = sigOut; + sig_args.signature_size = buf[2].Length + buf[3].Length + 1; + + if (args[3] == 32) { + sig_args.scheme_id = HSM_SIGNATURE_SCHEME_ECDSA_NIST_P256_SHA_256; + } + else { + sig_args.scheme_id = HSM_SIGNATURE_SCHEME_ECDSA_NIST_P384_SHA_384; + } + sig_args.flags = HSM_OP_GENERATE_SIGN_FLAGS_INPUT_DIGEST; + + #ifdef DEBUG_SECO + printf("Trying to create an ECC signature:\n"); + printf("\tkeyID : %u\n", sig_args.key_identifier); + printf("\tmsg size : %d\n", sig_args.message_size); + printf("\tsig size : %d\n", sig_args.signature_size); + #endif + err = hsm_generate_signature(sig_gen_hdl, &sig_args); + + /* always try to close sign service when open */ + if (hsm_close_signature_generation_service(sig_gen_hdl) + != HSM_NO_ERROR) { + err = HSM_GENERAL_ERROR; + } + } + + /* copy out r and s on success */ + if (err == HSM_NO_ERROR) { + XMEMCPY((byte*)buf[2].TheAddress, sigOut, buf[2].Length); + XMEMCPY((byte*)buf[3].TheAddress, sigOut + buf[2].Length, + buf[3].Length); + } + + wc_UnLockMutex(&caamMutex); + + (void)sz; + if (wc_TranslateHSMError(0, err) != Success) { + return -1; + } + else { + return 0; + } +} + + +/* verify a signature (hash(msg)) using HSM */ +static hsm_err_t wc_SECO_ECDSA_Verify(unsigned int args[4], CAAM_BUFFER *buf, + int sz) +{ + hsm_err_t err; + hsm_hdl_t sig_ver_hdl; + open_svc_sign_ver_args_t open_sig_ver_args; + op_verify_sign_args_t sig_ver_args; + hsm_verification_status_t verify; + + byte rsR[2*MAX_ECC_BYTES]; + word32 rsRSz = 2*MAX_ECC_BYTES; + + if (args[3] != 32 && args[3] != 48) { + WOLFSSL_MSG("Unexpected key size"); + return BAD_FUNC_ARG; + } + + if (buf[1].Length != (int)args[3]) { + WOLFSSL_MSG("Bad message input size"); + return BAD_FUNC_ARG; + } + + if (wc_LockMutex(&caamMutex) != 0) { + return BAD_MUTEX_E; + } + + XMEMSET(rsR, 0, rsRSz); + XMEMCPY(rsR, (byte*)buf[2].TheAddress, buf[2].Length); + XMEMCPY(rsR + buf[2].Length, (byte*)buf[3].TheAddress, buf[3].Length); + rsRSz = buf[2].Length + buf[3].Length + 1; /* +1 for the HSM compression */ + + XMEMSET(&open_sig_ver_args, 0, sizeof(open_sig_ver_args)); + err = hsm_open_signature_verification_service(hsm_session, + &open_sig_ver_args, &sig_ver_hdl); + if (err == HSM_NO_ERROR) { + XMEMSET(&sig_ver_args, 0, sizeof(sig_ver_args)); + sig_ver_args.key = (uint8_t*)buf[0].TheAddress; + sig_ver_args.key_size = buf[0].Length; + sig_ver_args.message = (uint8_t*)buf[1].TheAddress; + sig_ver_args.message_size = buf[1].Length; + sig_ver_args.signature = rsR; + sig_ver_args.signature_size = rsRSz; + if (args[3] == 32) { + sig_ver_args.scheme_id = + HSM_SIGNATURE_SCHEME_ECDSA_NIST_P256_SHA_256; + } + else { + sig_ver_args.scheme_id = + HSM_SIGNATURE_SCHEME_ECDSA_NIST_P384_SHA_384; + } + sig_ver_args.flags = HSM_OP_VERIFY_SIGN_FLAGS_INPUT_DIGEST; + + #ifdef DEBUG_SECO + { + word32 i; + + printf("Trying to verify an ECC signature:\n"); + printf("\tpublic key : "); + for (i = 0; i < sig_ver_args.key_size; i++) + printf("%02X", sig_ver_args.key[i]); + printf("\n"); + printf("\tsignature : "); + for (i = 0; i < sig_ver_args.signature_size; i++) + printf("%02X", sig_ver_args.signature[i]); + printf("\n"); + printf("\tmsg size : %d\n", sig_ver_args.message_size); + } + #endif + err = hsm_verify_signature (sig_ver_hdl, &sig_ver_args, + &verify); + if (verify != HSM_VERIFICATION_STATUS_SUCCESS) { + WOLFSSL_MSG("Verification found bad signature"); + err = HSM_GENERAL_ERROR; + } + + if (hsm_close_signature_verification_service(sig_ver_hdl) != + HSM_NO_ERROR) { + err = HSM_GENERAL_ERROR; + } + } + + wc_UnLockMutex(&caamMutex); + + (void)sz; + return err; +} + + +static hsm_err_t wc_SECO_CMAC(unsigned int args[4], CAAM_BUFFER* buf, int sz) +{ + unsigned int blackKey; + hsm_err_t err; + hsm_hdl_t mac_hdl; + open_svc_mac_args_t mac_svc_args; + op_mac_one_go_args_t mac_args; + hsm_mac_verification_status_t status; + + if ((args[0] & CAAM_ALG_FINAL) == 0) { + WOLFSSL_MSG("CMAC expected only in final case!"); + return HSM_GENERAL_ERROR; + } + + blackKey = args[2]; + /* black key listed as 0, the key needs to be imported */ + if (blackKey == 0) { + int keyGroup = 1; /* group one was chosen arbitrarily */ + byte importIV[GCM_NONCE_MID_SZ]; + int importIVSz = GCM_NONCE_MID_SZ; + int keyType = 0; + WC_RNG rng; + + if (wc_InitRng(&rng) != 0) { + WOLFSSL_MSG("RNG init for IV failed"); + return HSM_GENERAL_ERROR; + } + + if (wc_RNG_GenerateBlock(&rng, importIV, importIVSz) != 0) { + WOLFSSL_MSG("Generate IV failed"); + wc_FreeRng(&rng); + return HSM_GENERAL_ERROR; + } + wc_FreeRng(&rng); + + switch (buf[0].Length) { + case AES_128_KEY_SIZE: keyType = CAAM_KEYTYPE_AES128; break; + case AES_192_KEY_SIZE: keyType = CAAM_KEYTYPE_AES192; break; + case AES_256_KEY_SIZE: keyType = CAAM_KEYTYPE_AES256; break; + } + + blackKey = wc_SECO_WrapKey(0, (byte*)buf[0].TheAddress, buf[0].Length, + importIV, importIVSz, keyType, CAAM_KEY_TRANSIENT, keyGroup); + + if (blackKey == 0) { + return WC_HW_E; + } + } + + err = hsm_open_mac_service(key_store_hdl, &mac_svc_args, &mac_hdl); + if (err == HSM_NO_ERROR) { + mac_args.key_identifier = blackKey; /* blackKey / HSM */ + mac_args.algorithm = HSM_OP_MAC_ONE_GO_ALGO_AES_CMAC; + mac_args.flags = HSM_OP_MAC_ONE_GO_FLAGS_MAC_GENERATION; + + mac_args.payload = (uint8_t*)buf[2].TheAddress; + mac_args.payload_size = buf[2].Length; + + mac_args.mac = (uint8_t*)buf[1].TheAddress; + mac_args.mac_size = (buf[1].Length < AES_BLOCK_SIZE)? buf[1].Length: + AES_BLOCK_SIZE; + #ifdef DEBUG_SECO + printf("CMAC arguments used:\n"); + printf("\tkey id = %d\n", mac_args.key_identifier); + printf("\tpayload = %p\n", mac_args.payload); + printf("\tpayload size = %d\n", mac_args.payload_size); + printf("\tmac out = %p\n", mac_args.mac); + printf("\tmac out size = %d\n", mac_args.mac_size); + #endif + err = hsm_mac_one_go(mac_hdl, &mac_args, &status); + + /* always try to close mac service if open */ + if (hsm_close_mac_service(mac_hdl) != HSM_NO_ERROR) { + WOLFSSL_MSG("Error closing down mac service handle"); + err = HSM_GENERAL_ERROR; + } + } + + (void)sz; + return err; +} + + +/* common code between CBC,ECB, and CCM modes */ +static hsm_err_t wc_SEC_AES_Common(unsigned int args[4], CAAM_BUFFER* buf, + int sz, hsm_op_cipher_one_go_algo_t algo, + uint8_t* in, int inSz, uint8_t* out, int outSz) +{ + hsm_hdl_t cipher_hdl; + open_svc_cipher_args_t open_args; + op_cipher_one_go_args_t cipher_args; + hsm_err_t err; + + XMEMSET(&open_args, 0, sizeof(open_args)); + err = hsm_open_cipher_service(key_store_hdl, &open_args, &cipher_hdl); + if (err == HSM_NO_ERROR) { + XMEMSET(&cipher_args, 0, sizeof(cipher_args)); + cipher_args.key_identifier = args[3]; /* black key / HSM */ + cipher_args.iv = (uint8_t*)buf[1].TheAddress; + cipher_args.iv_size = buf[1].Length; + + cipher_args.cipher_algo = algo; + if (args[0] == CAAM_DEC) { + cipher_args.flags = HSM_CIPHER_ONE_GO_FLAGS_DECRYPT; + } + else { + cipher_args.flags = HSM_CIPHER_ONE_GO_FLAGS_ENCRYPT; + } + + cipher_args.input = in; + cipher_args.input_size = inSz; + cipher_args.output = out; + cipher_args.output_size = outSz; + + #ifdef DEBUG_SECO + printf("AES Operation :\n"); + printf("\tkeyID : %u\n", cipher_args.key_identifier); + printf("\tinput : %p\n", cipher_args.input); + printf("\tinput sz : %d\n", cipher_args.input_size); + printf("\toutput : %p\n", cipher_args.output); + printf("\toutput sz : %d\n", cipher_args.output_size); + printf("\tiv : %p\n", cipher_args.iv); + printf("\tiv sz : %d\n", cipher_args.iv_size); + #endif + err = hsm_cipher_one_go(cipher_hdl, &cipher_args); + + /* always try to close cipher service if open */ + if (hsm_close_cipher_service(cipher_hdl) != HSM_NO_ERROR) { + err = HSM_GENERAL_ERROR; + } + } + + (void)sz; + return err; +} + + +static hsm_err_t wc_SECO_AESECB(unsigned int args[4], CAAM_BUFFER* buf, int sz) +{ + return wc_SEC_AES_Common(args, buf, sz, HSM_CIPHER_ONE_GO_ALGO_AES_ECB, + (uint8_t*)buf[2].TheAddress, buf[2].Length, + (uint8_t*)buf[3].TheAddress, buf[3].Length); +} + + +static hsm_err_t wc_SECO_AESCBC(unsigned int args[4], CAAM_BUFFER* buf, int sz) +{ + return wc_SEC_AES_Common(args, buf, sz, HSM_CIPHER_ONE_GO_ALGO_AES_CBC, + (uint8_t*)buf[2].TheAddress, buf[2].Length, + (uint8_t*)buf[3].TheAddress, buf[3].Length); +} + + +static hsm_err_t wc_SECO_AESCCM(unsigned int args[4], CAAM_BUFFER* buf, int sz) +{ + hsm_err_t err; + uint8_t* in; + uint8_t* out; + int inSz; + int outSz; + + byte* cipherAndTag = NULL; + int cipherAndTagSz = 0; + + if (buf[1].Length != 12) { + WOLFSSL_MSG("SECO expecting nonce size of 12"); + return HSM_GENERAL_ERROR; + } + + if (buf[4].Length != 16) { + WOLFSSL_MSG("SECO expecting tag size of 16"); + return HSM_GENERAL_ERROR; + } + + if (buf[5].Length != 0) { + WOLFSSL_MSG("SECO expecting adata size of 0"); + return HSM_GENERAL_ERROR; + } + + cipherAndTagSz = buf[4].Length + buf[2].Length; + cipherAndTag = (byte*)XMALLOC(cipherAndTagSz, NULL, + DYNAMIC_TYPE_TMP_BUFFER); + if (args[0] == CAAM_ENC) { + in = (uint8_t*)buf[2].TheAddress; + inSz = buf[2].Length; + out = cipherAndTag; + outSz = cipherAndTagSz; + } + else { + XMEMCPY(cipherAndTag, (uint8_t*)buf[2].TheAddress, buf[2].Length); + XMEMCPY(cipherAndTag + buf[2].Length, (uint8_t*)buf[4].TheAddress, + buf[4].Length); + in = cipherAndTag; + inSz = cipherAndTagSz; + out = (uint8_t*)buf[3].TheAddress; + outSz = buf[3].Length; + } + + err = wc_SEC_AES_Common(args, buf, sz, HSM_CIPHER_ONE_GO_ALGO_AES_CCM, + in, inSz, out, outSz); + if (err == HSM_NO_ERROR) { + if (args[0] == CAAM_ENC) { + XMEMCPY((uint8_t*)buf[4].TheAddress, cipherAndTag + inSz, + buf[4].Length); + XMEMCPY((uint8_t*)buf[3].TheAddress, cipherAndTag, buf[3].Length); + } + } + XFREE(cipherAndTag, NULL, DYNAMIC_TYPE_TMP_BUFFER); + return err; +} + + +static hsm_err_t wc_SECO_AESGCM(unsigned int args[4], CAAM_BUFFER* buf, int sz) +{ + hsm_err_t err; + hsm_hdl_t cipher_hdl; + op_auth_enc_args_t auth_args; + open_svc_cipher_args_t open_args; + uint8_t* in; + uint8_t* out; + int inSz; + int outSz; + byte* cipherAndTag = NULL; + int cipherAndTagSz = 0; + + XMEMSET(&open_args, 0, sizeof(open_args)); + err = hsm_open_cipher_service(key_store_hdl, &open_args, &cipher_hdl); + if (err == HSM_NO_ERROR) { + cipherAndTagSz = buf[4].Length + buf[2].Length; + cipherAndTag = (byte*)XMALLOC(cipherAndTagSz, NULL, + DYNAMIC_TYPE_TMP_BUFFER); + if (args[0] == CAAM_ENC) { + in = (uint8_t*)buf[2].TheAddress; + inSz = buf[2].Length; + out = cipherAndTag; + outSz = cipherAndTagSz; + } + else { + XMEMCPY(cipherAndTag, (uint8_t*)buf[2].TheAddress, buf[2].Length); + XMEMCPY(cipherAndTag + buf[2].Length, (uint8_t*)buf[4].TheAddress, + buf[4].Length); + in = cipherAndTag; + inSz = cipherAndTagSz; + out = (uint8_t*)buf[3].TheAddress; + outSz = buf[3].Length; + } + + auth_args.key_identifier = args[3]; /* black key / HSM */ + auth_args.iv = (uint8_t*)buf[1].TheAddress; + auth_args.iv_size = buf[1].Length; + auth_args.input = in; + auth_args.input_size = inSz; + auth_args.output = out; + auth_args.output_size = outSz; + auth_args.aad = (uint8_t*)buf[5].TheAddress; + auth_args.aad_size = buf[5].Length; + + if (args[0] == CAAM_DEC) { + auth_args.flags = HSM_AUTH_ENC_FLAGS_DECRYPT; + } + else { + auth_args.flags = HSM_AUTH_ENC_FLAGS_ENCRYPT; + } + auth_args.ae_algo = HSM_AUTH_ENC_ALGO_AES_GCM; + + #ifdef DEBUG_SECO + printf("AES GCM Operation :\n"); + printf("\tkeyID : %u\n", auth_args.key_identifier); + printf("\tinput : %p\n", auth_args.input); + printf("\tinput sz : %d\n", auth_args.input_size); + printf("\toutput : %p\n", auth_args.output); + printf("\toutput sz : %d\n", auth_args.output_size); + printf("\tiv : %p\n", auth_args.iv); + printf("\tiv sz : %d\n", auth_args.iv_size); + printf("\taad : %p\n", auth_args.aad); + printf("\taad sz : %d\n", auth_args.aad_size); + #endif + err = hsm_auth_enc(cipher_hdl, &auth_args); + + /* always try to close cipher service if open */ + if (hsm_close_cipher_service(cipher_hdl) != HSM_NO_ERROR) { + err = HSM_GENERAL_ERROR; + } + } + + if (err == HSM_NO_ERROR) { + if (args[0] == CAAM_ENC) { + XMEMCPY((uint8_t*)buf[4].TheAddress, cipherAndTag + inSz, + buf[4].Length); + XMEMCPY((uint8_t*)buf[3].TheAddress, cipherAndTag, buf[3].Length); + } + } + XFREE(cipherAndTag, NULL, DYNAMIC_TYPE_TMP_BUFFER); + (void)sz; + return HSM_NO_ERROR; +} + + +/* use KEK to encrypt and import a key + * return 0 on failure and new key ID on success */ +word32 wc_SECO_WrapKey(word32 keyId, byte* in, word32 inSz, byte* iv, + word32 ivSz, int keyType, int keyInfo, int group) +{ + op_manage_key_args_t key_args; + hsm_hdl_t key_mgmt_hdl; + Aes aes; + int ret = 0; + word32 outId = 0; + byte *wrappedKey = NULL; + word32 wrappedKeySz; + open_svc_key_management_args_t key_mgmt_args; + hsm_err_t err; + + if (group > MAX_GROUP) { + WOLFSSL_MSG("group number is too large"); + return 0; + } + + if (ivSz != (word32)GCM_NONCE_MID_SZ) { + WOLFSSL_MSG("expected an IV size of 12"); + return 0; + } + + /* iv + key + tag */ + wrappedKeySz = GCM_NONCE_MID_SZ + inSz + AES_BLOCK_SIZE; + wrappedKey = (byte*)XMALLOC(wrappedKeySz, NULL, DYNAMIC_TYPE_TMP_BUFFER); + if (wrappedKey == NULL) { + WOLFSSL_MSG("Error malloc'ing buffer for wrapped key"); + return 0; + } + + XMEMSET(&key_mgmt_args, 0, sizeof(key_mgmt_args)); + err = hsm_open_key_management_service( + key_store_hdl, &key_mgmt_args, &key_mgmt_hdl); + + XMEMSET(&key_args, 0, sizeof(key_args)); + XMEMSET(wrappedKey, 0, wrappedKeySz); + XMEMCPY(wrappedKey, iv, ivSz); + + key_args.flags = HSM_OP_MANAGE_KEY_FLAGS_IMPORT_CREATE; + if (keyId == 0) { /* use the root unique key if no ID is provided */ + byte KEK[AES_256_KEY_SIZE]; + byte KEKSz = AES_256_KEY_SIZE; + + ret = wc_SECO_ExportKEK(KEK, KEKSz, 0); + if (ret != 0) { + WOLFSSL_MSG("error with getting KEK from device"); + } + + if (ret == 0) { + /* use software implementation for encrypting with KEK */ + ret = wc_AesInit(&aes, NULL, INVALID_DEVID); + } + + if (ret == 0) { + ret = wc_AesGcmSetKey(&aes, KEK, KEKSz); + if (ret != 0) { + WOLFSSL_MSG("error with AES-GCM set key"); + } + } + + key_args.flags |= HSM_OP_MANAGE_KEY_FLAGS_PART_UNIQUE_ROOT_KEK; + #if 0 + /* for now only using the unique kek, this would be for common */ + key_args.flags |= HSM_OP_MANAGE_KEY_FLAGS_COMMON_ROOT_KEK; + #endif + } + else { + wc_AesInit(&aes, NULL, WOLFSSL_SECO_DEVID); + wc_SECO_AesSetKeyID(&aes, keyId); + } + + if (ret == 0) { + ret = wc_AesGcmEncrypt(&aes, wrappedKey + ivSz, in, inSz, + wrappedKey, ivSz, wrappedKey + ivSz + inSz, AES_BLOCK_SIZE, + NULL, 0); + if (ret != 0) { + WOLFSSL_MSG("error with AES-GCM encrypt when wrapping key"); + } + } + + if (err == HSM_NO_ERROR) { + key_args.key_identifier = &outId; + key_args.kek_identifier = keyId; + key_args.key_group = group; + key_args.key_type = KeyTypeToHSM(keyType); + key_args.key_info = KeyInfoToHSM(keyInfo); + key_args.input_data = wrappedKey; + key_args.input_size = wrappedKeySz; + + #ifdef DEBUG_SECO + { + word32 i; + printf("Import Key Operation :\n"); + printf("\tkey ID : %u\n", *key_args.key_identifier); + printf("\tkEK ID : %u\n", key_args.kek_identifier); + printf("\tflags : %u\n", key_args.flags); + printf("\tgroup : %u\n", key_args.key_group); + printf("\tkey type : %d\n", key_args.key_type); + printf("\tkey info : %d\n", key_args.key_info); + printf("\tkey input Size [iv | key | tag ]: %d\n", key_args.input_size); + printf("\t[iv] = "); + for (i = 0; i < 12; i++) + printf("%02X", key_args.input_data[i]); + printf("\n"); + printf("\t[enc] = "); + for (i = 12; i < 12 + inSz; i++) + printf("%02X", key_args.input_data[i]); + printf("\n"); + printf("\t[tag] = "); + for (i = 12 + inSz; i < 12 + inSz + 16; i++) + printf("%02X", key_args.input_data[i]); + printf("\n"); + } + #endif + + /* only try to import if the AES-GCM encrypt was successful */ + if (ret == 0) { + err = hsm_manage_key(key_mgmt_hdl, &key_args); + } + + #ifdef DEBUG_SECO + if (err == HSM_NO_ERROR) { + printf("Result of Import Key Operation :\n"); + printf("\tkey ID : %u\n", *key_args.key_identifier); + } + #endif + + /* always try to close key management if open */ + if (hsm_close_key_management_service(key_mgmt_hdl) != HSM_NO_ERROR) { + err = HSM_GENERAL_ERROR; + } + } + + if (wrappedKey != NULL) { + XFREE(wrappedKey, NULL, DYNAMIC_TYPE_TMP_BUFFER); + } + + if (wc_TranslateHSMError(0, err) != Success) { + return 0; + } + else { + return *key_args.key_identifier; + } +} + + +/* trasnlates the HSM error to wolfSSL error and does debug print out */ +int wc_TranslateHSMError(int current, hsm_err_t err) +{ + int ret = -1; + + switch (err) { + case HSM_NO_ERROR: + ret = Success; + break; + + case HSM_INVALID_MESSAGE: + WOLFSSL_MSG("SECO HSM: Invalid/unknown msg"); + break; + + case HSM_INVALID_ADDRESS: + WOLFSSL_MSG("SECO HSM: Invalid address"); + break; + + case HSM_UNKNOWN_ID: + WOLFSSL_MSG("SECO HSM: unknown ID"); + break; + + case HSM_INVALID_PARAM: + WOLFSSL_MSG("SECO HSM: invalid param"); + break; + + case HSM_NVM_ERROR: + WOLFSSL_MSG("SECO HSM: generic nvm error"); + break; + + case HSM_OUT_OF_MEMORY: + WOLFSSL_MSG("SECO HSM: out of memory"); + break; + + case HSM_UNKNOWN_HANDLE: + WOLFSSL_MSG("SECO HSM: unknown handle"); + break; + + case HSM_UNKNOWN_KEY_STORE: + WOLFSSL_MSG("SECO HSM: unknown key store"); + break; + + case HSM_KEY_STORE_AUTH: + WOLFSSL_MSG("SECO HSM: key store auth error"); + break; + + case HSM_KEY_STORE_ERROR: + WOLFSSL_MSG("SECO HSM: key store error"); + break; + + case HSM_ID_CONFLICT: + WOLFSSL_MSG("SECO HSM: id conflict"); + break; + + case HSM_RNG_NOT_STARTED: + WOLFSSL_MSG("SECO HSM: RNG not started"); + break; + + case HSM_CMD_NOT_SUPPORTED: + WOLFSSL_MSG("SECO HSM: CMD not support"); + break; + + case HSM_INVALID_LIFECYCLE: + WOLFSSL_MSG("SECO HSM: invalid lifecycle"); + break; + + case HSM_KEY_STORE_CONFLICT: + WOLFSSL_MSG("SECO HSM: store conflict"); + break; + + case HSM_KEY_STORE_COUNTER: + WOLFSSL_MSG("SECO HSM: key store counter error"); + break; + + case HSM_FEATURE_NOT_SUPPORTED: + WOLFSSL_MSG("SECO HSM: feature not supported"); + break; + + case HSM_SELF_TEST_FAILURE: + WOLFSSL_MSG("SECO HSM: self test failure"); + break; + + case HSM_NOT_READY_RATING: + WOLFSSL_MSG("SECO HSM: not ready"); + break; + + case HSM_FEATURE_DISABLED: + WOLFSSL_MSG("SECO HSM: feature is disabled error"); + break; + + case HSM_GENERAL_ERROR: + WOLFSSL_MSG("SECO HSM: general error found"); + break; + + default: + WOLFSSL_MSG("SECO HSM: unkown error value found"); + } + + if (current != 0) { + WOLFSSL_MSG("In an error state before SECO HSM error"); + ret = current; + } + + return ret; +} + + +/* Do a synchronous operations and block till done + * returns Success on success */ +int SynchronousSendRequest(int type, unsigned int args[4], CAAM_BUFFER *buf, + int sz) +{ + int ret = 0; + hsm_err_t err = HSM_NO_ERROR; + CAAM_ADDRESS pubkey, privkey; + + switch (type) { + case CAAM_ENTROPY: + err = wc_SECO_RNG(args, buf, sz); + break; + + case CAAM_SHA224: + case CAAM_SHA256: + case CAAM_SHA384: + case CAAM_SHA512: + err = wc_SECO_Hash(args, buf, sz, type); + break; + + case CAAM_GET_PART: + case CAAM_FREE_PART: + case CAAM_FIND_PART: + case CAAM_READ_PART: + case CAAM_WRITE_PART: + break; + + case CAAM_ECDSA_KEYPAIR: + err = wc_SECO_ECDSA_Make(args, buf, sz); + break; + + case CAAM_ECDSA_VERIFY: + err = wc_SECO_ECDSA_Verify(args, buf, sz); + break; + + case CAAM_ECDSA_SIGN: + err = wc_SECO_ECDSA_Sign(args, buf, sz); + break; + + case CAAM_ECDSA_ECDH: + break; + + case CAAM_BLOB_ENCAP: + case CAAM_BLOB_DECAP: + break; + + case CAAM_AESECB: + err = wc_SECO_AESECB(args, buf, sz); + break; + + case CAAM_AESCBC: + err = wc_SECO_AESCBC(args, buf, sz); + break; + + case CAAM_AESCCM: + err = wc_SECO_AESCCM(args, buf, sz); + break; + + case CAAM_AESGCM: + err = wc_SECO_AESGCM(args, buf, sz); + break; + + case CAAM_CMAC: + err = wc_SECO_CMAC(args, buf, sz); + break; + + case CAAM_FIFO_S: + default: + WOLFSSL_MSG("Unknown/unsupported type"); + ret = -1; + } + + (void)pubkey; + (void)privkey; + (void)sz; + return wc_TranslateHSMError(ret, err); +} +#endif /* WOLFSSL_SECO_CAAM */ + diff --git a/wolfcrypt/src/port/caam/wolfcaam_x25519.c b/wolfcrypt/src/port/caam/wolfcaam_x25519.c new file mode 100644 index 000000000..d6a785c4a --- /dev/null +++ b/wolfcrypt/src/port/caam/wolfcaam_x25519.c @@ -0,0 +1,129 @@ +/* wolfcaam_x25519.c + * + * Copyright (C) 2006-2021 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + +#ifdef HAVE_CONFIG_H + #include +#endif + +#include + +#if defined(WOLFSSL_CAAM) && defined(HAVE_CURVE25519) + +#include +#include + +#ifdef NO_INLINE + #include +#else + #define WOLFSSL_MISC_INCLUDED + #include +#endif + +#include +#include + +#if defined(WOLFSSL_CAAM_DEBUG) || defined(WOLFSSL_CAAM_PRINT) +#include +#endif + +#if defined(WOLFSSL_DEVCRYPTO_CURVE25519) +#include + +/* HSM lib does not support Curve25519 with QXP board, use devcrypto instead */ +static int wc_CAAM_Curve25519Generic(byte* out, word32 outSz, const byte* k, + word32 kSz, const byte* a, word32 aSz, int endian) +{ + return wc_DevCryptoCurve25519(out, outSz, k, kSz, a, aSz, endian); +} + + +int wc_CAAM_MakeCurve25519Key(curve25519_key* key, int keySize, WC_RNG* rng) +{ + int ret = 0; + + if (keySize != CURVE25519_KEYSIZE || rng == NULL || key == NULL) { + ret = BAD_FUNC_ARG; + } + + if (ret == 0) { + ret = wc_curve25519_make_priv(rng, keySize, key->k); + } + + /* create public key from private key */ + if (ret == 0) { + static const unsigned char basePoint[CURVE25519_KEYSIZE] = {9}; + word32 outlen = (word32)keySize; + + key->privSet = 1; + ret = wc_CAAM_Curve25519Generic(key->p.point, outlen, key->k, + CURVE25519_KEYSIZE, basePoint, CURVE25519_KEYSIZE, + EC25519_LITTLE_ENDIAN); + if (ret == 0) { + key->pubSet = 1; + } + } + + return ret; +} + + +int wc_CAAM_Curve25519(byte* out, word32* outlen, curve25519_key* k, + curve25519_key* pubKey, int endian) +{ + int ret = 0; + + if (*outlen < CURVE25519_KEYSIZE) { + ret = BAD_FUNC_ARG; + } + + if (ret == 0) { + *outlen = CURVE25519_KEYSIZE; + ret = wc_CAAM_Curve25519Generic(out, *outlen, k->k, CURVE25519_KEYSIZE, + pubKey->p.point, CURVE25519_KEYSIZE, endian); + } + + return ret; +} + +#else + +int wc_CAAM_MakeCurve25519Key(curve25519_key* key, int keySize, WC_RNG* rng) +{ + (void)keySize; + (void)key; + (void)rng; + return CRYPTOCB_UNAVAILABLE; +} + + +int wc_CAAM_Curve25519(byte* out, word32* outlen, curve25519_key* k, + curve25519_key* pubKey, int endian) +{ + (void)out; + (void)outlen; + (void)k; + (void)pubKey; + (void)endian; + return CRYPTOCB_UNAVAILABLE; +} +#endif /* WOLFSSL_DEVCRYPTO_CURVE25519 */ +#endif + diff --git a/wolfcrypt/src/port/devcrypto/devcrypto_ecdsa.c b/wolfcrypt/src/port/devcrypto/devcrypto_ecdsa.c new file mode 100644 index 000000000..b9e3f0db0 --- /dev/null +++ b/wolfcrypt/src/port/devcrypto/devcrypto_ecdsa.c @@ -0,0 +1,278 @@ +/* devcrypto_ecdsa.c + * + * Copyright (C) 2006-2021 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + + +#ifdef HAVE_CONFIG_H + #include +#endif + +#include + +#if defined(WOLFSSL_DEVCRYPTO_ECDSA) + +#include +#include +#include +#include + + +static int CurveIDToFlag(int curveId) +{ + int ret = 0; + + switch (curveId) { + case ECC_SECP256R1: + ret = CAAM_EC_CURVE_P_256; + break; + case ECC_SECP384R1: + ret = CAAM_EC_CURVE_P_384; + break; + default: + WOLFSSL_MSG("Curve id not found"); + } + return ret; +} + +int wc_DevCryptoEccKeyGen(int curveId, int enc, byte* pri, word32 priSz, + byte* pub, word32 pubSz) +{ + struct crypt_kop kop; + int inIdx = 0; + int outIdx = 0; + int ret = 0; + WC_CRYPTODEV ctx; + int ecdsel; + + ecdsel = CurveIDToFlag(curveId); + if (ecdsel == 0) { + ret = NOT_COMPILED_IN; + } + + if (ret == 0) { + ret = wc_DevCryptoCreate(&ctx, CRYPTO_ASYM_ECC_KEYGEN, NULL, 0); + } + + if (ret == 0) { + kop.crk_op = CRK_ECC_KEYGEN; + kop.ses = ctx.sess.ses; + kop.crk_flags = ecdsel; + if (enc) { + kop.crk_flags |= (CAAM_KEY_COLOR_BLACK << 8); + } + + kop.crk_param[inIdx + outIdx].crp_p = pri; + kop.crk_param[inIdx + outIdx].crp_nbits = priSz * WOLFSSL_BIT_SIZE; + outIdx++; + + kop.crk_param[inIdx + outIdx].crp_p = pub; + kop.crk_param[inIdx + outIdx].crp_nbits = pubSz * WOLFSSL_BIT_SIZE; + outIdx++; + + kop.crk_iparams = inIdx; + kop.crk_oparams = outIdx; + + if (ioctl(ctx.cfd, CIOCKEY, &kop)) { + #if defined(DEBUG_DEVCRYPTO) + perror("Error value with ECC keygen operation was "); + #endif + WOLFSSL_MSG("Error with call to ioctl"); + ret = WC_DEVCRYPTO_E; + } + wc_DevCryptoFree(&ctx); + } + return ret; +} + + +int wc_DevCryptoEccEcdh(int curveId, int enc, byte* pri, word32 priSz, + byte* pub, word32 pubSz, byte* out, word32 outSz) +{ + struct crypt_kop kop; + int inIdx = 0; + int outIdx = 0; + int ret = 0; + int ecdsel; + WC_CRYPTODEV ctx; + + ecdsel = CurveIDToFlag(curveId); + if (ecdsel == 0) { + ret = NOT_COMPILED_IN; + } + + if (ret == 0) { + ret = wc_DevCryptoCreate(&ctx, CRYPTO_ASYM_ECC_ECDH, NULL, 0); + } + + if (ret == 0) { + XMEMSET(&kop, 0, sizeof(kop)); + kop.crk_op = CRK_ECC_ECDH; + kop.ses = ctx.sess.ses; + kop.crk_flags = CurveIDToFlag(curveId); + if (enc) { + kop.crk_flags |= (CAAM_KEY_COLOR_BLACK << 8); + } + + kop.crk_param[inIdx].crp_p = pub; + kop.crk_param[inIdx].crp_nbits = pubSz * WOLFSSL_BIT_SIZE; + inIdx++; + + kop.crk_param[inIdx].crp_p = pri; + kop.crk_param[inIdx].crp_nbits = priSz * WOLFSSL_BIT_SIZE; + inIdx++; + + kop.crk_param[inIdx + outIdx].crp_p = out; + kop.crk_param[inIdx + outIdx].crp_nbits = outSz * WOLFSSL_BIT_SIZE; + outIdx++; + + kop.crk_iparams = inIdx; + kop.crk_oparams = outIdx; + + if (ioctl(ctx.cfd, CIOCKEY, &kop)) { + #if defined(DEBUG_DEVCRYPTO) + perror("Error value with ECC keygen operation was "); + #endif + WOLFSSL_MSG("Error with call to ioctl"); + ret = WC_DEVCRYPTO_E; + } + wc_DevCryptoFree(&ctx); + } + return ret; +} + + +int wc_DevCryptoEccSign(int curveId, int enc, byte* pri, word32 priSz, + const byte* hash, word32 hashSz, byte* r, word32 rSz, byte* s, word32 sSz) +{ + struct crypt_kop kop; + int inIdx = 0; + int outIdx = 0; + int ret = 0; + int ecdsel; + WC_CRYPTODEV ctx; + + ecdsel = CurveIDToFlag(curveId); + if (ecdsel == 0) { + ret = NOT_COMPILED_IN; + } + + if (ret == 0) { + ret = wc_DevCryptoCreate(&ctx, CRYPTO_ASYM_ECDSA_SIGN, NULL, 0); + } + + if (ret == 0) { + XMEMSET(&kop, 0, sizeof(kop)); + kop.crk_op = CRK_ECDSA_SIGN; + kop.ses = ctx.sess.ses; + kop.crk_flags = CurveIDToFlag(curveId); + if (enc) { + kop.crk_flags |= (CAAM_KEY_COLOR_BLACK << 8); + } + + kop.crk_param[inIdx].crp_p = pri; + kop.crk_param[inIdx].crp_nbits = priSz * WOLFSSL_BIT_SIZE; + inIdx++; + + kop.crk_param[inIdx].crp_p = (byte*)hash; + kop.crk_param[inIdx].crp_nbits = hashSz * WOLFSSL_BIT_SIZE; + inIdx++; + + kop.crk_param[inIdx + outIdx].crp_p = r; + kop.crk_param[inIdx + outIdx].crp_nbits = rSz * WOLFSSL_BIT_SIZE; + outIdx++; + + kop.crk_param[inIdx + outIdx].crp_p = s; + kop.crk_param[inIdx + outIdx].crp_nbits = sSz * WOLFSSL_BIT_SIZE; + outIdx++; + + kop.crk_iparams = inIdx; + kop.crk_oparams = outIdx; + if (ioctl(ctx.cfd, CIOCKEY, &kop)) { + #if defined(DEBUG_DEVCRYPTO) + perror("Error value with ECC keygen operation was "); + #endif + WOLFSSL_MSG("Error with call to ioctl"); + ret = WC_DEVCRYPTO_E; + } + wc_DevCryptoFree(&ctx); + } + return ret; +} + +int wc_DevCryptoEccVerify(int curveId, byte* pub, word32 pubSz, + const byte* hash, word32 hashSz, byte* r, word32 rSz, byte* s, word32 sSz) +{ + struct crypt_kop kop; + int inIdx = 0; + int outIdx = 0; + int ret = 0; + int ecdsel; + WC_CRYPTODEV ctx; + + ecdsel = CurveIDToFlag(curveId); + if (ecdsel == 0) { + ret = NOT_COMPILED_IN; + } + + if (ret == 0) { + ret = wc_DevCryptoCreate(&ctx, CRYPTO_ASYM_ECDSA_VERIFY, NULL, 0); + } + if (ret == 0) { + kop.crk_op = CRK_ECDSA_VERIFY; + kop.ses = ctx.sess.ses; + kop.crk_flags = CurveIDToFlag(curveId); + + kop.crk_param[inIdx].crp_p = pub; + kop.crk_param[inIdx].crp_nbits = pubSz * WOLFSSL_BIT_SIZE; + inIdx++; + + kop.crk_param[inIdx].crp_p = (byte*)hash; + kop.crk_param[inIdx].crp_nbits = hashSz * WOLFSSL_BIT_SIZE; + inIdx++; + + kop.crk_param[inIdx].crp_p = r; + kop.crk_param[inIdx].crp_nbits = rSz * WOLFSSL_BIT_SIZE; + inIdx++; + + kop.crk_param[inIdx].crp_p = s; + kop.crk_param[inIdx].crp_nbits = sSz * WOLFSSL_BIT_SIZE; + inIdx++; + + kop.crk_iparams = inIdx; + kop.crk_oparams = outIdx; + if (ioctl(ctx.cfd, CIOCKEY, &kop)) { + #if defined(DEBUG_DEVCRYPTO) + perror("Error value with ECC keygen operation was "); + #endif + WOLFSSL_MSG("Error with call to ioctl"); + ret = WC_DEVCRYPTO_E; + } + wc_DevCryptoFree(&ctx); + } + + if (ret == 0) { + if (kop.crk_status == 0) { + ret = SIG_VERIFY_E; + } + } + return ret; +} +#endif /* WOLFSSL_DEVCRYPTO_ECDSA */ + diff --git a/wolfcrypt/src/port/devcrypto/devcrypto_hash.c b/wolfcrypt/src/port/devcrypto/devcrypto_hash.c index 09ed5f1ab..465686759 100644 --- a/wolfcrypt/src/port/devcrypto/devcrypto_hash.c +++ b/wolfcrypt/src/port/devcrypto/devcrypto_hash.c @@ -86,7 +86,8 @@ static int HashUpdate(void* ctx, int type, const byte* input, word32 inputSz) return BAD_FUNC_ARG; } - wc_SetupCrypt(&crt, dev, (byte*)input, inputSz, NULL, digest, COP_FLAG_UPDATE); + wc_SetupCrypt(&crt, dev, (byte*)input, inputSz, NULL, digest, + COP_FLAG_UPDATE, COP_ENCRYPT); if (ioctl(dev->cfd, CIOCCRYPT, &crt)) { WOLFSSL_MSG("Error with call to ioctl"); return WC_DEVCRYPTO_E; @@ -107,7 +108,7 @@ static int GetDigest(void* ctx, int type, byte* out) return BAD_FUNC_ARG; } - wc_SetupCrypt(&crt, dev, NULL, 0, NULL, out, COP_FLAG_FINAL); + wc_SetupCrypt(&crt, dev, NULL, 0, NULL, out, COP_FLAG_FINAL, COP_ENCRYPT); if (ioctl(dev->cfd, CIOCCRYPT, &crt)) { WOLFSSL_MSG("Error with call to ioctl"); return WC_DEVCRYPTO_E; diff --git a/wolfcrypt/src/port/devcrypto/devcrypto_hmac.c b/wolfcrypt/src/port/devcrypto/devcrypto_hmac.c new file mode 100644 index 000000000..f1ff58a73 --- /dev/null +++ b/wolfcrypt/src/port/devcrypto/devcrypto_hmac.c @@ -0,0 +1,129 @@ +/* devcrypto_hmac.c + * + * Copyright (C) 2006-2021 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + + +#ifdef HAVE_CONFIG_H + #include +#endif + +#include + +#if defined(WOLFSSL_DEVCRYPTO_HMAC) + +#include +#include +#include +#include + +static int InternalTypeToDevcrypto(int t) +{ + switch (t) { + case WC_HASH_TYPE_MD5: + return CRYPTO_MD5_HMAC; + case WC_HASH_TYPE_SHA: + return CRYPTO_SHA1_HMAC; + case WC_HASH_TYPE_SHA256: + return CRYPTO_SHA2_256_HMAC; + case WC_HASH_TYPE_SHA384: + return CRYPTO_SHA2_384_HMAC; + case WC_HASH_TYPE_SHA512: + return CRYPTO_SHA2_512_HMAC; + default: + WOLFSSL_MSG("Unsupported HMAC hash type with devcrypto"); + } + return HASH_TYPE_E; +} + + +int wc_DevCrypto_HmacSetKey(Hmac* hmac, int t, const byte* key, word32 keySz) +{ + int hType; + + hmac->ctx.cfd = -1; + hType = InternalTypeToDevcrypto(t); + if (hType < 0) { + return hType; + } + else { + return wc_DevCryptoCreate(&hmac->ctx, hType, (byte*)key, keySz); + } +} + + +int wc_DevCrypto_HmacUpdate(Hmac* hmac, const byte* input, word32 inputSz) +{ + WC_CRYPTODEV* dev; + struct crypt_op crt; + + if (inputSz == 0) { + return 0; + } + + if ((dev = &hmac->ctx) == NULL) { + WOLFSSL_MSG("Unsupported hash type"); + return BAD_FUNC_ARG; + } + + wc_SetupCrypt(&crt, dev, (byte*)input, inputSz, NULL, NULL, + COP_FLAG_UPDATE, COP_ENCRYPT); + if (ioctl(dev->cfd, CIOCCRYPT, &crt)) { + WOLFSSL_MSG("Error with call to ioctl"); + return WC_DEVCRYPTO_E; + } + + return 0; + +} + +int wc_DevCrypto_HmacFinal(Hmac* hmac, byte* out) +{ + WC_CRYPTODEV* dev; + struct crypt_op crt; + + if ((dev = &hmac->ctx) == NULL) { + WOLFSSL_MSG("Unsupported hash type"); + return BAD_FUNC_ARG; + } + + wc_SetupCrypt(&crt, dev, NULL, 0, NULL, out, COP_FLAG_FINAL, COP_ENCRYPT); + if (ioctl(dev->cfd, CIOCCRYPT, &crt)) { + WOLFSSL_MSG("Error with call to ioctl"); + return WC_DEVCRYPTO_E; + } + + return 0; +} + +int wc_DevCrypto_HmacInit(Hmac* hmac, void* heap, int devId) +{ + (void)hmac; + (void)heap; + (void)devId; + return 0; +} + + +void wc_DevCrypto_HmacFree(Hmac* hmac) +{ + wc_DevCryptoFree(&hmac->ctx); +} +#endif /* WOLFSSL_DEVCRYPTO */ + diff --git a/wolfcrypt/src/port/devcrypto/devcrypto_rsa.c b/wolfcrypt/src/port/devcrypto/devcrypto_rsa.c new file mode 100644 index 000000000..11ff6436e --- /dev/null +++ b/wolfcrypt/src/port/devcrypto/devcrypto_rsa.c @@ -0,0 +1,580 @@ +/* devcrypto_rsa.c + * + * Copyright (C) 2006-2021 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + + +#ifdef HAVE_CONFIG_H + #include +#endif + +#include + +#if defined(WOLFSSL_DEVCRYPTO_RSA) + +#include +#include +#include +#include + +static void wc_SetupRsaPublic(struct crypt_kop* kop, WC_CRYPTODEV* dev, + const byte* in, word32 inSz, byte* m, word32 mSz, byte* e, word32 eSz, + byte* out, word32 outSz) +{ + int inIdx = 0; + int outIdx = 0; + + kop->crk_op = CRK_RSA_PUBLIC; + kop->crk_pad1 = mSz; + kop->ses = dev->sess.ses; + + kop->crk_param[inIdx].crp_p = (byte*)in; + kop->crk_param[inIdx].crp_nbits = inSz * WOLFSSL_BIT_SIZE; + inIdx++; + + kop->crk_param[inIdx].crp_p = m; + kop->crk_param[inIdx].crp_nbits = mSz * WOLFSSL_BIT_SIZE; + inIdx++; + + kop->crk_param[inIdx].crp_p = e; + kop->crk_param[inIdx].crp_nbits = eSz * WOLFSSL_BIT_SIZE; + inIdx++; + + /* add output buffer */ + kop->crk_param[inIdx + outIdx].crp_p = out; + kop->crk_param[inIdx + outIdx].crp_nbits = outSz * WOLFSSL_BIT_SIZE; + outIdx++; + + kop->crk_iparams = inIdx; + kop->crk_oparams = outIdx; +#ifdef DEBUG_DEVCRYPTO + printf("SetupRsaPublic:\n"); + printf("\tinSz = %u\n", inSz); + printf("\tmSz = %u\n", mSz); + printf("\teSz = %u\n", eSz); + printf("\toutSz= %u\n", outSz); + printf("\tiparams = %d\n", inIdx); + printf("\toparams = %d\n", outIdx); +#endif + (void)dev; +} + + +static void wc_SetupRsaPrivate(struct crypt_kop* kop, WC_CRYPTODEV* dev, + const byte* in, word32 inSz, byte* d, word32 dSz, byte* n, word32 nSz, + byte* p, word32 pSz, byte* q, word32 qSz, byte* dp, word32 dpSz, + byte* dq, word32 dqSz, byte* u, word32 uSz, byte* out, word32 outSz, + int flag) +{ + int inIdx = 0; + int outIdx = 0; + + XMEMSET(kop, 0, sizeof(struct crypt_kop)); + kop->ses = dev->sess.ses; + kop->crk_op = CRK_RSA_PRIVATE; + kop->crk_flags= flag; + + kop->crk_param[inIdx].crp_p = (byte*)in; + kop->crk_param[inIdx].crp_nbits = inSz * WOLFSSL_BIT_SIZE; + inIdx++; + + if (dpSz == 0 || dqSz == 0) { + kop->crk_param[inIdx].crp_p = n; + kop->crk_param[inIdx].crp_nbits = dSz * WOLFSSL_BIT_SIZE; + inIdx++; + + kop->crk_param[inIdx].crp_p = d; + kop->crk_param[inIdx].crp_nbits = nSz * WOLFSSL_BIT_SIZE; + inIdx++; + } + else { + kop->crk_param[inIdx].crp_p = p; + kop->crk_param[inIdx].crp_nbits = pSz * WOLFSSL_BIT_SIZE; + inIdx++; + + kop->crk_param[inIdx].crp_p = q; + kop->crk_param[inIdx].crp_nbits = qSz * WOLFSSL_BIT_SIZE; + inIdx++; + + kop->crk_param[inIdx].crp_p = dp; + kop->crk_param[inIdx].crp_nbits = dpSz * WOLFSSL_BIT_SIZE; + inIdx++; + + kop->crk_param[inIdx].crp_p = dq; + kop->crk_param[inIdx].crp_nbits = dqSz * WOLFSSL_BIT_SIZE; + inIdx++; + + kop->crk_param[inIdx].crp_p = u; + kop->crk_param[inIdx].crp_nbits = uSz * WOLFSSL_BIT_SIZE; + inIdx++; + } + + /* add output buffer */ + kop->crk_param[inIdx + outIdx].crp_p = out; + kop->crk_param[inIdx + outIdx].crp_nbits = outSz * WOLFSSL_BIT_SIZE; + outIdx++; + + kop->crk_iparams = inIdx; + kop->crk_oparams = outIdx; +#ifdef DEBUG_DEVCRYPTO + printf("SetupModExpCrt:\n"); + printf("\tinSz = %u\n", inSz); + printf("\tdSz = %u\n", dSz); + printf("\tpSz = %u\n", pSz); + printf("\tqSz = %u\n", qSz); + printf("\tdpSz = %u\n", dpSz); + printf("\tdqSz = %u\n", dqSz); + printf("\tu = %u\n", uSz); + printf("\toutSz= %u\n", outSz); + printf("\tiparams = %d\n", kop->crk_iparams); + printf("\toparams = %d\n", kop->crk_oparams); +#endif + (void)dev; +} + +static int _PrivateOperation(const byte* in, word32 inlen, byte* out, + word32 outlen, RsaKey* key) +{ + int ret = 0; + WC_CRYPTODEV* dev; + struct crypt_kop kop; + int flag = 0; + byte* d = NULL; + byte* p = NULL; + byte* q = NULL; + byte* dq = NULL; + byte* dp = NULL; + byte* u = NULL; + byte* n = NULL; + word32 dSz, pSz, qSz, dpSz = 0, dqSz = 0, uSz = 0, nSz; + + dev = &key->ctx; + dSz = nSz = wc_RsaEncryptSize(key); + pSz = qSz = nSz / 2; + if (outlen < dSz) { + WOLFSSL_MSG("Output buffer is too small"); + return BAD_FUNC_ARG; + } + outlen = dSz; + + if (wc_DevCryptoCreate(dev, CRYPTO_ASYM_RSA_PRIVATE, NULL, 0) != 0) { + WOLFSSL_MSG("Error getting RSA private session"); + return WC_DEVCRYPTO_E; + } + d = (byte*)XMALLOC(dSz, NULL, DYNAMIC_TYPE_TMP_BUFFER); + p = (byte*)XMALLOC(pSz, NULL, DYNAMIC_TYPE_TMP_BUFFER); + q = (byte*)XMALLOC(qSz, NULL, DYNAMIC_TYPE_TMP_BUFFER); + n = (byte*)XMALLOC(dSz, NULL, DYNAMIC_TYPE_TMP_BUFFER); + if (d == NULL || p == NULL || q == NULL) { + ret = MEMORY_E; + } + + if (ret == 0) { + byte e[8]; + word32 eSz = 8; + ret = wc_RsaExportKey(key, e, &eSz, n, &nSz, d, &dSz, p, &pSz, q, &qSz); + if (ret != 0) { + WOLFSSL_MSG("Error with key export"); + } + if (!key->blackKey) { /* @TODO unexpected results with black key CRT form */ + dpSz = mp_unsigned_bin_size(&key->dP); + dqSz = mp_unsigned_bin_size(&key->dQ); + uSz = mp_unsigned_bin_size(&key->u); + } + } + + /* get values for CRT if present */ + if (!key->blackKey) { /* @TODO unexpected results with black key CRT form */ + if (ret == 0 && dpSz > 0) { + dSz = 0; nSz = 0; + dq = (byte*)XMALLOC(dpSz, NULL, DYNAMIC_TYPE_TMP_BUFFER); + dp = (byte*)XMALLOC(dpSz, NULL, DYNAMIC_TYPE_TMP_BUFFER); + u = (byte*)XMALLOC(uSz, NULL, DYNAMIC_TYPE_TMP_BUFFER); + if (dq == NULL || dp == NULL || u == NULL) { + ret = MEMORY_E; + } + } + if (ret == 0 && dq != NULL && + mp_to_unsigned_bin(&key->dQ, dq) != MP_OKAY) { + ret = MP_READ_E; + } + + if (ret == 0 && dp != NULL && + mp_to_unsigned_bin(&key->dP, dp) != MP_OKAY) { + ret = MP_READ_E; + } + + if (ret == 0 && u != NULL && + mp_to_unsigned_bin(&key->u, u) != MP_OKAY) { + ret = MP_READ_E; + } + } + + if (ret == 0) { + if (key->blackKey) { + flag = (CAAM_KEY_COLOR_BLACK << 8); + } + wc_SetupRsaPrivate(&kop, dev, in, inlen, d, dSz, n, nSz, p, pSz, q, qSz, + dp, dpSz, dq, dqSz, u, uSz, out, outlen, flag); + } + + if (ret == 0) { + if (ioctl(dev->cfd, CIOCKEY, &kop)) { + #if defined(DEBUG_DEVCRYPTO) + perror("Error value with private RSA operation was "); + #endif + WOLFSSL_MSG("Error with call to ioctl"); + ret = WC_DEVCRYPTO_E; + } + } + + if (d != NULL) + XFREE(d, NULL, DYNAMIC_TYPE_TMP_BUFFER); + if (p != NULL) + XFREE(p, NULL, DYNAMIC_TYPE_TMP_BUFFER); + if (q != NULL) + XFREE(q, NULL, DYNAMIC_TYPE_TMP_BUFFER); + if (dp != NULL) + XFREE(dp, NULL, DYNAMIC_TYPE_TMP_BUFFER); + if (dq != NULL) + XFREE(dq, NULL, DYNAMIC_TYPE_TMP_BUFFER); + if (u != NULL) + XFREE(u, NULL, DYNAMIC_TYPE_TMP_BUFFER); + if (n != NULL) + XFREE(n, NULL, DYNAMIC_TYPE_TMP_BUFFER); + + wc_DevCryptoFree(dev); + return ret; +} + + +static int _PublicOperation(const byte* in, word32 inlen, byte* out, + word32 outlen, RsaKey* key) +{ + int ret = 0; + WC_CRYPTODEV* dev; + struct crypt_kop kop; + byte* m = NULL; + byte* e = NULL; + word32 mSz = 0; + word32 eSz = 0; + + dev = &key->ctx; + + key->ctx.cfd = -1; + if (wc_DevCryptoCreate(dev, CRYPTO_ASYM_RSA_PUBLIC, NULL, 0) != 0) { + WOLFSSL_MSG("Error getting RSA public session"); + return WC_DEVCRYPTO_E; + } + + mSz = wc_RsaEncryptSize(key); + eSz = mp_unsigned_bin_size(&key->e); + + m = (byte*)XMALLOC(mSz, NULL, DYNAMIC_TYPE_TMP_BUFFER); + e = (byte*)XMALLOC(eSz, NULL, DYNAMIC_TYPE_TMP_BUFFER); + if (m == NULL || e == NULL) { + ret = MEMORY_E; + } + + if (ret == 0) { + ret = wc_RsaFlattenPublicKey(key, e, &eSz, m, &mSz); + if (ret != 0) { + WOLFSSL_MSG("Issue with getting RSA public key parts"); + } + } + + if (ret == 0) { + wc_SetupRsaPublic(&kop, dev, in, inlen, m, mSz, e, eSz, out, outlen); + if (ioctl(dev->cfd, CIOCKEY, &kop)) { + #if defined(DEBUG_DEVCRYPTO) + perror("Error value with public RSA operation was "); + #endif + WOLFSSL_MSG("Error with call to ioctl"); + ret = WC_DEVCRYPTO_E; + } + } + wc_DevCryptoFree(&key->ctx); + + if (m != NULL) + XFREE(m, NULL, DYNAMIC_TYPE_TMP_BUFFER); + if (e != NULL) + XFREE(e, NULL, DYNAMIC_TYPE_TMP_BUFFER); + return ret; +} + + +int wc_DevCrypto_RsaDecrypt(const byte* in, word32 inlen, + byte* out, word32 outlen, RsaKey* key, int type) +{ + int ret = BAD_FUNC_ARG; + + switch (type) { + case RSA_PUBLIC_DECRYPT: + ret = _PublicOperation(in, inlen, out, outlen, key); + break; + + case RSA_PRIVATE_DECRYPT: + ret = _PrivateOperation(in, inlen, out, outlen, key); + break; + } + + return ret; +} + + +int wc_DevCrypto_RsaEncrypt(const byte* in, word32 inlen, byte* out, + word32* outlen, RsaKey *key, int type) +{ + int ret = BAD_FUNC_ARG; + + switch (type) { + case RSA_PUBLIC_ENCRYPT: + ret = _PublicOperation(in, inlen, out, *outlen, key); + break; + + case RSA_PRIVATE_ENCRYPT: + ret = _PrivateOperation(in, inlen, out, *outlen, key); + break; + } + if (ret == 0) { + *outlen = inlen; + } + + return ret; +} + + +#ifdef WOLFSSL_KEY_GEN +/* generate p and q prive values for RSA key generation + * nSz is size of key in bits + */ +static int GeneratePandQ(byte* p, int pSz, byte* q, int qSz, byte* e, int eSz, + int nSz, WC_RNG* rng) +{ + int isPrime = 0; + int i = 0; + int failCount; + int err; + + /* The failCount value comes from NIST FIPS 186-4, section B.3.3, + * process steps 4.7 and 5.8. */ + failCount = 5 * ((nSz * WOLFSSL_BIT_SIZE)/ 2); + + /* make p */ + do { +#ifdef SHOW_GEN + printf("."); + fflush(stdout); +#endif + /* generate value */ + err = wc_RNG_GenerateBlock(rng, p, pSz); + if (err == 0) { + /* prime lower bound has the MSB set, set it in candidate */ + p[0] |= 0x80; + /* make candidate odd */ + p[pSz-1] |= 0x01; + } + + if (err == MP_OKAY) + err = wc_CheckProbablePrime_ex(p, pSz, NULL, 0, e, eSz, nSz, &isPrime, rng); + + i++; + } while (err == MP_OKAY && !isPrime && i < failCount); + + if (err == MP_OKAY && !isPrime) + err = PRIME_GEN_E; + + /* make q */ + if (err == MP_OKAY) { + isPrime = 0; + i = 0; + do { +#ifdef SHOW_GEN + printf("."); + fflush(stdout); +#endif + /* generate value */ + err = wc_RNG_GenerateBlock(rng, q, qSz); + if (err == 0) { + /* prime lower bound has the MSB set, set it in candidate */ + q[0] |= 0x80; + /* make candidate odd */ + q[qSz-1] |= 0x01; + } + + if (err == MP_OKAY) + err = wc_CheckProbablePrime_ex(p, pSz, q, qSz, e, eSz, nSz, &isPrime, rng); + + i++; + } while (err == MP_OKAY && !isPrime && i < failCount); + } + + if (err == MP_OKAY && !isPrime) + err = PRIME_GEN_E; + + return err; +} + +int wc_DevCrypto_MakeRsaKey(RsaKey* key, int size, long e, WC_RNG* rng) +{ + int ret = 0; + struct crypt_kop kop; + int pSz, qSz, nSz, dSz, dpSz, dqSz, cSz; + byte *p = NULL; + byte *q = NULL; + byte *n = NULL; + byte *d = NULL; + byte *dp = NULL; + byte *dq = NULL; + byte *c = NULL; + int bSz = (size + WOLFSSL_BIT_SIZE - 1) / WOLFSSL_BIT_SIZE; + int inIdx = 0, outIdx = 0; + byte eBuf[8]; + int eBufSz; + + key->ctx.cfd = -1; + nSz = dSz = bSz; + cSz = pSz = qSz = dpSz = dqSz = bSz/2; + + ret = wc_DevCryptoCreate(&key->ctx, CRYPTO_ASYM_RSA_KEYGEN, NULL, 0); + if (ret == 0) { + p = (byte*)XMALLOC(pSz, key->heap, DYNAMIC_TYPE_TMP_BUFFER); + q = (byte*)XMALLOC(qSz, key->heap, DYNAMIC_TYPE_TMP_BUFFER); + dp = (byte*)XMALLOC(dpSz, key->heap, DYNAMIC_TYPE_TMP_BUFFER); + dq = (byte*)XMALLOC(dqSz, key->heap, DYNAMIC_TYPE_TMP_BUFFER); + c = (byte*)XMALLOC(cSz, key->heap, DYNAMIC_TYPE_TMP_BUFFER); + n = (byte*)XMALLOC(nSz, key->heap, DYNAMIC_TYPE_TMP_BUFFER); + d = (byte*)XMALLOC(dSz, key->heap, DYNAMIC_TYPE_TMP_BUFFER); + if (p == NULL || q == NULL || dp == NULL || dq == NULL || + n == NULL || d == NULL || c == NULL) { + ret = MEMORY_E; + } + } + + if (ret == 0) { + mp_init(&key->e); + mp_set_int(&key->e, (int)e); + eBufSz = mp_unsigned_bin_size(&key->e); + mp_to_unsigned_bin(&key->e, eBuf); + } + + if (ret == 0 && + GeneratePandQ(p, pSz, q, qSz, eBuf, eBufSz, size, rng) != MP_OKAY) { + WOLFSSL_MSG("Issue generating primes"); + ret = PRIME_GEN_E; + } + + if (ret == 0) { + XMEMSET(&kop, 0, sizeof(struct crypt_kop)); + kop.crk_op = CRK_RSA_KEYGEN; + kop.crk_pad1 = size; + + kop.crk_param[inIdx].crp_p = eBuf; + kop.crk_param[inIdx].crp_nbits = eBufSz * WOLFSSL_BIT_SIZE; + inIdx++; + + kop.crk_param[inIdx + outIdx].crp_p = p; + kop.crk_param[inIdx + outIdx].crp_nbits = pSz * WOLFSSL_BIT_SIZE; + outIdx++; + + kop.crk_param[inIdx + outIdx].crp_p = q; + kop.crk_param[inIdx + outIdx].crp_nbits = qSz * WOLFSSL_BIT_SIZE; + outIdx++; + + kop.crk_param[inIdx + outIdx].crp_p = n; + kop.crk_param[inIdx + outIdx].crp_nbits = nSz * WOLFSSL_BIT_SIZE; + outIdx++; + + kop.crk_param[inIdx + outIdx].crp_p = d; + kop.crk_param[inIdx + outIdx].crp_nbits = dSz * WOLFSSL_BIT_SIZE; + outIdx++; + + kop.crk_param[inIdx + outIdx].crp_p = dp; + kop.crk_param[inIdx + outIdx].crp_nbits = dpSz * WOLFSSL_BIT_SIZE; + outIdx++; + + kop.crk_param[inIdx + outIdx].crp_p = dq; + kop.crk_param[inIdx + outIdx].crp_nbits = dqSz * WOLFSSL_BIT_SIZE; + outIdx++; + + kop.crk_param[inIdx + outIdx].crp_p = c; + kop.crk_param[inIdx + outIdx].crp_nbits = cSz * WOLFSSL_BIT_SIZE; + outIdx++; + + kop.ses = key->ctx.sess.ses; + kop.crk_flags |= (CAAM_KEY_COLOR_BLACK << 8); + kop.crk_iparams = inIdx; + kop.crk_oparams = outIdx; + + if (ioctl(key->ctx.cfd, CIOCKEY, &kop)) { + #if defined(DEBUG_DEVCRYPTO) + perror("Error value with RSA keygen operation was "); + #endif + WOLFSSL_MSG("Error with call to ioctl"); + ret = WC_DEVCRYPTO_E; + } + } + wc_DevCryptoFree(&key->ctx); + + if (ret == 0) { + key->type = RSA_PRIVATE; + if (kop.crk_flags & (CAAM_KEY_COLOR_BLACK << 8)) { + key->blackKey = 1; + } + mp_read_unsigned_bin(&key->n, n, nSz); + #ifndef WOLFSSL_RSA_PUBLIC_ONLY + mp_read_unsigned_bin(&key->p, p, pSz); + mp_read_unsigned_bin(&key->q, q, qSz); + mp_read_unsigned_bin(&key->d, d, dSz); + #if defined(WOLFSSL_KEY_GEN) || defined(OPENSSL_EXTRA) || !defined(RSA_LOW_MEM) + mp_read_unsigned_bin(&key->dP, dp, dpSz); + mp_read_unsigned_bin(&key->dQ, dq, dqSz); + mp_read_unsigned_bin(&key->u, c, cSz); + #endif + #endif + } + + if (p != NULL) + XFREE(p, key->heap, DYNAMIC_TYPE_TMP_BUFFER); + if (q != NULL) + XFREE(q, key->heap, DYNAMIC_TYPE_TMP_BUFFER); + if (dp != NULL) + XFREE(dp, key->heap, DYNAMIC_TYPE_TMP_BUFFER); + if (dq != NULL) + XFREE(dq, key->heap, DYNAMIC_TYPE_TMP_BUFFER); + if (c != NULL) + XFREE(c, key->heap, DYNAMIC_TYPE_TMP_BUFFER); + if (n != NULL) + XFREE(n, key->heap, DYNAMIC_TYPE_TMP_BUFFER); + if (d != NULL) { + XFREE(d, key->heap, DYNAMIC_TYPE_TMP_BUFFER); + } + + (void)rng; + return ret; +} +#endif /* WOLFSSL_KEY_GEN */ + +void wc_DevCrypto_RsaFree(RsaKey* rsa) +{ + wc_DevCryptoFree(&rsa->ctx); +} + +#endif /* WOLFSSL_DEVCRYPTO */ + diff --git a/wolfcrypt/src/port/devcrypto/devcrypto_x25519.c b/wolfcrypt/src/port/devcrypto/devcrypto_x25519.c new file mode 100644 index 000000000..dc27eee0e --- /dev/null +++ b/wolfcrypt/src/port/devcrypto/devcrypto_x25519.c @@ -0,0 +1,107 @@ +/* devcrypto_x25519.c + * + * Copyright (C) 2006-2021 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + + +#ifdef HAVE_CONFIG_H + #include +#endif + +#include + +#if defined(WOLFSSL_DEVCRYPTO_CURVE25519) + +#include +#include +#include +#include + +const unsigned char qle[] = { + 0xED, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F +}; +const unsigned char a24le[] = { + 0x42, 0xdb, 0x01, 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 +}; + +/* mul mod on montgomery curve */ +int wc_DevCryptoCurve25519(byte* out, word32 outSz, const byte* k, + word32 kSz, const byte* a, word32 aSz, int endian) +{ + struct crypt_kop kop; + int inIdx = 0; + int outIdx = 0; + int ret; + WC_CRYPTODEV ctx; + const unsigned char* a24 = a24le; + const unsigned char* q = qle; + + ret = wc_DevCryptoCreate(&ctx, CRYPTO_ASYM_MUL_MOD, NULL, 0); + if (ret == 0) { + kop.crk_op = CRK_MUL_MOD; + kop.ses = ctx.sess.ses; + kop.crk_flags = 0; + if (endian == EC25519_LITTLE_ENDIAN) { + kop.crk_flags = CAAM_MUL_MOD_LE; + } + + kop.crk_param[inIdx].crp_p = (byte*)k; + kop.crk_param[inIdx].crp_nbits = kSz * WOLFSSL_BIT_SIZE; + inIdx++; + + kop.crk_param[inIdx].crp_p = (byte*)a; + kop.crk_param[inIdx].crp_nbits = aSz * WOLFSSL_BIT_SIZE; + inIdx++; + + kop.crk_param[inIdx].crp_p = (byte*)q; + kop.crk_param[inIdx].crp_nbits = CURVE25519_KEYSIZE * WOLFSSL_BIT_SIZE; + inIdx++; + + kop.crk_param[inIdx].crp_p = (byte*)a24; + kop.crk_param[inIdx].crp_nbits = CURVE25519_KEYSIZE * WOLFSSL_BIT_SIZE; + inIdx++; + + /* add output buffer */ + kop.crk_param[inIdx + outIdx].crp_p = out; + kop.crk_param[inIdx + outIdx].crp_nbits = outSz * WOLFSSL_BIT_SIZE; + outIdx++; + + kop.crk_iparams = inIdx; + kop.crk_oparams = outIdx; + + if (ioctl(ctx.cfd, CIOCKEY, &kop)) { + #if defined(DEBUG_DEVCRYPTO) + perror("Error value with Curve25519 operation was "); + #endif + WOLFSSL_MSG("Error with call to ioctl"); + ret = WC_DEVCRYPTO_E; + } + wc_DevCryptoFree(&ctx); + } + + return ret; +} +#endif /* WOLFSSL_DEVCRYPTO_CURVE25519 */ + diff --git a/wolfcrypt/src/port/devcrypto/wc_devcrypto.c b/wolfcrypt/src/port/devcrypto/wc_devcrypto.c index 23a613932..9315a1546 100644 --- a/wolfcrypt/src/port/devcrypto/wc_devcrypto.c +++ b/wolfcrypt/src/port/devcrypto/wc_devcrypto.c @@ -28,16 +28,55 @@ #if defined(WOLFSSL_DEVCRYPTO) +static volatile int fd; + #include #include #include +int wc_DevCryptoInit(void) +{ + /* create descriptor */ + if ((fd = open("/dev/crypto", O_RDWR, 0)) < 0) { + WOLFSSL_MSG("Error opening /dev/crypto is cryptodev module loaded?"); + return WC_DEVCRYPTO_E; + } + +#if defined(CIOCASYMFEAT) && defined(WOLFSSL_DEVCRYPTO_RSA) + { + word32 asymAva = 0; + + if (ioctl(fd, CIOCASYMFEAT, &asymAva) == -1) { + WOLFSSL_MSG("Error checking which asym. operations are available"); + close(fd); + return WC_DEVCRYPTO_E; + } + + if ((asymAva & CRF_RSA_PUBLIC) == 0) { + WOLFSSL_MSG("CRK_RSA_PUBLIC is not available"); + close(fd); + return WC_DEVCRYPTO_E; + } + } +#endif + + return 0; +} + + +void wc_DevCryptoCleanup(void) +{ + close(fd); +} + + /* sets up a context for talking to /dev/crypto * return 0 on success */ int wc_DevCryptoCreate(WC_CRYPTODEV* ctx, int type, byte* key, word32 keySz) { - int fd; - int isHash = 0; /* flag for if hashing algorithm */ +#if defined(CIOCGSESSINFO) && defined(DEBUG_DEVCRYPTO) + struct session_info_op sesInfo; +#endif if (ctx == NULL) { return BAD_FUNC_ARG; @@ -45,10 +84,24 @@ int wc_DevCryptoCreate(WC_CRYPTODEV* ctx, int type, byte* key, word32 keySz) /* sanity check on session type before creating descriptor */ XMEMSET(ctx, 0, sizeof(WC_CRYPTODEV)); + + /* clone the master fd */ + if (ioctl(fd, CRIOGET, &ctx->cfd) != 0) { + WOLFSSL_MSG("Error cloning fd"); + return WC_DEVCRYPTO_E; + } + + if (fcntl(ctx->cfd, F_SETFD, 1) == -1) { + WOLFSSL_MSG("Error setting F_SETFD with fcntl"); + (void)close(ctx->cfd); + return WC_DEVCRYPTO_E; + } + + /* set up session */ switch (type) { case CRYPTO_SHA1: case CRYPTO_SHA2_256: - isHash = 1; + ctx->sess.mac = type; break; #ifndef NO_AES @@ -56,44 +109,75 @@ int wc_DevCryptoCreate(WC_CRYPTODEV* ctx, int type, byte* key, word32 keySz) case CRYPTO_AES_ECB: case CRYPTO_AES_GCM: case CRYPTO_AES_CBC: - isHash = 0; + ctx->sess.cipher = type; + ctx->sess.key = (void*)key; + ctx->sess.keylen = keySz; break; #endif + case CRYPTO_MD5_HMAC: + case CRYPTO_SHA1_HMAC: + case CRYPTO_SHA2_256_HMAC: + case CRYPTO_SHA2_384_HMAC: + case CRYPTO_SHA2_512_HMAC: + ctx->sess.cipher = 0; + ctx->sess.mac = type; + ctx->sess.mackey = (uint8_t*)key; + ctx->sess.mackeylen = keySz; + break; + + #if defined(WOLFSSL_DEVCRYPTO_ECDSA) + #endif /* WOLFSSL_DEVCRYPTO_ECDSA */ + + #if defined(WOLFSSL_DEVCRYPTO_RSA) + case CRYPTO_ASYM_RSA_KEYGEN: + case CRYPTO_ASYM_RSA_PRIVATE: + case CRYPTO_ASYM_RSA_PUBLIC: + ctx->sess.acipher = type; + break; + #endif + + #if defined(WOLFSSL_DEVCRYPTO_ECDSA) + case CRYPTO_ASYM_ECDSA_SIGN: + case CRYPTO_ASYM_ECDSA_VERIFY: + case CRYPTO_ASYM_ECC_KEYGEN: + case CRYPTO_ASYM_ECC_ECDH: + ctx->sess.acipher = type; + break; + #endif + + #if defined(WOLFSSL_DEVCRYPTO_CURVE25519) + case CRYPTO_ASYM_MUL_MOD: + ctx->sess.acipher = type; + break; + #endif /* WOLFSSL_DEVCRYPTO_CURVE25519 */ + default: WOLFSSL_MSG("Unknown / Unimplemented algorithm type"); + (void)close(ctx->cfd); return BAD_FUNC_ARG; } - /* create descriptor */ - if ((fd = open("/dev/crypto", O_RDWR, 0)) < 0) { - WOLFSSL_MSG("Error opening /dev/crypto is cryptodev module loaded?"); - return WC_DEVCRYPTO_E; - } - if (fcntl(fd, F_SETFD, 1) == -1) { - WOLFSSL_MSG("Error setting F_SETFD with fcntl"); - (void)close(fd); - return WC_DEVCRYPTO_E; - } - - /* set up session */ - ctx->cfd = fd; - - if (isHash) { - ctx->sess.mac = type; - } - else { - ctx->sess.cipher = type; - ctx->sess.key = (void*)key; - ctx->sess.keylen = keySz; - } if (ioctl(ctx->cfd, CIOCGSESSION, &ctx->sess)) { - (void)close(fd); + #if defined(DEBUG_DEVCRYPTO) + perror("CIOGSESSION error "); + #endif + (void)close(ctx->cfd); WOLFSSL_MSG("Error starting cryptodev session"); return WC_DEVCRYPTO_E; } +#if defined(CIOCGSESSINFO) && defined(DEBUG_DEVCRYPTO) + sesInfo.ses = ctx->sess.ses; + if (ioctl(ctx->cfd, CIOCGSESSINFO, &sesInfo)) { + (void)close(ctx->cfd); + WOLFSSL_MSG("Error getting session info"); + return WC_DEVCRYPTO_E; + } + printf("Using %s with driver %s\n", sesInfo.hash_info.cra_name, + sesInfo.hash_info.cra_driver_name); +#endif (void)key; (void)keySz; @@ -109,13 +193,14 @@ void wc_DevCryptoFree(WC_CRYPTODEV* ctx) WOLFSSL_MSG("Error stopping cryptodev session"); } (void)close(ctx->cfd); + ctx->cfd = -1; } } /* setup crypt_op structure */ void wc_SetupCrypt(struct crypt_op* crt, WC_CRYPTODEV* dev, - byte* src, int srcSz, byte* dst, byte* dig, int flag) + byte* src, int srcSz, byte* dst, byte* dig, int flag, int op) { XMEMSET(crt, 0, sizeof(struct crypt_op)); @@ -123,6 +208,7 @@ void wc_SetupCrypt(struct crypt_op* crt, WC_CRYPTODEV* dev, crt->src = src; crt->len = srcSz; crt->dst = dst; + crt->op = op; crt->mac = dig; crt->flags = flag; } @@ -163,5 +249,6 @@ void wc_SetupCryptAead(struct crypt_auth_op* crt, WC_CRYPTODEV* dev, crt->tag = authTag; crt->tag_len = authTagSz; } + #endif /* WOLFSSL_DEVCRYPTO */ diff --git a/wolfcrypt/src/random.c b/wolfcrypt/src/random.c index ea9feea46..fbd91d468 100644 --- a/wolfcrypt/src/random.c +++ b/wolfcrypt/src/random.c @@ -2384,7 +2384,8 @@ int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz) return 0; } -#elif (defined(WOLFSSL_IMX6_CAAM) || defined(WOLFSSL_IMX6_CAAM_RNG)) +#elif (defined(WOLFSSL_IMX6_CAAM) || defined(WOLFSSL_IMX6_CAAM_RNG) || \ + defined(WOLFSSL_SECO_CAAM)) #include diff --git a/wolfcrypt/src/rsa.c b/wolfcrypt/src/rsa.c index 6da4c740d..e86dd1f17 100644 --- a/wolfcrypt/src/rsa.c +++ b/wolfcrypt/src/rsa.c @@ -689,6 +689,13 @@ int wc_CheckRsaKey(RsaKey* key) #endif int ret = 0; +#ifdef WOLFSSL_CAAM + /* can not perform these checks on an encrypted key */ + if (key->blackKey != 0) { + return 0; + } +#endif + #ifdef WOLFSSL_SMALL_STACK rng = (WC_RNG*)XMALLOC(sizeof(WC_RNG), NULL, DYNAMIC_TYPE_RNG); if (rng != NULL) diff --git a/wolfcrypt/src/sha256.c b/wolfcrypt/src/sha256.c index 92dd5a9fd..c893b05e4 100644 --- a/wolfcrypt/src/sha256.c +++ b/wolfcrypt/src/sha256.c @@ -213,6 +213,15 @@ static int InitSha256(wc_Sha256* sha256) #ifdef WOLFSSL_HASH_FLAGS sha256->flags = 0; #endif +#ifdef WOLFSSL_HASH_KEEP + sha256->msg = NULL; + sha256->len = 0; + sha256->used = 0; +#endif + +#ifdef WOLF_CRYPTO_CB + sha256->devId = wc_CryptoCb_DefaultDevID(); +#endif return ret; } @@ -778,6 +787,10 @@ static int InitSha256(wc_Sha256* sha256) if (sha256 == NULL) return BAD_FUNC_ARG; + ret = InitSha256(sha256); + if (ret != 0) + return ret; + sha256->heap = heap; #ifdef WOLF_CRYPTO_CB sha256->devId = devId; @@ -787,10 +800,6 @@ static int InitSha256(wc_Sha256* sha256) sha256->W = NULL; #endif - ret = InitSha256(sha256); - if (ret != 0) - return ret; - #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_SHA256) ret = wolfAsync_DevCtxInit(&sha256->asyncDev, WOLFSSL_ASYNC_MARKER_SHA256, sha256->heap, devId); @@ -1500,6 +1509,12 @@ static int InitSha256(wc_Sha256* sha256) #ifdef WOLFSSL_HASH_FLAGS sha224->flags = 0; #endif + #ifdef WOLFSSL_HASH_KEEP + sha224->msg = NULL; + sha224->len = 0; + sha224->used = 0; + #endif + return ret; } @@ -1586,7 +1601,12 @@ static int InitSha256(wc_Sha256* sha256) int wc_InitSha224(wc_Sha224* sha224) { - return wc_InitSha224_ex(sha224, NULL, INVALID_DEVID); + int devId = INVALID_DEVID; + + #ifdef WOLF_CRYPTO_CB + devId = wc_CryptoCb_DefaultDevID(); + #endif + return wc_InitSha224_ex(sha224, NULL, devId); } #if !defined(WOLFSSL_HAVE_PSA) || defined(WOLFSSL_PSA_NO_HASH) @@ -1621,7 +1641,12 @@ static int InitSha256(wc_Sha256* sha256) int wc_InitSha256(wc_Sha256* sha256) { - return wc_InitSha256_ex(sha256, NULL, INVALID_DEVID); + int devId = INVALID_DEVID; + +#ifdef WOLF_CRYPTO_CB + devId = wc_CryptoCb_DefaultDevID(); +#endif + return wc_InitSha256_ex(sha256, NULL, devId); } #if !defined(WOLFSSL_HAVE_PSA) || defined(WOLFSSL_PSA_NO_HASH) @@ -1663,7 +1688,8 @@ void wc_Sha256Free(wc_Sha256* sha256) (defined(WOLFSSL_RENESAS_TSIP_CRYPT) && \ !defined(NO_WOLFSSL_RENESAS_TSIP_CRYPT_HASH)) || \ (defined(WOLFSSL_RENESAS_SCEPROTECT) && \ - !defined(NO_WOLFSSL_RENESAS_SCEPROTECT_HASH)) + !defined(NO_WOLFSSL_RENESAS_SCEPROTECT_HASH)) || \ + defined(WOLFSSL_HASH_KEEP) if (sha256->msg != NULL) { XFREE(sha256->msg, sha256->heap, DYNAMIC_TYPE_TMP_BUFFER); @@ -1679,6 +1705,26 @@ void wc_Sha256Free(wc_Sha256* sha256) } #endif /* !defined(WOLFSSL_HAVE_PSA) || defined(WOLFSSL_PSA_NO_HASH) */ +#ifdef WOLFSSL_HASH_KEEP +/* Some hardware have issues with update, this function stores the data to be + * hashed into an array. Once ready, the Final operation is called on all of the + * data to be hashed at once. + * returns 0 on success + */ +int wc_Sha256_Grow(wc_Sha256* sha256, const byte* in, int inSz) +{ + return _wc_Hash_Grow(&(sha256->msg), &(sha256->used), &(sha256->len), in, + inSz, sha256->heap); +} +#ifdef WOLFSSL_SHA224 +int wc_Sha224_Grow(wc_Sha224* sha224, const byte* in, int inSz) +{ + return _wc_Hash_Grow(&(sha224->msg), &(sha224->used), &(sha224->len), in, + inSz, sha224->heap); +} +#endif /* WOLFSSL_SHA224 */ +#endif /* WOLFSSL_HASH_KEEP */ + #endif /* !WOLFSSL_TI_HASH */ #endif /* HAVE_FIPS */ @@ -1698,6 +1744,7 @@ void wc_Sha256Free(wc_Sha256* sha256) int ret; wc_Sha224 tmpSha224; + wc_InitSha224(&tmpSha224); if (sha224 == NULL || hash == NULL) return BAD_FUNC_ARG; @@ -1731,6 +1778,15 @@ void wc_Sha256Free(wc_Sha256* sha256) #ifdef WOLFSSL_HASH_FLAGS dst->flags |= WC_HASH_FLAG_ISCOPY; #endif + #if defined(WOLFSSL_HASH_KEEP) + if (src->msg != NULL) { + dst->msg = (byte*)XMALLOC(src->len, dst->heap, + DYNAMIC_TYPE_TMP_BUFFER); + if (dst->msg == NULL) + return MEMORY_E; + XMEMCPY(dst->msg, src->msg, src->len); + } + #endif return ret; } @@ -1846,6 +1902,14 @@ int wc_Sha256Copy(wc_Sha256* src, wc_Sha256* dst) #ifdef WOLFSSL_HASH_FLAGS dst->flags |= WC_HASH_FLAG_ISCOPY; #endif +#if defined(WOLFSSL_HASH_KEEP) + if (src->msg != NULL) { + dst->msg = (byte*)XMALLOC(src->len, dst->heap, DYNAMIC_TYPE_TMP_BUFFER); + if (dst->msg == NULL) + return MEMORY_E; + XMEMCPY(dst->msg, src->msg, src->len); + } +#endif return ret; } diff --git a/wolfcrypt/src/sha512.c b/wolfcrypt/src/sha512.c index 84149da26..f6c863665 100644 --- a/wolfcrypt/src/sha512.c +++ b/wolfcrypt/src/sha512.c @@ -597,6 +597,11 @@ static int InitSha512_Family(wc_Sha512* sha512, void* heap, int devId, (defined(HAVE_INTEL_AVX1) || defined(HAVE_INTEL_AVX2)) Sha512_SetTransform(); #endif +#ifdef WOLFSSL_HASH_KEEP + sha512->msg = NULL; + sha512->len = 0; + sha512->used = 0; +#endif #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_SHA512) ret = wolfAsync_DevCtxInit(&sha512->asyncDev, @@ -1138,7 +1143,12 @@ int wc_Sha512Final(wc_Sha512* sha512, byte* hash) #if !defined(WOLFSSL_SE050) || !defined(WOLFSSL_SE050_HASH) int wc_InitSha512(wc_Sha512* sha512) { - return wc_InitSha512_ex(sha512, NULL, INVALID_DEVID); + int devId = INVALID_DEVID; + +#ifdef WOLF_CRYPTO_CB + devId = wc_CryptoCb_DefaultDevID(); +#endif + return wc_InitSha512_ex(sha512, NULL, devId); } void wc_Sha512Free(wc_Sha512* sha512) @@ -1157,6 +1167,13 @@ void wc_Sha512Free(wc_Sha512* sha512) KcapiHashFree(&sha512->kcapi); #endif +#if defined(WOLFSSL_HASH_KEEP) + if (sha512->msg != NULL) { + XFREE(sha512->msg, sha512->heap, DYNAMIC_TYPE_TMP_BUFFER); + sha512->msg = NULL; + } +#endif + #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_SHA512) wolfAsync_DevCtxFree(&sha512->asyncDev, WOLFSSL_ASYNC_MARKER_SHA512); #endif /* WOLFSSL_ASYNC_CRYPT */ @@ -1304,6 +1321,11 @@ static int InitSha384(wc_Sha384* sha384) #ifdef WOLFSSL_HASH_FLAGS sha384->flags = 0; #endif +#ifdef WOLFSSL_HASH_KEEP + sha384->msg = NULL; + sha384->len = 0; + sha384->used = 0; +#endif return 0; } @@ -1429,7 +1451,12 @@ int wc_InitSha384_ex(wc_Sha384* sha384, void* heap, int devId) int wc_InitSha384(wc_Sha384* sha384) { - return wc_InitSha384_ex(sha384, NULL, INVALID_DEVID); + int devId = INVALID_DEVID; + +#ifdef WOLF_CRYPTO_CB + devId = wc_CryptoCb_DefaultDevID(); +#endif + return wc_InitSha384_ex(sha384, NULL, devId); } void wc_Sha384Free(wc_Sha384* sha384) @@ -1448,6 +1475,12 @@ void wc_Sha384Free(wc_Sha384* sha384) KcapiHashFree(&sha384->kcapi); #endif +#if defined(WOLFSSL_HASH_KEEP) + if (sha384->msg != NULL) { + XFREE(sha384->msg, sha384->heap, DYNAMIC_TYPE_TMP_BUFFER); + sha384->msg = NULL; + } +#endif #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_SHA384) wolfAsync_DevCtxFree(&sha384->asyncDev, WOLFSSL_ASYNC_MARKER_SHA384); @@ -1529,6 +1562,14 @@ int wc_Sha512Copy(wc_Sha512* src, wc_Sha512* dst) #ifdef WOLFSSL_HASH_FLAGS dst->flags |= WC_HASH_FLAG_ISCOPY; #endif +#if defined(WOLFSSL_HASH_KEEP) + if (src->msg != NULL) { + dst->msg = (byte*)XMALLOC(src->len, dst->heap, DYNAMIC_TYPE_TMP_BUFFER); + if (dst->msg == NULL) + return MEMORY_E; + XMEMCPY(dst->msg, src->msg, src->len); + } +#endif return ret; } @@ -1747,6 +1788,14 @@ int wc_Sha384Copy(wc_Sha384* src, wc_Sha384* dst) #ifdef WOLFSSL_HASH_FLAGS dst->flags |= WC_HASH_FLAG_ISCOPY; #endif +#if defined(WOLFSSL_HASH_KEEP) + if (src->msg != NULL) { + dst->msg = (byte*)XMALLOC(src->len, dst->heap, DYNAMIC_TYPE_TMP_BUFFER); + if (dst->msg == NULL) + return MEMORY_E; + XMEMCPY(dst->msg, src->msg, src->len); + } +#endif return ret; } @@ -1772,4 +1821,23 @@ int wc_Sha384GetFlags(wc_Sha384* sha384, word32* flags) #endif /* WOLFSSL_SHA384 */ +#ifdef WOLFSSL_HASH_KEEP +/* Some hardware have issues with update, this function stores the data to be + * hashed into an array. Once ready, the Final operation is called on all of the + * data to be hashed at once. + * returns 0 on success + */ +int wc_Sha512_Grow(wc_Sha512* sha512, const byte* in, int inSz) +{ + return _wc_Hash_Grow(&(sha512->msg), &(sha512->used), &(sha512->len), in, + inSz, sha512->heap); +} +#ifdef WOLFSSL_SHA384 +int wc_Sha384_Grow(wc_Sha384* sha384, const byte* in, int inSz) +{ + return _wc_Hash_Grow(&(sha384->msg), &(sha384->used), &(sha384->len), in, + inSz, sha384->heap); +} +#endif /* WOLFSSL_SHA384 */ +#endif /* WOLFSSL_HASH_KEEP */ #endif /* WOLFSSL_SHA512 || WOLFSSL_SHA384 */ diff --git a/wolfcrypt/src/wc_port.c b/wolfcrypt/src/wc_port.c index bd3a27d0c..ad4a1569c 100644 --- a/wolfcrypt/src/wc_port.c +++ b/wolfcrypt/src/wc_port.c @@ -75,10 +75,13 @@ #endif #if defined(WOLFSSL_IMX6_CAAM) || defined(WOLFSSL_IMX6_CAAM_RNG) || \ - defined(WOLFSSL_IMX6UL_CAAM) || defined(WOLFSSL_IMX6_CAAM_BLOB) + defined(WOLFSSL_IMX6UL_CAAM) || defined(WOLFSSL_IMX6_CAAM_BLOB) || \ + defined(WOLFSSL_SECO_CAAM) #include #endif - +#if defined(WOLFSSL_DEVCRYPTO) + #include +#endif #ifdef WOLFSSL_IMXRT_DCP #include #endif @@ -305,8 +308,15 @@ int wolfCrypt_Init(void) } #endif +#if defined(WOLFSSL_DEVCRYPTO) + if ((ret = wc_DevCryptoInit()) != 0) { + return ret; + } +#endif + #if defined(WOLFSSL_IMX6_CAAM) || defined(WOLFSSL_IMX6_CAAM_RNG) || \ - defined(WOLFSSL_IMX6UL_CAAM) || defined(WOLFSSL_IMX6_CAAM_BLOB) + defined(WOLFSSL_IMX6UL_CAAM) || defined(WOLFSSL_IMX6_CAAM_BLOB) || \ + defined(WOLFSSL_SECO_CAAM) if ((ret = wc_caamInit()) != 0) { return ret; } @@ -390,7 +400,8 @@ int wolfCrypt_Cleanup(void) #endif #if defined(WOLFSSL_IMX6_CAAM) || defined(WOLFSSL_IMX6_CAAM_RNG) || \ - defined(WOLFSSL_IMX6_CAAM_BLOB) + defined(WOLFSSL_IMX6_CAAM_BLOB) || \ + defined(WOLFSSL_SECO_CAAM) wc_caamFree(); #endif #if defined(WOLFSSL_CRYPTOCELL) @@ -402,6 +413,9 @@ int wolfCrypt_Cleanup(void) #if defined(WOLFSSL_RENESAS_TSIP_CRYPT) tsip_Close(); #endif + #if defined(WOLFSSL_DEVCRYPTO) + wc_DevCryptoCleanup(); + #endif #if defined(WOLFSSL_DSP) && !defined(WOLFSSL_DSP_BUILD) rpcmem_deinit(); wolfSSL_CleanupHandle(); diff --git a/wolfcrypt/test/test.c b/wolfcrypt/test/test.c index 0ab766a37..9fb993b3b 100644 --- a/wolfcrypt/test/test.c +++ b/wolfcrypt/test/test.c @@ -289,7 +289,7 @@ #if defined(OPENSSL_EXTRA) || defined(DEBUG_WOLFSSL_VERBOSE) #include #endif -#ifdef WOLFSSL_IMX6_CAAM_BLOB +#ifdef WOLFSSL_CAAM #include #endif #ifdef WOLF_CRYPTO_CB @@ -349,13 +349,18 @@ #define NO_INTM_HASH_TEST #endif +#if defined(WOLFSSL_RENESAS_TSIP) || defined(WOLFSSL_RENESAS_SCEPROTECT) || \ + defined(WOLFSSL_SECO_CAAM) + #define HASH_SIZE_LIMIT +#endif + #if defined(WOLFSSL_CERT_GEN) && (!defined(NO_RSA) || defined(HAVE_ECC)) || \ (defined(WOLFSSL_TEST_CERT) && (defined(HAVE_ED25519) || defined(HAVE_ED448))) static void initDefaultName(void); #endif /* for async devices */ -#ifdef WOLFSSL_QNX_CAAM +#ifdef WOLFSSL_CAAM_DEVID static int devId = WOLFSSL_CAAM_DEVID; #else static int devId = INVALID_DEVID; @@ -2735,7 +2740,7 @@ WOLFSSL_TEST_SUBROUTINE int sha256_test(void) /* BEGIN LARGE HASH TEST */ { byte large_input[1024]; -#if defined(WOLFSSL_RENESAS_TSIP_CRYPT) || defined(WOLFSSL_RENESAS_SCEPROTECT) +#ifdef HASH_SIZE_LIMIT const char* large_digest = "\xa4\x75\x9e\x7a\xa2\x03\x38\x32\x88\x66\xa2\xea\x17\xea\xf8\xc7" "\xfe\x4e\xc6\xbb\xe3\xbb\x71\xce\xe7\xdf\x7c\x04\x61\xb3\xc2\x2f"; @@ -2747,7 +2752,7 @@ WOLFSSL_TEST_SUBROUTINE int sha256_test(void) for (i = 0; i < (int)sizeof(large_input); i++) { large_input[i] = (byte)(i & 0xFF); } -#if defined(WOLFSSL_RENESAS_TSIP) || defined(WOLFSSL_RENESAS_SCEPROTECT) +#ifdef HASH_SIZE_LIMIT times = 20; #else times = 100; @@ -2855,16 +2860,28 @@ WOLFSSL_TEST_SUBROUTINE int sha512_test(void) /* BEGIN LARGE HASH TEST */ { byte large_input[1024]; +#ifdef HASH_SIZE_LIMIT + const char* large_digest = + "\x30\x9B\x96\xA6\xE9\x43\x78\x30\xA3\x71\x51\x61\xC1\xEB\xE1\xBE" + "\xC8\xA5\xF9\x13\x5A\xD6\x6D\x9E\x46\x31\x31\x67\x8D\xE2\xC0\x0B" + "\x2A\x1A\x03\xE1\xF3\x48\xA7\x33\xBD\x49\xF8\xFF\xF1\xC2\xC2\x95" + "\xCB\xF0\xAF\x87\x61\x85\x58\x63\x6A\xCA\x70\x9C\x8B\x83\x3F\x5D"; +#else const char* large_digest = "\x5a\x1f\x73\x90\xbd\x8c\xe4\x63\x54\xce\xa0\x9b\xef\x32\x78\x2d" "\x2e\xe7\x0d\x5e\x2f\x9d\x15\x1b\xdd\x2d\xde\x65\x0c\x7b\xfa\x83" "\x5e\x80\x02\x13\x84\xb8\x3f\xff\x71\x62\xb5\x09\x89\x63\xe1\xdc" "\xa5\xdc\xfc\xfa\x9d\x1a\x4d\xc0\xfa\x3a\x14\xf6\x01\x51\x90\xa4"; +#endif for (i = 0; i < (int)sizeof(large_input); i++) { large_input[i] = (byte)(i & 0xFF); } +#ifdef HASH_SIZE_LIMIT + times = 20; +#else times = 100; +#endif for (i = 0; i < times; ++i) { ret = wc_Sha512Update(&sha, (byte*)large_input, (word32)sizeof(large_input)); @@ -2971,15 +2988,26 @@ WOLFSSL_TEST_SUBROUTINE int sha384_test(void) /* BEGIN LARGE HASH TEST */ { byte large_input[1024]; +#ifdef HASH_SIZE_LIMIT + const char* large_digest = + "\xB5\xAD\x66\x6F\xD9\x58\x5E\x68\xDD\x5E\x30\xD3\x95\x72\x33\xA4" + "\xE9\x4B\x99\x3A\xEF\xF8\xE1\xBF\x1F\x05\x32\xAA\x16\x00\x82\xEC" + "\x15\xDA\xF2\x75\xEE\xE9\x06\xAF\x52\x8A\x5C\xEF\x72\x81\x80\xD6"; +#else const char* large_digest = "\x37\x01\xdb\xff\x1e\x40\x4f\xe1\xe2\xea\x0b\x40\xbb\x3b\x39\x9a" "\xcc\xe8\x44\x8e\x7e\xe5\x64\xb5\x6b\x7f\x56\x64\xa7\x2b\x84\xe3" "\xc5\xd7\x79\x03\x25\x90\xf7\xa4\x58\xcb\x97\xa8\x8b\xb1\xa4\x81"; +#endif for (i = 0; i < (int)sizeof(large_input); i++) { large_input[i] = (byte)(i & 0xFF); } +#ifdef HASH_SIZE_LIMIT + times = 20; +#else times = 100; +#endif for (i = 0; i < times; ++i) { ret = wc_Sha384Update(&sha, (byte*)large_input, (word32)sizeof(large_input)); @@ -8449,6 +8477,95 @@ static int aes_cbc_test(void) } #endif +#if defined(HAVE_AES_ECB) && !defined(HAVE_FIPS) && !defined(HAVE_SELFTEST) +static int aesecb_test(void) +{ +#ifdef WOLFSSL_SMALL_STACK + Aes *enc = (Aes *)XMALLOC(sizeof *enc, HEAP_HINT, DYNAMIC_TYPE_AES); +#else + Aes enc[1]; +#endif + byte cipher[AES_BLOCK_SIZE * 4]; +#ifdef HAVE_AES_DECRYPT +#ifdef WOLFSSL_SMALL_STACK + Aes *dec = (Aes *)XMALLOC(sizeof *dec, HEAP_HINT, DYNAMIC_TYPE_AES); +#else + Aes dec[1]; +#endif + byte plain [AES_BLOCK_SIZE * 4]; +#endif /* HAVE_AES_DECRYPT */ + int ret = 0; + +#if defined(WOLFSSL_AES_256) + { + WOLFSSL_SMALL_STACK_STATIC const byte niPlain[] = + { + 0x6b,0xc1,0xbe,0xe2,0x2e,0x40,0x9f,0x96, + 0xe9,0x3d,0x7e,0x11,0x73,0x93,0x17,0x2a + }; + + WOLFSSL_SMALL_STACK_STATIC const byte niCipher[] = + { + 0xf3,0xee,0xd1,0xbd,0xb5,0xd2,0xa0,0x3c, + 0x06,0x4b,0x5a,0x7e,0x3d,0xb1,0x81,0xf8 + }; + + WOLFSSL_SMALL_STACK_STATIC const byte niKey[] = + { + 0x60,0x3d,0xeb,0x10,0x15,0xca,0x71,0xbe, + 0x2b,0x73,0xae,0xf0,0x85,0x7d,0x77,0x81, + 0x1f,0x35,0x2c,0x07,0x3b,0x61,0x08,0xd7, + 0x2d,0x98,0x10,0xa3,0x09,0x14,0xdf,0xf4 + }; + + if (wc_AesInit(enc, HEAP_HINT, devId) != 0) + ERROR_OUT(-5900, out); + #if defined(HAVE_AES_DECRYPT) + if (wc_AesInit(dec, HEAP_HINT, devId) != 0) + ERROR_OUT(-5901, out); + #endif + + XMEMSET(cipher, 0, AES_BLOCK_SIZE); + ret = wc_AesSetKey(enc, niKey, sizeof(niKey), cipher, AES_ENCRYPTION); + if (ret != 0) + ERROR_OUT(-5943, out); + if (wc_AesEcbEncrypt(enc, cipher, niPlain, AES_BLOCK_SIZE) != 0) + ERROR_OUT(-5950, out); + if (XMEMCMP(cipher, niCipher, AES_BLOCK_SIZE) != 0) + ERROR_OUT(-5944, out); + + XMEMSET(plain, 0, AES_BLOCK_SIZE); + ret = wc_AesSetKey(dec, niKey, sizeof(niKey), plain, AES_DECRYPTION); + if (ret != 0) + ERROR_OUT(-5945, out); + if (wc_AesEcbDecrypt(dec, plain, niCipher, AES_BLOCK_SIZE) != 0) + ERROR_OUT(-5951, out); + wc_AesEcbDecrypt(dec, plain, niCipher, AES_BLOCK_SIZE); + if (XMEMCMP(plain, niPlain, AES_BLOCK_SIZE) != 0) + ERROR_OUT(-5946, out); + } + + wc_AesFree(enc); +#ifdef HAVE_AES_DECRYPT + wc_AesFree(dec); +#endif + + out: +#ifdef WOLFSSL_SMALL_STACK + if (enc) + XFREE(enc, HEAP_HINT, DYNAMIC_TYPE_AES); +#ifdef HAVE_AES_DECRYPT + if (dec) + XFREE(dec, HEAP_HINT, DYNAMIC_TYPE_AES); +#endif +#endif +#endif /* WOLFSSL_AES_256 */ + + return ret; +} +#endif /* HAVE_AES_ECB */ + + WOLFSSL_TEST_SUBROUTINE int aes_test(void) { #if defined(HAVE_AES_CBC) || defined(WOLFSSL_AES_COUNTER) || defined(WOLFSSL_AES_DIRECT) @@ -9079,6 +9196,12 @@ WOLFSSL_TEST_SUBROUTINE int aes_test(void) #endif #endif +#if defined(HAVE_AES_ECB) && !defined(HAVE_FIPS) && !defined(HAVE_SELFTEST) + ret = aesecb_test(); + if (ret != 0) + goto out; +#endif + out: #if defined(HAVE_AES_CBC) || defined(WOLFSSL_AES_COUNTER) || defined(WOLFSSL_AES_DIRECT) @@ -22096,7 +22219,8 @@ static int ecc_test_make_pub(WC_RNG* rng) /* create a new key since above test for loading key is not supported */ #if defined(WOLFSSL_CRYPTOCELL) || defined(NO_ECC256) || \ - defined(WOLFSSL_QNX_CAAM) || defined(WOLFSSL_SE050) + defined(WOLFSSL_QNX_CAAM) || defined(WOLFSSL_SE050) || \ + defined(WOLFSSL_SECO_CAAM) ret = wc_ecc_make_key(rng, ECC_KEYGEN_SIZE, key); if (ret != 0) { ERROR_OUT(-9861, done); @@ -39729,6 +39853,36 @@ static int myCryptoDevCb(int devIdArg, wc_CryptoInfo* info, void* ctx) } } #endif /* HAVE_AES_CBC */ + #if defined(HAVE_AES_ECB) && !defined(HAVE_FIPS) && !defined(HAVE_SELFTEST) + if (info->cipher.type == WC_CIPHER_AES_ECB) { + if (info->cipher.enc) { + /* set devId to invalid, so software is used */ + info->cipher.aesecb.aes->devId = INVALID_DEVID; + + ret = wc_AesEcbEncrypt( + info->cipher.aesecb.aes, + info->cipher.aesecb.out, + info->cipher.aesecb.in, + info->cipher.aesecb.sz); + + /* reset devId */ + info->cipher.aesecb.aes->devId = devIdArg; + } + else { + /* set devId to invalid, so software is used */ + info->cipher.aesecb.aes->devId = INVALID_DEVID; + + ret = wc_AesEcbDecrypt( + info->cipher.aesecb.aes, + info->cipher.aesecb.out, + info->cipher.aesecb.in, + info->cipher.aesecb.sz); + + /* reset devId */ + info->cipher.aesecb.aes->devId = devIdArg; + } + } + #endif /* HAVE_AES_CBC */ #if defined(HAVE_AESCCM) && defined(WOLFSSL_AES_128) if (info->cipher.type == WC_CIPHER_AES_CCM) { if (info->cipher.enc) { diff --git a/wolfssl/openssl/sha.h b/wolfssl/openssl/sha.h index 6f787bff9..17af1ed2b 100644 --- a/wolfssl/openssl/sha.h +++ b/wolfssl/openssl/sha.h @@ -44,6 +44,9 @@ typedef struct WOLFSSL_SHA_CTX { #else void* holder[(112 + WC_ASYNC_DEV_SIZE) / sizeof(void*)]; #endif + #if defined(WOLFSSL_DEVCRYPTO_HASH) || defined(WOLFSSL_HASH_KEEP) + void* keephash_holder[sizeof(void*) + (2 * sizeof(unsigned int))]; + #endif #ifdef WOLF_CRYPTO_CB void* cryptocb_holder[(sizeof(int) + sizeof(void*) + 4) / sizeof(void*)]; #endif diff --git a/wolfssl/wolfcrypt/aes.h b/wolfssl/wolfcrypt/aes.h index 14ea8427e..264fe5fe6 100644 --- a/wolfssl/wolfcrypt/aes.h +++ b/wolfssl/wolfcrypt/aes.h @@ -191,6 +191,9 @@ struct Aes { int ctxInitDone; int keyId; #endif +#ifdef WOLFSSL_CAAM + int blackKey; /* black key / hsm key id */ +#endif #ifdef GCM_TABLE /* key-based fast multiplication table. */ diff --git a/wolfssl/wolfcrypt/cmac.h b/wolfssl/wolfcrypt/cmac.h index 4f5d4cf04..8e39c679b 100644 --- a/wolfssl/wolfcrypt/cmac.h +++ b/wolfssl/wolfcrypt/cmac.h @@ -56,13 +56,18 @@ struct Cmac { #ifdef WOLF_CRYPTO_CB int devId; void* devCtx; - #ifdef WOLFSSL_QNX_CAAM + #ifdef WOLFSSL_CAAM byte ctx[32]; /* hold state for save and return */ word32 blackKey; word32 keylen; byte initialized; #endif #endif +#if defined(WOLFSSL_HASH_KEEP) + byte* msg; + word32 used; + word32 len; +#endif }; @@ -106,6 +111,11 @@ int wc_AesCmacVerify(const byte* check, word32 checkSz, WOLFSSL_LOCAL void ShiftAndXorRb(byte* out, byte* in); +#ifdef WOLFSSL_HASH_KEEP +WOLFSSL_API +int wc_CMAC_Grow(Cmac* cmac, const byte* in, int inSz); +#endif + #ifdef __cplusplus } /* extern "C" */ #endif diff --git a/wolfssl/wolfcrypt/cryptocb.h b/wolfssl/wolfcrypt/cryptocb.h index f6b266461..6b20e72e2 100644 --- a/wolfssl/wolfcrypt/cryptocb.h +++ b/wolfssl/wolfcrypt/cryptocb.h @@ -251,7 +251,7 @@ typedef struct wc_CryptoInfo { word32 authInSz; } aesccm_dec; #endif /* HAVE_AESCCM */ - #ifdef HAVE_AES_CBC + #if defined(HAVE_AES_CBC) struct { Aes* aes; byte* out; @@ -259,6 +259,14 @@ typedef struct wc_CryptoInfo { word32 sz; } aescbc; #endif /* HAVE_AES_CBC */ + #if defined(HAVE_AES_ECB) + struct { + Aes* aes; + byte* out; + const byte* in; + word32 sz; + } aesecb; + #endif /* HAVE_AES_ECB */ #ifndef NO_DES3 struct { Des3* des; @@ -285,6 +293,9 @@ typedef struct wc_CryptoInfo { #ifndef NO_SHA wc_Sha* sha1; #endif + #ifdef WOLFSSL_SHA224 + wc_Sha224* sha224; + #endif #ifndef NO_SHA256 wc_Sha256* sha256; #endif @@ -345,6 +356,7 @@ WOLFSSL_LOCAL void wc_CryptoCb_Init(void); WOLFSSL_LOCAL int wc_CryptoCb_GetDevIdAtIndex(int startIdx); WOLFSSL_API int wc_CryptoCb_RegisterDevice(int devId, CryptoDevCallbackFunc cb, void* ctx); WOLFSSL_API void wc_CryptoCb_UnRegisterDevice(int devId); +WOLFSSL_API int wc_CryptoCb_DefaultDevID(void); /* old function names */ #define wc_CryptoDev_RegisterDevice wc_CryptoCb_RegisterDevice @@ -430,6 +442,12 @@ WOLFSSL_LOCAL int wc_CryptoCb_AesCbcEncrypt(Aes* aes, byte* out, WOLFSSL_LOCAL int wc_CryptoCb_AesCbcDecrypt(Aes* aes, byte* out, const byte* in, word32 sz); #endif /* HAVE_AES_CBC */ +#ifdef HAVE_AES_ECB +WOLFSSL_LOCAL int wc_CryptoCb_AesEcbEncrypt(Aes* aes, byte* out, + const byte* in, word32 sz); +WOLFSSL_LOCAL int wc_CryptoCb_AesEcbDecrypt(Aes* aes, byte* out, + const byte* in, word32 sz); +#endif /* HAVE_AES_ECB */ #endif /* !NO_AES */ #ifndef NO_DES3 diff --git a/wolfssl/wolfcrypt/ecc.h b/wolfssl/wolfcrypt/ecc.h index edf9b69a7..d0defd94b 100644 --- a/wolfssl/wolfcrypt/ecc.h +++ b/wolfssl/wolfcrypt/ecc.h @@ -440,7 +440,7 @@ struct ecc_key { ecc_point pubkey; /* public key */ mp_int k; /* private key */ -#ifdef WOLFSSL_QNX_CAAM +#ifdef WOLFSSL_CAAM word32 blackKey; /* address of key encrypted and in secure memory */ word32 securePubKey; /* address of public key in secure memory */ int partNum; /* partition number*/ diff --git a/wolfssl/wolfcrypt/hash.h b/wolfssl/wolfcrypt/hash.h index 0c7967429..81e176890 100644 --- a/wolfssl/wolfcrypt/hash.h +++ b/wolfssl/wolfcrypt/hash.h @@ -222,6 +222,11 @@ WOLFSSL_API int wc_Shake256Hash(const byte* data, word32 len, byte* hash, word32 #endif /* !NO_HASH_WRAPPER */ +#if defined(WOLFSSL_HASH_KEEP) +WOLFSSL_LOCAL int _wc_Hash_Grow(byte** msg, word32* used, word32* len, + const byte* in, int inSz, void* heap); +#endif + #ifdef __cplusplus } /* extern "C" */ #endif diff --git a/wolfssl/wolfcrypt/hmac.h b/wolfssl/wolfcrypt/hmac.h index 99ca2a4b1..4d064ca73 100644 --- a/wolfssl/wolfcrypt/hmac.h +++ b/wolfssl/wolfcrypt/hmac.h @@ -55,6 +55,10 @@ #include #endif +#if defined(WOLFSSL_DEVCRYPTO_AES) || defined(WOLFSSL_DEVCRYPTO_HMAC) + #include +#endif + #ifndef NO_OLD_WC_NAMES #define HMAC_BLOCK_SIZE WC_HMAC_BLOCK_SIZE #endif @@ -155,6 +159,9 @@ struct Hmac { #ifdef WOLFSSL_ASYNC_CRYPT WC_ASYNC_DEV asyncDev; #endif /* WOLFSSL_ASYNC_CRYPT */ +#if defined(WOLFSSL_DEVCRYPTO) && defined(WOLFSSL_DEVCRYPTO_HMAC) + WC_CRYPTODEV ctx; +#endif #ifdef WOLF_CRYPTO_CB int devId; void* devCtx; diff --git a/wolfssl/wolfcrypt/include.am b/wolfssl/wolfcrypt/include.am index 9bf1d9a8d..3a7c1f6e1 100644 --- a/wolfssl/wolfcrypt/include.am +++ b/wolfssl/wolfcrypt/include.am @@ -160,12 +160,17 @@ nobase_include_HEADERS+= wolfssl/wolfcrypt/fips.h endif endif -if BUILD_QNXCAAM +if BUILD_CAAM nobase_include_HEADERS+= wolfssl/wolfcrypt/port/caam/wolfcaam.h \ wolfssl/wolfcrypt/port/caam/wolfcaam_sha.h \ + wolfssl/wolfcrypt/port/caam/wolfcaam_hash.h \ + wolfssl/wolfcrypt/port/caam/wolfcaam_rsa.h \ + wolfssl/wolfcrypt/port/caam/wolfcaam_x25519.h \ wolfssl/wolfcrypt/port/caam/wolfcaam_ecdsa.h \ wolfssl/wolfcrypt/port/caam/wolfcaam_cmac.h \ - wolfssl/wolfcrypt/port/caam/wolfcaam_qnx.h + wolfssl/wolfcrypt/port/caam/wolfcaam_aes.h \ + wolfssl/wolfcrypt/port/caam/wolfcaam_qnx.h \ + wolfssl/wolfcrypt/port/caam/wolfcaam_seco.h endif if BUILD_IOTSAFE diff --git a/wolfssl/wolfcrypt/port/caam/wolfcaam.h b/wolfssl/wolfcrypt/port/caam/wolfcaam.h index 9f15df20f..7fbed0e88 100644 --- a/wolfssl/wolfcrypt/port/caam/wolfcaam.h +++ b/wolfssl/wolfcrypt/port/caam/wolfcaam.h @@ -28,12 +28,19 @@ /* include for porting layer */ #ifdef WOLFSSL_QNX_CAAM #include +#elif defined(WOLFSSL_SECO_CAAM) + #include #endif #if defined(WOLFSSL_IMX6_CAAM) || defined(WOLFSSL_IMX6_CAAM_RNG) || \ - defined(WOLFSSL_QNX_CAAM) + defined(WOLFSSL_QNX_CAAM) || defined(WOLFSSL_SECO_CAAM) +/* unique devId for CAAM use on crypto callbacks */ +#ifndef WOLFSSL_CAAM_DEVID + #define WOLFSSL_CAAM_DEVID 7 +#endif + #if defined(__INTEGRITY) || defined(INTEGRITY) #include typedef Buffer CAAM_BUFFER; @@ -76,7 +83,7 @@ WOLFSSL_API int wc_caamCoverKey(byte* in, word32 inSz, byte* out, word32* outSz, #define WC_CAAM_BLACK_KEYMOD_SZ 16 #define WC_CAAM_MAX_ENTROPY 44 -#ifndef WOLFSSL_QNX_CAAM +#if !defined(WOLFSSL_QNX_CAAM) && !defined(WOLFSSL_SECO_CAAM) WOLFSSL_API int wc_caamSetResource(IODevice ioDev); #ifndef WC_CAAM_READ #define WC_CAAM_READ(reg) wc_caamReadRegister((reg)) @@ -94,6 +101,7 @@ WOLFSSL_API int wc_caamCoverKey(byte* in, word32 inSz, byte* out, word32* outSz, #define CAAM_AESOFB 0x00100400 #define CAAM_CMAC 0x00100600 #define CAAM_AESCCM 0x00100800 +#define CAAM_AESGCM 0x00100900 #define CAAM_MD5 0x00400000 #define CAAM_SHA 0x00410000 diff --git a/wolfssl/wolfcrypt/port/caam/wolfcaam_aes.h b/wolfssl/wolfcrypt/port/caam/wolfcaam_aes.h new file mode 100644 index 000000000..40c58f65c --- /dev/null +++ b/wolfssl/wolfcrypt/port/caam/wolfcaam_aes.h @@ -0,0 +1,61 @@ +/* wolfcaam_aes.h + * + * Copyright (C) 2006-2021 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + + +#include + +#ifndef WOLFCAAM_AES_H +#define WOLFCAAM_AES_H + +#if !defined(NO_AES) && defined(WOLFSSL_CAAM) + +#include + +WOLFSSL_LOCAL int wc_CAAM_AesCcmEncrypt(Aes* aes, const byte* in, byte* out, + word32 sz, const byte* nonce, word32 nonceSz, byte* authTag, + word32 authTagSz, const byte* authIn, word32 authInSz); + +WOLFSSL_LOCAL int wc_CAAM_AesCcmDecrypt(Aes* aes, const byte* in, byte* out, + word32 sz, const byte* nonce, word32 nonceSz, const byte* authTag, + word32 authTagSz, const byte* authIn, word32 authInSz); + +WOLFSSL_LOCAL int wc_CAAM_AesGcmEncrypt(Aes* aes, const byte* in, byte* out, + word32 sz, const byte* nonce, word32 nonceSz, byte* authTag, + word32 authTagSz, const byte* authIn, word32 authInSz); + +WOLFSSL_LOCAL int wc_CAAM_AesGcmDecrypt(Aes* aes, const byte* in, byte* out, + word32 sz, const byte* nonce, word32 nonceSz, const byte* authTag, + word32 authTagSz, const byte* authIn, word32 authInSz); + +WOLFSSL_LOCAL int wc_CAAM_AesCbcEncrypt(Aes* aes, byte* out, const byte* in, + word32 sz); + +WOLFSSL_LOCAL int wc_CAAM_AesCbcDecrypt(Aes* aes, byte* out, const byte* in, + word32 sz); + +WOLFSSL_LOCAL int wc_CAAM_AesEcbEncrypt(Aes* aes, byte* out, const byte* in, + word32 sz); + +WOLFSSL_LOCAL int wc_CAAM_AesEcbDecrypt(Aes* aes, byte* out, const byte* in, + word32 sz); +#endif /* WOLFSSL_CAAM && !NO_AES */ +#endif /* WOLFCAAM_AES_H */ + diff --git a/wolfssl/wolfcrypt/port/caam/wolfcaam_cmac.h b/wolfssl/wolfcrypt/port/caam/wolfcaam_cmac.h index d075c9816..cba837592 100644 --- a/wolfssl/wolfcrypt/port/caam/wolfcaam_cmac.h +++ b/wolfssl/wolfcrypt/port/caam/wolfcaam_cmac.h @@ -25,7 +25,7 @@ #ifndef WOLFCAAM_CMAC_H #define WOLFCAAM_CMAC_H -#if defined(WOLFSSL_CMAC) && defined(WOLFSSL_QNX_CAAM) +#if defined(WOLFSSL_CMAC) && defined(WOLFSSL_CAAM) #include diff --git a/wolfssl/wolfcrypt/port/caam/wolfcaam_ecdsa.h b/wolfssl/wolfcrypt/port/caam/wolfcaam_ecdsa.h index 36dbe831a..9ab3a99c2 100644 --- a/wolfssl/wolfcrypt/port/caam/wolfcaam_ecdsa.h +++ b/wolfssl/wolfcrypt/port/caam/wolfcaam_ecdsa.h @@ -24,18 +24,18 @@ #ifndef WOLFCAAM_ECDSA_H #define WOLFCAAM_ECDSA_H -#if defined(HAVE_ECC) && defined(WOLFSSL_QNX_CAAM) +#if defined(HAVE_ECC) && defined(WOLFSSL_CAAM) #include WOLFSSL_LOCAL int wc_CAAM_EccSign(const byte* in, int inlen, byte* out, - word32* outlen, WC_RNG *rng, ecc_key *key); + word32* outlen, WC_RNG *rng, ecc_key *key, int devId); WOLFSSL_LOCAL int wc_CAAM_EccVerify(const byte* sig, word32 siglen, - const byte* hash, word32 hashlen, int* res, ecc_key* key); + const byte* hash, word32 hashlen, int* res, ecc_key* key, int devId); WOLFSSL_LOCAL int wc_CAAM_Ecdh(ecc_key* private_key, ecc_key* public_key, - byte* out, word32* outlen); + byte* out, word32* outlen, int devId); WOLFSSL_LOCAL int wc_CAAM_MakeEccKey(WC_RNG* rng, int keySize, ecc_key* key, - int curveId); + int curveId, int devId); WOLFSSL_LOCAL int wc_CAAM_EccCheckPrivKey(ecc_key* key, const byte* pubKey, word32 pubKeySz); #endif /* HAVE_ECC && WOLFSSL_QNX_CAAM */ diff --git a/wolfssl/wolfcrypt/port/caam/wolfcaam_hash.h b/wolfssl/wolfcrypt/port/caam/wolfcaam_hash.h new file mode 100644 index 000000000..7647a7b35 --- /dev/null +++ b/wolfssl/wolfcrypt/port/caam/wolfcaam_hash.h @@ -0,0 +1,53 @@ +/* wolfcaam_hash.h + * + * Copyright (C) 2006-2021 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + +#include + +#ifndef WOLFCAAM_HASH_H +#define WOLFCAAM_HASH_H + +#include + +WOLFSSL_LOCAL int wc_CAAM_ShaHash(wc_Sha* sha, const byte* in, word32 inSz, + byte* digest); +#ifdef WOLFSSL_SHA224 +WOLFSSL_LOCAL int wc_CAAM_Sha224Hash(wc_Sha224* sha224, const byte* in, + word32 inSz, byte* digest); +#endif +WOLFSSL_LOCAL int wc_CAAM_Sha256Hash(wc_Sha256* sha256, const byte* in, + word32 inSz, byte* digest); +WOLFSSL_LOCAL int wc_CAAM_Sha384Hash(wc_Sha384* sha384, const byte* in, + word32 inSz, byte* digest); +WOLFSSL_LOCAL int wc_CAAM_Sha512Hash(wc_Sha512* sha512, const byte* in, + word32 inSz, byte* digest); + + +#if !defined(NO_HMAC) +#ifndef WC_HMAC_TYPE_DEFINED + typedef struct Hmac Hmac; + #define WC_HMAC_TYPE_DEFINED +#endif +WOLFSSL_LOCAL int wc_CAAM_Hmac(Hmac* hmac, int macType, const byte* msg, + int msgSz, byte* digest); +#endif + +#endif + diff --git a/wolfssl/wolfcrypt/port/caam/wolfcaam_rsa.h b/wolfssl/wolfcrypt/port/caam/wolfcaam_rsa.h new file mode 100644 index 000000000..668007428 --- /dev/null +++ b/wolfssl/wolfcrypt/port/caam/wolfcaam_rsa.h @@ -0,0 +1,40 @@ +/* wolfcaam_rsa.h + * + * Copyright (C) 2006-2021 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + +#include + +#ifndef WOLFCAAM_RSA_H +#define WOLFCAAM_RSA_H + +#if !defined(NO_RSA) && defined(WOLFSSL_CAAM) + +#include + +WOLFSSL_LOCAL int wc_CAAM_Rsa(const byte* in, word32 inLen, byte* out, + word32* outLen, int type, RsaKey* key, WC_RNG* rng); +#ifdef WOLFSSL_KEY_GEN +WOLFSSL_LOCAL int wc_CAAM_MakeRsaKey(RsaKey* key, int size, long e, + WC_RNG* rng); +#endif + +#endif /* !NO_RSA && WOLFSSL_CAAM */ +#endif /* WOLFCAAM_RSA_H */ + diff --git a/wolfssl/wolfcrypt/port/caam/wolfcaam_seco.h b/wolfssl/wolfcrypt/port/caam/wolfcaam_seco.h new file mode 100644 index 000000000..ec6fb4cce --- /dev/null +++ b/wolfssl/wolfcrypt/port/caam/wolfcaam_seco.h @@ -0,0 +1,138 @@ +/* wolfcaam_seco.h + * + * Copyright (C) 2006-2021 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + + +/* This file is for interacting with the driver code */ +#ifndef WOLFCAAM_SECO_H +#define WOLFCAAM_SECO_H + +#include + +#ifdef WOLFSSL_SECO_CAAM + +/* unique devId for SECO use on crypto callbacks */ +#ifndef WOLFSSL_SECO_DEVID + #define WOLFSSL_SECO_DEVID 8 +#endif + +#define Error int +#define Value int +#define Boolean int +#define Success 1 +#define Failure 0 +#define INTERRUPT_Panic() +#define MemoryMapMayNotBeEmpty -1 +#define CAAM_WAITING -2 +#define NoActivityReady -1 +#define MemoryOperationNotPerformed -1 + +#include +#define CAAM_ADDRESS intptr_t +#ifndef WOLFSSL_CAAM_BUFFER +#define WOLFSSL_CAAM_BUFFER + typedef struct CAAM_BUFFER { + int BufferType; + CAAM_ADDRESS TheAddress; + int Length; + } CAAM_BUFFER; +#endif + + +#define DataBuffer 0 +#define LastBuffer 0 +#define Success 1 + +#include +#include +#include +#include +#include +#include +#include + +#define ResourceNotAvailable -3 +#define CAAM_WAITING -2 + +/* key stays after key store is closed */ +#define CAAM_KEY_PERSISTENT 0 + +/* key is deleted when key store is closed */ +#define CAAM_KEY_TRANSIENT 1 + +/* key is used as a key encryption key */ +#define CAAM_KEY_KEK 2 + +/* list of key types available */ +#define CAAM_KEYTYPE_ECDSA_P256 0 +#define CAAM_KEYTYPE_ECDSA_P384 1 +#define CAAM_KEYTYPE_ECDSA_P521 2 +#define CAAM_KEYTYPE_AES128 3 +#define CAAM_KEYTYPE_AES192 4 +#define CAAM_KEYTYPE_AES256 5 +#define CAAM_KEYTYPE_HMAC224 6 +#define CAAM_KEYTYPE_HMAC256 7 +#define CAAM_KEYTYPE_HMAC384 8 +#define CAAM_KEYTYPE_HMAC512 9 + +/* flags for key management */ +#define CAAM_UPDATE_KEY 1 +#define CAAM_GENERATE_KEY 2 +#define CAAM_DELETE_KEY 4 + +/* flags for key store open */ +#define CAAM_KEYSTORE_CREATE 1 +#define CAAM_KEYSTORE_UPDATE 0 + +#define MAX_GROUP 1023 + +WOLFSSL_LOCAL int SynchronousSendRequest(int type, unsigned int args[4], + CAAM_BUFFER *buf, int sz); +WOLFSSL_LOCAL int wc_SECOInitInterface(void); +WOLFSSL_LOCAL void wc_SECOFreeInterface(void); + +WOLFSSL_API int wc_SECO_OpenHSM(word32 keyId, word32 nonce, word16 maxUpdates, + byte flag); +WOLFSSL_API int wc_SECO_CloseHSM(void); + +WOLFSSL_API int wc_SECO_GenerateKey(int flags, int group, byte* out, int outSz, + int keyType, int keyInfo, unsigned int* keyIdOut); +WOLFSSL_API int wc_SECO_DeleteKey(unsigned int keyId, int group, int keyTypeIn); + +#if defined(WOLFSSL_CMAC) +WOLFSSL_API void wc_SECO_CMACSetKeyID(Cmac* cmac, int keyId); +WOLFSSL_API int wc_SECO_CMACGetKeyID(Cmac* cmac); +#endif + +WOLFSSL_API void wc_SECO_AesSetKeyID(Aes* aes, int keyId); +WOLFSSL_API int wc_SECO_AesGetKeyID(Aes* aes); + +WOLFSSL_LOCAL int wc_SECO_ExportKEK(byte* out, byte outSz, byte isCommon); +WOLFSSL_API word32 wc_SECO_WrapKey(word32 keyID, byte* in, word32 inSz, + byte* iv, word32 ivSz, int keyType, int keyInfo, int group); + +#define CAAM_SEND_REQUEST(type, sz, arg, buf) \ + SynchronousSendRequest((type), (arg), (buf), (sz)) +#define CAAM_INIT_INTERFACE wc_SECOInitInterface +#define CAAM_FREE_INTERFACE wc_SECOFreeInterface +#endif + +#endif /* WOLFCAAM_SECO_H */ + diff --git a/wolfssl/wolfcrypt/port/caam/wolfcaam_x25519.h b/wolfssl/wolfcrypt/port/caam/wolfcaam_x25519.h new file mode 100644 index 000000000..4fcc31c7b --- /dev/null +++ b/wolfssl/wolfcrypt/port/caam/wolfcaam_x25519.h @@ -0,0 +1,38 @@ +/* wolfcaam_x25519.h + * + * Copyright (C) 2006-2021 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + +#include + +#ifndef WOLFCAAM_X25519_H +#define WOLFCAAM_X25519_H + +#if defined(HAVE_CURVE25519) && defined(WOLFSSL_CAAM) + +#include + +WOLFSSL_LOCAL int wc_CAAM_MakeCurve25519Key(curve25519_key* key, int keySize, + WC_RNG* rng); +WOLFSSL_LOCAL int wc_CAAM_Curve25519(byte* out, word32* outlen, + curve25519_key* k, curve25519_key* pubKey, int endian); + +#endif /* !NO_RSA && WOLFSSL_CAAM */ +#endif /* WOLFCAAM_X25519_H */ + diff --git a/wolfssl/wolfcrypt/port/devcrypto/wc_devcrypto.h b/wolfssl/wolfcrypt/port/devcrypto/wc_devcrypto.h index a20aae685..e7bb54ba9 100644 --- a/wolfssl/wolfcrypt/port/devcrypto/wc_devcrypto.h +++ b/wolfssl/wolfcrypt/port/devcrypto/wc_devcrypto.h @@ -32,6 +32,10 @@ #include #include +#ifdef DEBUG_DEVCRYPTO +#include +#endif + typedef struct WC_CRYPTODEV { int cfd; struct session_op sess; @@ -40,13 +44,67 @@ typedef struct WC_CRYPTODEV { WOLFSSL_LOCAL int wc_DevCryptoCreate(WC_CRYPTODEV* ctx, int type, byte* key, word32 keySz); WOLFSSL_LOCAL void wc_DevCryptoFree(WC_CRYPTODEV* ctx); WOLFSSL_LOCAL void wc_SetupCrypt(struct crypt_op* crt, WC_CRYPTODEV* dev, - byte* src, int srcSz, byte* dst, byte* dig, int flag); + byte* src, int srcSz, byte* dst, byte* dig, int flag, int op); WOLFSSL_LOCAL void wc_SetupCryptSym(struct crypt_op* crt, WC_CRYPTODEV* dev, byte* src, word32 srcSz, byte* dst, byte* iv, int flag); WOLFSSL_LOCAL void wc_SetupCryptAead(struct crypt_auth_op* crt, WC_CRYPTODEV* dev, byte* src, word32 srcSz, byte* dst, byte* iv, word32 ivSz, int flag, byte* authIn, word32 authInSz, byte* authTag, word32 authTagSz); +WOLFSSL_LOCAL int wc_DevCryptoInit(void); +WOLFSSL_LOCAL void wc_DevCryptoCleanup(void); + +/* currently local API */ +#if defined(WOLFSSL_DEVCRYPTO_HMAC) +#ifndef WC_HMAC_TYPE_DEFINED + typedef struct Hmac Hmac; + #define WC_HMAC_TYPE_DEFINED +#endif +WOLFSSL_LOCAL int wc_DevCrypto_HmacSetKey(Hmac* hmac, int t, const byte* key, + word32 keySz); +WOLFSSL_LOCAL int wc_DevCrypto_HmacUpdate(Hmac* hmac, const byte* input, + word32 inputSz); +WOLFSSL_LOCAL int wc_DevCrypto_HmacFinal(Hmac* hmac, byte* out); +WOLFSSL_LOCAL int wc_DevCrypto_HmacInit(Hmac* hmac, void* heap, int devId); +WOLFSSL_LOCAL void wc_DevCrypto_HmacFree(Hmac* hmac); +#endif /* WOLFSSL_DEVCRYPTO_HMAC */ + +#if defined(WOLFSSL_DEVCRYPTO_RSA) +#ifndef WC_RSAKEY_TYPE_DEFINED + typedef struct RsaKey RsaKey; + #define WC_RSAKEY_TYPE_DEFINED +#endif +#ifndef WC_RNG_TYPE_DEFINED /* guard on redeclaration */ + typedef struct OS_Seed OS_Seed; + typedef struct WC_RNG WC_RNG; + #ifdef WC_RNG_SEED_CB + typedef int (*wc_RngSeed_Cb)(OS_Seed* os, byte* seed, word32 sz); + #endif + #define WC_RNG_TYPE_DEFINED +#endif +WOLFSSL_LOCAL int wc_DevCrypto_RsaEncrypt(const byte* in, word32 inlen, byte* out, + word32* outlen, RsaKey *key, int type); +WOLFSSL_LOCAL int wc_DevCrypto_RsaDecrypt(const byte* in, word32 inlen, + byte* out, word32 outlen, RsaKey* key, int type); +WOLFSSL_LOCAL int wc_DevCrypto_MakeRsaKey(RsaKey* key, int size, long e, WC_RNG* rng); +WOLFSSL_LOCAL void wc_DevCrypto_RsaFree(RsaKey* key); +#endif /* WOLFSSL_DEVCRYPTO_RSA */ + +#if defined(WOLFSSL_DEVCRYPTO_CURVE25519) +WOLFSSL_LOCAL int wc_DevCryptoCurve25519(byte* out, word32 outSz, const byte* k, + word32 kSz, const byte* a, word32 aSz, int endian); +#endif + +#if defined(WOLFSSL_DEVCRYPTO_ECDSA) +int wc_DevCryptoEccKeyGen(int curveId, int enc, byte* pri, word32 priSz, byte* pub, word32 pubSz); +int wc_DevCryptoEccEcdh(int curveId, int enc, byte* pri, word32 priSz, + byte* pub, word32 pubSz, byte* out, word32 outSz); +int wc_DevCryptoEccSign(int curveId, int enc, byte* pri, word32 priSz, + const byte* hash, word32 hashSz, byte* r, word32 rSz, byte* s, word32 sSz); +int wc_DevCryptoEccVerify(int curveId, byte* pub, word32 pubSz, + const byte* hash, word32 hashSz, byte* r, word32 rSz, byte* s, word32 sSz); +#endif + #endif /* WOLFSSL_DEVCRYPTO */ #endif /* WOLFSSL_DEVCRYPTO_H */ diff --git a/wolfssl/wolfcrypt/rsa.h b/wolfssl/wolfcrypt/rsa.h index 8d3c243a8..2b2e373c0 100644 --- a/wolfssl/wolfcrypt/rsa.h +++ b/wolfssl/wolfcrypt/rsa.h @@ -94,6 +94,10 @@ RSA keys can be used to encrypt, decrypt, sign and verify data. #include #endif +#if defined(WOLFSSL_DEVCRYPTO_RSA) + #include +#endif + #ifdef __cplusplus extern "C" { #endif @@ -214,6 +218,12 @@ struct RsaKey { #if defined(WOLFSSL_CRYPTOCELL) rsa_context_t ctx; #endif +#if defined(WOLFSSL_CAAM) + word32 blackKey; +#endif +#if defined(WOLFSSL_DEVCRYPTO_RSA) + WC_CRYPTODEV ctx; +#endif }; #ifndef WC_RSAKEY_TYPE_DEFINED diff --git a/wolfssl/wolfcrypt/sha.h b/wolfssl/wolfcrypt/sha.h index ad93830cd..f9b1c7012 100644 --- a/wolfssl/wolfcrypt/sha.h +++ b/wolfssl/wolfcrypt/sha.h @@ -156,6 +156,11 @@ struct wc_Sha { int devId; void* devCtx; /* generic crypto callback context */ #endif + #if defined(WOLFSSL_DEVCRYPTO_HASH) || defined(WOLFSSL_HASH_KEEP) + byte* msg; + word32 used; + word32 len; + #endif #endif #if defined(WOLFSSL_ESP32WROOM32_CRYPT) && \ !defined(NO_WOLFSSL_ESP32WROOM32_CRYPT_HASH) diff --git a/wolfssl/wolfcrypt/sha256.h b/wolfssl/wolfcrypt/sha256.h index 56a9ae859..38abbf4a1 100644 --- a/wolfssl/wolfcrypt/sha256.h +++ b/wolfssl/wolfcrypt/sha256.h @@ -196,6 +196,8 @@ struct wc_Sha256 { #endif /* !FREESCALE_LTC_SHA && !STM32_HASH_SHA2 */ #ifdef WOLFSSL_DEVCRYPTO_HASH WC_CRYPTODEV ctx; +#endif +#if defined(WOLFSSL_DEVCRYPTO_HASH) || defined(WOLFSSL_HASH_KEEP) byte* msg; word32 used; word32 len; @@ -237,7 +239,10 @@ WOLFSSL_API void wc_Sha256Free(wc_Sha256* sha256); #if defined(OPENSSL_EXTRA) WOLFSSL_API int wc_Sha256Transform(wc_Sha256* sha, const unsigned char* data); #endif -WOLFSSL_API int wc_Sha256GetHash(wc_Sha256* sha256, byte* hash); +#if defined(WOLFSSL_HASH_KEEP) +WOLFSSL_API int wc_Sha256_Grow(wc_Sha256* sha256, const byte* in, int inSz); +#endif +WOLFSSL_API int wc_Sha256GetHash(wc_Sha256*, byte*); WOLFSSL_API int wc_Sha256Copy(wc_Sha256* src, wc_Sha256* dst); #ifdef WOLFSSL_PIC32MZ_HASH @@ -286,7 +291,10 @@ WOLFSSL_API int wc_Sha224Update(wc_Sha224* sha224, const byte* data, word32 len) WOLFSSL_API int wc_Sha224Final(wc_Sha224* sha224, byte* hash); WOLFSSL_API void wc_Sha224Free(wc_Sha224* sha224); -WOLFSSL_API int wc_Sha224GetHash(wc_Sha224* sha224, byte* hash); +#if defined(WOLFSSL_HASH_KEEP) +WOLFSSL_API int wc_Sha224_Grow(wc_Sha224* sha224, const byte* in, int inSz); +#endif +WOLFSSL_API int wc_Sha224GetHash(wc_Sha224*, byte*); WOLFSSL_API int wc_Sha224Copy(wc_Sha224* src, wc_Sha224* dst); #ifdef WOLFSSL_HASH_FLAGS diff --git a/wolfssl/wolfcrypt/sha512.h b/wolfssl/wolfcrypt/sha512.h index 7f59ea1d7..b4e6dfaac 100644 --- a/wolfssl/wolfcrypt/sha512.h +++ b/wolfssl/wolfcrypt/sha512.h @@ -180,6 +180,11 @@ struct wc_Sha512 { #if defined(WOLFSSL_SE050) SE050_HASH_Context se050Ctx; #endif +#if defined(WOLFSSL_HASH_KEEP) + byte* msg; + word32 used; + word32 len; +#endif #ifdef WOLF_CRYPTO_CB int devId; void* devCtx; /* generic crypto callback context */ @@ -215,6 +220,9 @@ WOLFSSL_API void wc_Sha512Free(wc_Sha512* sha); WOLFSSL_API int wc_Sha512GetHash(wc_Sha512* sha512, byte* hash); WOLFSSL_API int wc_Sha512Copy(wc_Sha512* src, wc_Sha512* dst); +#if defined(WOLFSSL_HASH_KEEP) + WOLFSSL_API int wc_Sha512_Grow(wc_Sha512* sha512, const byte* in, int inSz); +#endif #ifdef WOLFSSL_HASH_FLAGS WOLFSSL_API int wc_Sha512SetFlags(wc_Sha512* sha512, word32 flags); WOLFSSL_API int wc_Sha512GetFlags(wc_Sha512* sha512, word32* flags); @@ -310,6 +318,9 @@ WOLFSSL_API void wc_Sha384Free(wc_Sha384* sha); WOLFSSL_API int wc_Sha384GetHash(wc_Sha384* sha384, byte* hash); WOLFSSL_API int wc_Sha384Copy(wc_Sha384* src, wc_Sha384* dst); +#if defined(WOLFSSL_HASH_KEEP) + WOLFSSL_API int wc_Sha384_Grow(wc_Sha384* sha384, const byte* in, int inSz); +#endif #ifdef WOLFSSL_HASH_FLAGS WOLFSSL_API int wc_Sha384SetFlags(wc_Sha384* sha384, word32 flags); WOLFSSL_API int wc_Sha384GetFlags(wc_Sha384* sha384, word32* flags); diff --git a/wolfssl/wolfcrypt/types.h b/wolfssl/wolfcrypt/types.h index 8b6c10bdb..aec28a8db 100644 --- a/wolfssl/wolfcrypt/types.h +++ b/wolfssl/wolfcrypt/types.h @@ -1016,6 +1016,7 @@ decouple library dependencies with standard string, memory and so on. WC_CIPHER_AES_XTS = 5, WC_CIPHER_AES_CFB = 6, WC_CIPHER_AES_CCM = 12, + WC_CIPHER_AES_ECB = 13, WC_CIPHER_DES3 = 7, WC_CIPHER_DES = 8, WC_CIPHER_CHACHA = 9,