diff --git a/wolfcrypt/benchmark/benchmark.c b/wolfcrypt/benchmark/benchmark.c index 042f73646..60f500c43 100644 --- a/wolfcrypt/benchmark/benchmark.c +++ b/wolfcrypt/benchmark/benchmark.c @@ -220,6 +220,9 @@ #ifdef HAVE_RENESAS_SYNC #include #endif + #if defined(WOLFSSL_MAX3266X) || defined(WOLFSSL_MAX3266X_OLD) + #include + #endif #endif #ifdef WOLFSSL_ASYNC_CRYPT @@ -3167,8 +3170,9 @@ 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(WOLFSSL_CAAM)) && \ - !defined(NO_HW_BENCH) + defined(HAVE_RENESAS_SYNC) || defined(WOLFSSL_CAAM)) || \ + ((defined(WOLFSSL_MAX3266X) || defined(WOLFSSL_MAX3266X_OLD)) && \ + defined(WOLF_CRYPTO_CB)) && !defined(NO_HW_BENCH) bench_aes_aad_options_wrap(bench_aesgcm, 1); #endif #ifndef NO_SW_BENCH diff --git a/wolfcrypt/src/aes.c b/wolfcrypt/src/aes.c index f226156e6..1073c4e01 100644 --- a/wolfcrypt/src/aes.c +++ b/wolfcrypt/src/aes.c @@ -84,6 +84,13 @@ block cipher mechanism that uses n-bit binary string parameter key with 128-bits #if defined(WOLFSSL_MAX3266X) || defined(WOLFSSL_MAX3266X_OLD) #include +#ifdef WOLF_CRYPTO_CB + /* Revert back to SW so HW CB works */ + /* HW only works for AES: ECB, CBC, and partial via ECB for other modes */ + #include + /* Turn off MAX3266X_AES in the context of this file when using CB */ + #undef MAX3266X_AES +#endif #endif #if defined(WOLFSSL_TI_CRYPT) @@ -2794,9 +2801,12 @@ extern void AesEncryptBlocks_C(Aes* aes, const byte* in, byte* out, word32 sz); static WARN_UNUSED_RESULT int wc_AesEncrypt( Aes* aes, const byte* inBlock, byte* outBlock) { - #if defined(MAX3266X_AES) +#if defined(MAX3266X_AES) word32 keySize; - #endif +#endif +#if defined(MAX3266X_CB) + int ret_cb; +#endif word32 r; if (aes == NULL) { @@ -2907,6 +2917,18 @@ static WARN_UNUSED_RESULT int wc_AesEncrypt( outBlock, (unsigned int)keySize); } #endif +#ifdef MAX3266X_CB /* Can do a basic ECB block */ + #ifndef WOLF_CRYPTO_CB_FIND + if (aes->devId != INVALID_DEVID) + #endif + { + ret_cb = wc_CryptoCb_AesEcbEncrypt(aes, outBlock, inBlock, + AES_BLOCK_SIZE); + if (ret_cb != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE)) + return ret_cb; + /* fall-through when unavailable */ + } +#endif AesEncrypt_C(aes, inBlock, outBlock, r); @@ -3556,9 +3578,12 @@ static void AesDecryptBlocks_C(Aes* aes, const byte* in, byte* out, word32 sz) static WARN_UNUSED_RESULT int wc_AesDecrypt( Aes* aes, const byte* inBlock, byte* outBlock) { - #if defined(MAX3266X_AES) +#if defined(MAX3266X_AES) word32 keySize; - #endif +#endif +#if defined(MAX3266X_CB) + int ret_cb; +#endif word32 r; if (aes == NULL) { @@ -3643,6 +3668,19 @@ static WARN_UNUSED_RESULT int wc_AesDecrypt( } #endif +#ifdef MAX3266X_CB /* Can do a basic ECB block */ + #ifndef WOLF_CRYPTO_CB_FIND + if (aes->devId != INVALID_DEVID) + #endif + { + ret_cb = wc_CryptoCb_AesEcbDecrypt(aes, outBlock, inBlock, + AES_BLOCK_SIZE); + if (ret_cb != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE)) + return ret_cb; + /* fall-through when unavailable */ + } +#endif + AesDecrypt_C(aes, inBlock, outBlock, r); return 0; @@ -4130,6 +4168,9 @@ static void AesSetKey_C(Aes* aes, const byte* key, word32 keySz, int dir) unsigned int i = 0; XMEMCPY(rk, key, keySz); +#ifdef MAX3266X_CB /* Copies needed values to use later if CB is used */ + XMEMCPY(aes->cb_key, key, keySz); +#endif #if defined(LITTLE_ENDIAN_ORDER) && !defined(WOLFSSL_PIC32MZ_CRYPT) && \ (!defined(WOLFSSL_ESP32_CRYPT) || defined(NO_WOLFSSL_ESP32_CRYPT_AES)) && \ !defined(MAX3266X_AES) @@ -4572,6 +4613,9 @@ static void AesSetKey_C(Aes* aes, const byte* key, word32 keySz, int dir) #endif XMEMCPY(aes->key, userKey, keylen); +#ifdef MAX3266X_CB /* Copy Key for CB for use later if needed */ + XMEMCMP(aes->cb_key, userKey, keylen); +#endif #ifndef WC_AES_BITSLICED #if defined(LITTLE_ENDIAN_ORDER) && !defined(WOLFSSL_PIC32MZ_CRYPT) && \ diff --git a/wolfcrypt/src/cryptocb.c b/wolfcrypt/src/cryptocb.c index d510bb438..47c333cf0 100644 --- a/wolfcrypt/src/cryptocb.c +++ b/wolfcrypt/src/cryptocb.c @@ -56,6 +56,10 @@ #include #endif +#if defined (WOLFSSL_MAX3266X) || defined (WOLFSSL_MAX3266X_OLD) + #include +#endif + /* TODO: Consider linked list with mutex */ #ifndef MAX_CRYPTO_DEVID_CALLBACKS #define MAX_CRYPTO_DEVID_CALLBACKS 8 diff --git a/wolfcrypt/src/port/maxim/max3266x.c b/wolfcrypt/src/port/maxim/max3266x.c index de293ea78..615af9fe5 100644 --- a/wolfcrypt/src/port/maxim/max3266x.c +++ b/wolfcrypt/src/port/maxim/max3266x.c @@ -42,6 +42,10 @@ #include #endif +#ifdef WOLF_CRYPTO_CB + #include +#endif + #if defined(USE_FAST_MATH) || defined(USE_INTEGER_HEAP_MATH) #error MXC Not Compatible with Fast Math or Heap Math #include @@ -82,6 +86,85 @@ int wc_MXC_TPU_Shutdown(void) } +#ifdef WOLF_CRYPTO_CB +int wc_MxcAesCryptoCb(wc_CryptoInfo* info) +{ + switch (info->cipher.type) { +#ifdef HAVE_AES_CBC + case WC_CIPHER_AES_CBC: + if (info->cipher.enc == 1) { + return wc_MxcCb_AesCbcEncrypt(info->cipher.aescbc.aes, + info->cipher.aescbc.out, + info->cipher.aescbc.in, + info->cipher.aescbc.sz); + } + #ifdef HAVE_AES_DECRYPT + else if (info->cipher.enc == 0) { + return wc_MxcCb_AesCbcDecrypt(info->cipher.aescbc.aes, + info->cipher.aescbc.out, + info->cipher.aescbc.in, + info->cipher.aescbc.sz); + } + #endif + break; /* Break out and return error */ +#endif +#ifdef HAVE_AES_ECB + case WC_CIPHER_AES_ECB: + if (info->cipher.enc == 1) { + return wc_MxcCb_AesEcbEncrypt(info->cipher.aesecb.aes, + info->cipher.aesecb.out, + info->cipher.aesecb.in, + info->cipher.aesecb.sz); + } + #ifdef HAVE_AES_DECRYPT + else if (info->cipher.enc == 0) { + return wc_MxcCb_AesEcbDecrypt(info->cipher.aesecb.aes, + info->cipher.aesecb.out, + info->cipher.aesecb.in, + info->cipher.aesecb.sz); + } + #endif + break; /* Break out and return error */ +#endif + default: + /* Is not ECB/CBC/GCM */ + return WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE); + } + /* Just in case code breaks of switch statement return error */ + return BAD_FUNC_ARG; +} + +/* Determines AES Type for Callback */ +/* General Callback Function to determine ALGO Type */ +int wc_MxcCryptoCb(int devIdArg, wc_CryptoInfo* info, void* ctx) +{ + int ret; + (void)ctx; + + if (info == NULL) { + return BAD_FUNC_ARG; + } + +#ifdef DEBUG_CRYPTOCB + wc_CryptoCb_InfoString(info); +#endif + + switch (info->algo_type) { + case WC_ALGO_TYPE_CIPHER: + /* return this to bypass HW and use SW */ + MAX3266X_MSG("Using MXC HW Callback:"); + ret = wc_MxcAesCryptoCb(info); /* Determine AES HW or SW */ + break; + default: + MAX3266X_MSG("Callback not support with MXC, using SW"); + /* return this to bypass HW and use SW */ + ret = WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE); + } + + return ret; +} +#endif + /* Convert Error Codes Correctly and Report HW error when */ /* using #define MAX3266X_VERBOSE */ int wc_MXC_error(int *ret) @@ -131,7 +214,7 @@ int wc_MXC_TRNG_Random(unsigned char* output, unsigned int sz) if (output == NULL) { return BAD_FUNC_ARG; } - status = wolfSSL_CryptHwMutexLock(); /* Lock Mutex needed since */ + status = wolfSSL_HwRngMutexLock(); /* Lock Mutex needed since */ /* calling TPU init */ if (status != 0) { return status; @@ -146,7 +229,7 @@ int wc_MXC_TRNG_Random(unsigned char* output, unsigned int sz) MAX3266X_MSG("TRNG Device did not initialize"); status = RNG_FAILURE_E; } - wolfSSL_CryptHwMutexUnLock(); /* Unlock Mutex no matter status value */ + wolfSSL_HwRngMutexUnLock(); /* Unlock Mutex no matter status value */ return status; } #endif /* MAX3266X_RNG */ @@ -162,7 +245,7 @@ int wc_MXC_TPU_AesEncrypt(const unsigned char* in, const unsigned char* iv, if (in == NULL || iv == NULL || enc_key == NULL || out == NULL) { return BAD_FUNC_ARG; } - status = wolfSSL_CryptHwMutexLock(); + status = wolfSSL_HwAesMutexLock(); MAX3266X_MSG("AES HW Encryption"); if (status != 0) { MAX3266X_MSG("Hardware Mutex Failure"); @@ -192,17 +275,84 @@ int wc_MXC_TPU_AesEncrypt(const unsigned char* in, const unsigned char* iv, break; default: MAX3266X_MSG("AES HW ERROR: Length Not Supported"); - wolfSSL_CryptHwMutexUnLock(); - return WC_HW_E; - break; + wolfSSL_HwAesMutexUnLock(); + return BAD_FUNC_ARG; } - wolfSSL_CryptHwMutexUnLock(); + wolfSSL_HwAesMutexUnLock(); if (status != 0) { MAX3266X_MSG("AES HW Acceleration Error Occurred"); return WC_HW_E; } - return 0; + return status; } + + +/* Encrypt AES Crypto Callbacks*/ +#if defined(WOLF_CRYPTO_CB) + +#ifdef HAVE_AES_ECB +int wc_MxcCb_AesEcbEncrypt(Aes* aes, byte* out, const byte* in, word32 sz) +{ + int status; + word32 keySize; + + if ((in == NULL) || (out == NULL) || (aes == NULL)) { + return BAD_FUNC_ARG; + } + + status = wc_AesGetKeySize(aes, &keySize); + if (status != 0) { + return status; + } + + status = wc_MXC_TPU_AesEncrypt(in, (byte*)aes->reg, (byte*)aes->cb_key, + MXC_TPU_MODE_ECB, sz, out, keySize); + + return status; +} +#endif /* HAVE_AES_ECB */ + +#ifdef HAVE_AES_CBC +int wc_MxcCb_AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz) +{ + word32 keySize; + int status; + byte *iv; + + if ((in == NULL) || (out == NULL) || (aes == NULL)) { + return BAD_FUNC_ARG; + } + + /* Always enforce a length check */ + if (sz % AES_BLOCK_SIZE) { + #ifdef WOLFSSL_AES_CBC_LENGTH_CHECKS + return BAD_LENGTH_E; + #else + return BAD_FUNC_ARG; + #endif + } + if (sz == 0) { + return 0; + } + + iv = (byte*)aes->reg; + status = wc_AesGetKeySize(aes, &keySize); + if (status != 0) { + return status; + } + + status = wc_MXC_TPU_AesEncrypt(in, iv, (byte*)aes->cb_key, + MXC_TPU_MODE_CBC, sz, out, + (unsigned int)keySize); + /* store iv for next call */ + if (status == 0) { + XMEMCPY(iv, out + sz - AES_BLOCK_SIZE, AES_BLOCK_SIZE); + } + return (status == 0) ? 0 : -1; +} +#endif /* HAVE_AES_CBC */ +#endif /* WOLF_CRYPTO_CB */ + #ifdef HAVE_AES_DECRYPT /* Generic call to the SDK's AES 1 shot decrypt based on inputs given */ int wc_MXC_TPU_AesDecrypt(const unsigned char* in, const unsigned char* iv, @@ -214,7 +364,7 @@ int wc_MXC_TPU_AesDecrypt(const unsigned char* in, const unsigned char* iv, if (in == NULL || iv == NULL || dec_key == NULL || out == NULL) { return BAD_FUNC_ARG; } - status = wolfSSL_CryptHwMutexLock(); + status = wolfSSL_HwAesMutexLock(); if (status != 0) { return status; } @@ -242,17 +392,86 @@ int wc_MXC_TPU_AesDecrypt(const unsigned char* in, const unsigned char* iv, break; default: MAX3266X_MSG("AES HW ERROR: Length Not Supported"); - wolfSSL_CryptHwMutexUnLock(); - return WC_HW_E; - break; + wolfSSL_HwAesMutexUnLock(); + return BAD_FUNC_ARG; } - wolfSSL_CryptHwMutexUnLock(); + wolfSSL_HwAesMutexUnLock(); if (status != 0) { MAX3266X_MSG("AES HW Acceleration Error Occurred"); return WC_HW_E; } - return 0; + return status; } + +/* Decrypt Aes Crypto Callbacks*/ +#if defined(WOLF_CRYPTO_CB) + +#ifdef HAVE_AES_ECB +int wc_MxcCb_AesEcbDecrypt(Aes* aes, byte* out, const byte* in, word32 sz) +{ + int status; + word32 keySize; + + if ((in == NULL) || (out == NULL) || (aes == NULL)) { + return BAD_FUNC_ARG; + } + + status = wc_AesGetKeySize(aes, &keySize); + if (status != 0) { + return status; + } + + status = wc_MXC_TPU_AesDecrypt(in, (byte*)aes->reg, (byte*)aes->cb_key, + MXC_TPU_MODE_ECB, sz, out, keySize); + + return status; +} +#endif /* HAVE_AES_ECB */ + +#ifdef HAVE_AES_CBC +int wc_MxcCb_AesCbcDecrypt(Aes* aes, byte* out, const byte* in, word32 sz) +{ + word32 keySize; + int status; + byte *iv; + byte temp_block[AES_BLOCK_SIZE]; + + if ((in == NULL) || (out == NULL) || (aes == NULL)) { + return BAD_FUNC_ARG; + } + + /* Always enforce a length check */ + if (sz % AES_BLOCK_SIZE) { + #ifdef WOLFSSL_AES_CBC_LENGTH_CHECKS + return BAD_LENGTH_E; + #else + return BAD_FUNC_ARG; + #endif + } + if (sz == 0) { + return 0; + } + + iv = (byte*)aes->reg; + status = wc_AesGetKeySize(aes, &keySize); + if (status != 0) { + return status; + } + + /* get IV for next call */ + XMEMCPY(temp_block, in + sz - AES_BLOCK_SIZE, AES_BLOCK_SIZE); + status = wc_MXC_TPU_AesDecrypt(in, iv, (byte*)aes->cb_key, + MXC_TPU_MODE_CBC, sz, out, + keySize); + + /* store iv for next call */ + if (status == 0) { + XMEMCPY(iv, temp_block, AES_BLOCK_SIZE); + } + return (status == 0) ? 0 : -1; +} +#endif /* HAVE_AES_CBC */ +#endif /* WOLF_CRYPTO_CB */ #endif /* HAVE_AES_DECRYPT */ #endif /* MAX3266X_AES */ @@ -331,7 +550,7 @@ int wc_MXC_TPU_SHA_GetHash(wc_MXC_Sha *hash, unsigned char* digest, } /* False Case where msg needs to be processed */ else if (status == 0) { - status = wolfSSL_CryptHwMutexLock(); /* Set Mutex **/ + status = wolfSSL_HwHashMutexLock(); /* Set Mutex */ if (status != 0) { /* Mutex Call Check */ return status; } @@ -340,7 +559,7 @@ int wc_MXC_TPU_SHA_GetHash(wc_MXC_Sha *hash, unsigned char* digest, status = MXC_TPU_Hash_SHA((const char *)hash->msg, algo, hash->size, (char *)digest); MAX3266X_MSG("SHA HW Acceleration Used"); - wolfSSL_CryptHwMutexUnLock(); /* Release Mutex */ + wolfSSL_HwHashMutexUnLock(); /* Release Mutex */ if (wc_MXC_error(&status) != 0) { MAX3266X_MSG("SHA HW Error Occurred"); return status; @@ -684,7 +903,7 @@ int wc_MXC_MAA_init(unsigned int len) { int status; MAX3266X_MSG("Setting Hardware Mutex and Starting MAA"); - status = wolfSSL_CryptHwMutexLock(); + status = wolfSSL_HwPkMutexLock(); if (status == 0) { status = MXC_TPU_MAA_Init(len); } @@ -701,7 +920,7 @@ int wc_MXC_MAA_Shutdown(void) /* This is returned when MAA cannot stop */ status = WC_HW_E; } - wolfSSL_CryptHwMutexUnLock(); /* Always call Unlock in shutdown */ + wolfSSL_HwPkMutexUnLock(); /* Always call Unlock in shutdown */ return wc_MXC_error(&status); } @@ -901,7 +1120,7 @@ int wc_MXC_MAA_math(mp_int* multiplier, mp_int* multiplicand, mp_int* exp, ret = wc_MXC_MAA_init(length*sizeof(mp_digit)*8); if (ret != 0) { MAX3266X_MSG("HW Init Failed"); - wolfSSL_CryptHwMutexUnLock(); + wolfSSL_HwPkMutexUnLock(); return ret; } @@ -915,14 +1134,14 @@ int wc_MXC_MAA_math(mp_int* multiplier, mp_int* multiplicand, mp_int* exp, MAX3266X_MSG("MAA Finished Computation"); if (wc_MXC_error(&ret) != 0) { MAX3266X_MSG("HW Computation Error"); - wolfSSL_CryptHwMutexUnLock(); + wolfSSL_HwPkMutexUnLock(); return ret; } ret = wc_MXC_MAA_Shutdown(); if (ret != 0) { MAX3266X_MSG("HW Shutdown Failure"); - /* Shutdown will always call wolfSSL_CryptHwMutexUnLock(); */ + /* Shutdown will always call wolfSSL_HwPkMutexUnLock(); */ /* before returning */ return ret; } diff --git a/wolfcrypt/src/random.c b/wolfcrypt/src/random.c index 5f2320315..d6c32f692 100644 --- a/wolfcrypt/src/random.c +++ b/wolfcrypt/src/random.c @@ -3839,15 +3839,30 @@ int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz) #elif defined(MAX3266X_RNG) int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz) { + #ifdef WOLFSSL_MAX3266X + int status; + #endif /* WOLFSSL_MAX3266X */ static int initDone = 0; (void)os; if (initDone == 0) { + #ifdef WOLFSSL_MAX3266X + status = wolfSSL_HwRngMutexLock(); + if (status != 0) { + return status; + } + #endif /* WOLFSSL_MAX3266X */ if(MXC_TRNG_HealthTest() != 0) { - #if defined(DEBUG_WOLFSSL) + #ifdef DEBUG_WOLFSSL WOLFSSL_MSG("TRNG HW Health Test Failed"); - #endif + #endif /* DEBUG_WOLFSSL */ + #ifdef WOLFSSL_MAX3266X + wolfSSL_HwRngMutexUnLock(); + #endif /* WOLFSSL_MAX3266X */ return WC_HW_E; } + #ifdef WOLFSSL_MAX3266X + wolfSSL_HwRngMutexUnLock(); + #endif /* WOLFSSL_MAX3266X */ initDone = 1; } return wc_MXC_TRNG_Random(output, sz); diff --git a/wolfcrypt/src/wc_port.c b/wolfcrypt/src/wc_port.c index 5d3e9123b..772231ba0 100644 --- a/wolfcrypt/src/wc_port.c +++ b/wolfcrypt/src/wc_port.c @@ -46,6 +46,9 @@ #if defined(WOLFSSL_MAX3266X) || defined(WOLFSSL_MAX3266X_OLD) #include +#ifdef WOLF_CRYPTO_CB + #include +#endif #endif #ifdef WOLFSSL_PSOC6_CRYPTO @@ -255,6 +258,14 @@ int wolfCrypt_Init(void) } #endif + /* Crypto Callbacks only works on AES for MAX32666/5 HW */ + #if defined(MAX3266X_AES) && defined(WOLF_CRYPTO_CB) + ret = wc_CryptoCb_RegisterDevice(WOLFSSL_MAX3266X_DEVID, wc_MxcCryptoCb, + NULL); + if(ret != 0) { + return ret; + } + #endif #if defined(MAX3266X_RTC) ret = wc_MXC_RTC_Init(); if (ret != 0) { @@ -1362,6 +1373,196 @@ int wolfSSL_CryptHwMutexUnLock(void) #endif /* WOLFSSL_CRYPT_HW_MUTEX */ +#if WOLFSSL_CRYPT_HW_MUTEX && defined(WOLFSSL_ALGO_HW_MUTEX) +/* Mutex for protection of cryptography hardware */ +#ifndef NO_RNG_MUTEX +static wolfSSL_Mutex wcCryptHwRngMutex \ + WOLFSSL_MUTEX_INITIALIZER_CLAUSE(wcCryptHwRngMutex); +#endif /* NO_RNG_MUTEX */ +#ifndef NO_AES_MUTEX +static wolfSSL_Mutex wcCryptHwAesMutex \ + WOLFSSL_MUTEX_INITIALIZER_CLAUSE(wcCryptHwAesMutex); +#endif /* NO_AES_MUTEX */ +#ifndef NO_HASH_MUTEX +static wolfSSL_Mutex wcCryptHwHashMutex \ + WOLFSSL_MUTEX_INITIALIZER_CLAUSE(wcCryptHwHashMutex); +#endif /* NO_HASH_MUTEX */ +#ifndef NO_PK_MUTEX +static wolfSSL_Mutex wcCryptHwPkMutex \ + WOLFSSL_MUTEX_INITIALIZER_CLAUSE(wcCryptHwPkMutex); +#endif /* NO_PK_MUTEX */ + +#ifndef WOLFSSL_MUTEX_INITIALIZER +#ifndef NO_RNG_MUTEX +static int wcCryptHwRngMutexInit = 0; +#endif /* NO_RNG_MUTEX */ +#ifndef NO_AES_MUTEX +static int wcCryptHwAesMutexInit = 0; +#endif /* NO_AES_MUTEX */ +#ifndef NO_HASH_MUTEX +static int wcCryptHwHashMutexInit = 0; +#endif /* NO_HASH_MUTEX */ +#ifndef NO_PK_MUTEX +static int wcCryptHwPkMutexInit = 0; +#endif /* NO_PK_MUTEX */ +#endif /* WOLFSSL_MUTEX_INITIALIZER */ + + +/* Allows ability to switch to different mutex based on enum type */ +/* hw_mutex_algo, expects the dereferenced Ptrs to be set to NULL */ +static int hwAlgoPtrSet(hw_mutex_algo hwAlgo, wolfSSL_Mutex** wcHwAlgoMutexPtr, + int** wcHwAlgoInitPtr) +{ + if (*wcHwAlgoMutexPtr != NULL || *wcHwAlgoInitPtr != NULL) { + return BAD_FUNC_ARG; + } + switch (hwAlgo) { + #ifndef NO_RNG_MUTEX + case rng_mutex: + *wcHwAlgoMutexPtr = &wcCryptHwRngMutex; + *wcHwAlgoInitPtr = &wcCryptHwRngMutexInit; + break; + #endif + #ifndef NO_AES_MUTEX + case aes_mutex: + *wcHwAlgoMutexPtr = &wcCryptHwAesMutex; + *wcHwAlgoInitPtr = &wcCryptHwAesMutexInit; + break; + #endif + #ifndef NO_HASH_MUTEX + case hash_mutex: + *wcHwAlgoMutexPtr = &wcCryptHwHashMutex; + *wcHwAlgoInitPtr = &wcCryptHwHashMutexInit; + break; + #endif + #ifndef NO_PK_MUTEX + case pk_mutex: + *wcHwAlgoMutexPtr = &wcCryptHwPkMutex; + *wcHwAlgoInitPtr = &wcCryptHwPkMutexInit; + break; + #endif + default: + return BAD_FUNC_ARG; + } + return 0; +} + +static int hwAlgoMutexInit(hw_mutex_algo hwAlgo) +{ + int ret = 0; +#ifndef WOLFSSL_MUTEX_INITIALIZER + wolfSSL_Mutex* wcHwAlgoMutexPtr = NULL; + int* wcHwAlgoInitPtr = NULL; + ret = hwAlgoPtrSet(hwAlgo, &wcHwAlgoMutexPtr, &wcHwAlgoInitPtr); + if (ret != 0) { + return ret; + } + if (*wcHwAlgoInitPtr == 0) { + ret = wc_InitMutex(wcHwAlgoMutexPtr); + if (ret == 0) { + *wcHwAlgoInitPtr = 1; + } + } +#endif + return ret; +} + +static int hwAlgoMutexLock(hw_mutex_algo hwAlgo) +{ + /* Make sure HW Mutex has been initialized */ + int ret = 0; + wolfSSL_Mutex* wcHwAlgoMutexPtr = NULL; + int* wcHwAlgoInitPtr = NULL; + ret = hwAlgoPtrSet(hwAlgo, &wcHwAlgoMutexPtr, &wcHwAlgoInitPtr); + if (ret != 0) { + return ret; + } + ret = hwAlgoMutexInit(hwAlgo); + if (ret == 0) { + ret = wc_LockMutex(wcHwAlgoMutexPtr); + } + return ret; +} + +static int hwAlgoMutexUnLock(hw_mutex_algo hwAlgo) +{ + wolfSSL_Mutex* wcHwAlgoMutexPtr = NULL; + int* wcHwAlgoInitPtr = NULL; + if (hwAlgoPtrSet(hwAlgo, &wcHwAlgoMutexPtr, &wcHwAlgoInitPtr) != 0) { + return BAD_FUNC_ARG; + } + if (*wcHwAlgoInitPtr) { + return wc_UnLockMutex(wcHwAlgoMutexPtr); + } + else { + return BAD_MUTEX_E; + } +} + +/* Wrap around generic hwAlgo* functions and use correct */ +/* global mutex to determine if it can be unlocked/locked */ +#ifndef NO_RNG_MUTEX +int wolfSSL_HwRngMutexInit(void) +{ + return hwAlgoMutexInit(rng_mutex); +} +int wolfSSL_HwRngMutexLock(void) +{ + return hwAlgoMutexLock(rng_mutex); +} +int wolfSSL_HwRngMutexUnLock(void) +{ + return hwAlgoMutexUnLock(rng_mutex); +} +#endif /* NO_RNG_MUTEX */ + +#ifndef NO_AES_MUTEX +int wolfSSL_HwAesMutexInit(void) +{ + return hwAlgoMutexInit(aes_mutex); +} +int wolfSSL_HwAesMutexLock(void) +{ + return hwAlgoMutexLock(aes_mutex); +} +int wolfSSL_HwAesMutexUnLock(void) +{ + return hwAlgoMutexUnLock(aes_mutex); +} +#endif /* NO_AES_MUTEX */ + +#ifndef NO_HASH_MUTEX +int wolfSSL_HwHashMutexInit(void) +{ + return hwAlgoMutexInit(hash_mutex); +} +int wolfSSL_HwHashMutexLock(void) +{ + return hwAlgoMutexLock(hash_mutex); +} +int wolfSSL_HwHashMutexUnLock(void) +{ + return hwAlgoMutexUnLock(hash_mutex); +} +#endif /* NO_HASH_MUTEX */ + +#ifndef NO_PK_MUTEX +int wolfSSL_HwPkMutexInit(void) +{ + return hwAlgoMutexInit(pk_mutex); +} +int wolfSSL_HwPkMutexLock(void) +{ + return hwAlgoMutexLock(pk_mutex); +} +int wolfSSL_HwPkMutexUnLock(void) +{ + return hwAlgoMutexUnLock(pk_mutex); +} +#endif /* NO_PK_MUTEX */ + +#endif /* WOLFSSL_CRYPT_HW_MUTEX && defined(WOLFSSL_ALGO_HW_MUTEX) */ + /* ---------------------------------------------------------------------------*/ /* Mutex Ports */ /* ---------------------------------------------------------------------------*/ diff --git a/wolfcrypt/test/test.c b/wolfcrypt/test/test.c index c14d712e2..7be838e60 100644 --- a/wolfcrypt/test/test.c +++ b/wolfcrypt/test/test.c @@ -390,6 +390,9 @@ const byte const_byte_array[] = "A+Gd\0\0\0"; #ifdef HAVE_RENESAS_SYNC #include #endif + #if defined(WOLFSSL_MAX3266X) || defined(WOLFSSL_MAX3266X_OLD) + #include + #endif #endif #ifdef _MSC_VER diff --git a/wolfssl/wolfcrypt/aes.h b/wolfssl/wolfcrypt/aes.h index cf08ec3a5..eab2ea5b5 100644 --- a/wolfssl/wolfcrypt/aes.h +++ b/wolfssl/wolfcrypt/aes.h @@ -263,6 +263,11 @@ struct Aes { word32 rounds; #ifdef WC_C_DYNAMIC_FALLBACK word32 key_C_fallback[60]; +#endif +#if (defined(WOLFSSL_MAX3266X) || defined(WOLFSSL_MAX3266X_OLD)) && \ + defined(WOLF_CRYPTO_CB) + /* Need backup key for MXC CB */ + word32 cb_key[60]; #endif int keylen; diff --git a/wolfssl/wolfcrypt/include.am b/wolfssl/wolfcrypt/include.am index 490dadd9a..d091946c0 100644 --- a/wolfssl/wolfcrypt/include.am +++ b/wolfssl/wolfcrypt/include.am @@ -117,7 +117,8 @@ noinst_HEADERS+= \ wolfssl/wolfcrypt/port/Renesas/renesas_cmn.h \ wolfssl/wolfcrypt/port/Renesas/renesas_tsip_types.h \ wolfssl/wolfcrypt/port/cypress/psoc6_crypto.h \ - wolfssl/wolfcrypt/port/maxim/max3266x.h + wolfssl/wolfcrypt/port/maxim/max3266x.h \ + wolfssl/wolfcrypt/port/maxim/max3266x-cryptocb.h if BUILD_CRYPTOAUTHLIB nobase_include_HEADERS+= wolfssl/wolfcrypt/port/atmel/atmel.h diff --git a/wolfssl/wolfcrypt/port/maxim/max3266x-cryptocb.h b/wolfssl/wolfcrypt/port/maxim/max3266x-cryptocb.h new file mode 100644 index 000000000..371af11ed --- /dev/null +++ b/wolfssl/wolfcrypt/port/maxim/max3266x-cryptocb.h @@ -0,0 +1,70 @@ +/* max3266x-cryptocb.h + * + * Copyright (C) 2006-2024 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 + */ + +#ifndef _WOLFPORT_MAX3266X_CRYPTO_CB_H_ +#define _WOLFPORT_MAX3266X_CRYPTO_CB_H_ + +#if (defined(WOLFSSL_MAX3266X) || defined(WOLFSSL_MAX3266X_OLD)) && \ + defined(WOLF_CRYPTO_CB) + +#ifndef WOLFSSL_MAX3266X_DEVID + #define WOLFSSL_MAX3266X_DEVID 9 +#endif +#ifndef MAX_CRYPTO_DEVID_CALLBACKS + #define MAX_CRYPTO_DEVID_CALLBACKS WOLFSSL_MAX3266X_DEVID +#endif +#define WC_USE_DEVID WOLFSSL_MAX3266X_DEVID +#include +#include +#include + +#ifdef __cplusplus + extern "C" { +#endif + + WOLFSSL_LOCAL int wc_MxcCryptoCb(int devIdArg, wc_CryptoInfo* info, + void* ctx); +#ifdef HAVE_AES_ECB + WOLFSSL_LOCAL int wc_MxcCb_AesEcbEncrypt(Aes* aes, byte* out, + const byte* in, word32 sz); +#endif +#ifdef HAVE_AES_CBC + WOLFSSL_LOCAL int wc_MxcCb_AesCbcEncrypt(Aes* aes, byte* out, + const byte* in, word32 sz); +#endif + +#ifdef HAVE_AES_DECRYPT +#ifdef HAVE_AES_ECB + WOLFSSL_LOCAL int wc_MxcCb_AesEcbDecrypt(Aes* aes, byte* out, + const byte* in, word32 sz); +#endif +#ifdef HAVE_AES_CBC + WOLFSSL_LOCAL int wc_MxcCb_AesCbcDecrypt(Aes* aes, byte* out, + const byte* in, word32 sz); +#endif +#endif /* HAVE_AES_DECRYPT */ + +#ifdef __cplusplus + } /* extern "C" */ +#endif + +#endif /* (WOLFSSL_MAX3266X || WOLFSSL_MAX3266X_OLD) && WOLF_CRYPTO_CB) */ +#endif /* _WOLFPORT_MAX3266X_CRYPTO_CB_H_ */ diff --git a/wolfssl/wolfcrypt/port/maxim/max3266x.h b/wolfssl/wolfcrypt/port/maxim/max3266x.h index 5fa12a1be..39c79b9c0 100644 --- a/wolfssl/wolfcrypt/port/maxim/max3266x.h +++ b/wolfssl/wolfcrypt/port/maxim/max3266x.h @@ -41,6 +41,21 @@ #define MAX3266X_MATH #endif +/* Some extra conditions when using callbacks */ +#if defined(WOLF_CRYPTO_CB) + #define MAX3266X_CB +#endif + +/* Crypto HW can be used in parallel on this device */ +/* Sets up new Mutexing if desired */ +#ifdef WOLFSSL_ALGO_HW_MUTEX + /* SDK only supports using RNG in parallel with crypto HW */ + /* AES, HASH, and PK must share some mutex */ + #define NO_AES_MUTEX + #define NO_HASH_MUTEX + #define NO_PK_MUTEX +#endif /* WOLFSSL_ALGO_HW_MUTEX */ + #if defined(WOLFSSL_MAX3266X_OLD) /* Support for older SDK API Maxim provides */ @@ -198,14 +213,15 @@ MXC_TPU_MODE_TYPE mode, unsigned int data_size, unsigned char* out, unsigned int keySize); - +#ifdef HAVE_AES_DECRYPT WOLFSSL_LOCAL int wc_MXC_TPU_AesDecrypt(const unsigned char* in, const unsigned char* iv, const unsigned char* enc_key, MXC_TPU_MODE_TYPE mode, unsigned int data_size, unsigned char* out, unsigned int keySize); -#endif +#endif /* HAVE_AES_DECRYPT */ +#endif /* MAX3266X_AES */ #ifdef MAX3266X_SHA @@ -214,6 +230,13 @@ unsigned int used; unsigned int size; unsigned char hash[WOLFSSL_MAX_HASH_SIZE]; + #ifdef WOLF_CRYPTO_CB + int devId; + void* devCtx; /* generic crypto callback context */ + #endif + #ifdef WOLFSSL_HASH_FLAGS + unsigned int flags; /* enum wc_HashFlags in hash.h */ + #endif } wc_MXC_Sha; #if !defined(NO_SHA) diff --git a/wolfssl/wolfcrypt/wc_port.h b/wolfssl/wolfcrypt/wc_port.h index 7f39ce726..58aba6bec 100644 --- a/wolfssl/wolfcrypt/wc_port.h +++ b/wolfssl/wolfcrypt/wc_port.h @@ -448,6 +448,74 @@ WOLFSSL_LOCAL void wolfSSL_RefDec(wolfSSL_Ref* ref, int* isZero, int* err); #define wolfSSL_CryptHwMutexUnLock() (void)0 /* Success */ #endif /* WOLFSSL_CRYPT_HW_MUTEX */ +#if defined(WOLFSSL_ALGO_HW_MUTEX) && (defined(NO_RNG_MUTEX) && \ + defined(NO_AES_MUTEX) && defined(NO_HASH_MUTEX) && defined(NO_PK_MUTEX)) + #error WOLFSSL_ALGO_HW_MUTEX does not support having all mutexs off +#endif +/* To support HW that can do different Crypto in parallel */ +#if WOLFSSL_CRYPT_HW_MUTEX && defined(WOLFSSL_ALGO_HW_MUTEX) + typedef enum { + #ifndef NO_RNG_MUTEX + rng_mutex, + #endif + #ifndef NO_AES_MUTEX + aes_mutex, + #endif + #ifndef NO_HASH_MUTEX + hash_mutex, + #endif + #ifndef NO_PK_MUTEX + pk_mutex, + #endif + } hw_mutex_algo; +#endif + +/* If algo mutex is off, or WOLFSSL_ALGO_HW_MUTEX is not define, default */ +/* to using the generic wolfSSL_CryptHwMutex */ +#if (!defined(NO_RNG_MUTEX) && defined(WOLFSSL_ALGO_HW_MUTEX)) && \ + WOLFSSL_CRYPT_HW_MUTEX + int wolfSSL_HwRngMutexInit(void); + int wolfSSL_HwRngMutexLock(void); + int wolfSSL_HwRngMutexUnLock(void); +#else + #define wolfSSL_HwRngMutexInit wolfSSL_CryptHwMutexInit + #define wolfSSL_HwRngMutexLock wolfSSL_CryptHwMutexLock + #define wolfSSL_HwRngMutexUnLock wolfSSL_CryptHwMutexUnLock +#endif /* !defined(NO_RNG_MUTEX) && defined(WOLFSSL_ALGO_HW_MUTEX) */ + +#if (!defined(NO_AES_MUTEX) && defined(WOLFSSL_ALGO_HW_MUTEX)) && \ + WOLFSSL_CRYPT_HW_MUTEX + int wolfSSL_HwAesMutexInit(void); + int wolfSSL_HwAesMutexLock(void); + int wolfSSL_HwAesMutexUnLock(void); +#else + #define wolfSSL_HwAesMutexInit wolfSSL_CryptHwMutexInit + #define wolfSSL_HwAesMutexLock wolfSSL_CryptHwMutexLock + #define wolfSSL_HwAesMutexUnLock wolfSSL_CryptHwMutexUnLock +#endif /* !defined(NO_AES_MUTEX) && defined(WOLFSSL_ALGO_HW_MUTEX) */ + +#if (!defined(NO_HASH_MUTEX) && defined(WOLFSSL_ALGO_HW_MUTEX)) && \ + WOLFSSL_CRYPT_HW_MUTEX + int wolfSSL_HwHashMutexInit(void); + int wolfSSL_HwHashMutexLock(void); + int wolfSSL_HwHashMutexUnLock(void); +#else + #define wolfSSL_HwHashMutexInit wolfSSL_CryptHwMutexInit + #define wolfSSL_HwHashMutexLock wolfSSL_CryptHwMutexLock + #define wolfSSL_HwHashMutexUnLock wolfSSL_CryptHwMutexUnLock +#endif /* !defined(NO_HASH_MUTEX) && defined(WOLFSSL_ALGO_HW_MUTEX) */ + +#if (!defined(NO_PK_MUTEX) && defined(WOLFSSL_ALGO_HW_MUTEX)) && \ + WOLFSSL_CRYPT_HW_MUTEX + int wolfSSL_HwPkMutexInit(void); + int wolfSSL_HwPkMutexLock(void); + int wolfSSL_HwPkMutexUnLock(void); +#else + #define wolfSSL_HwPkMutexInit wolfSSL_CryptHwMutexInit + #define wolfSSL_HwPkMutexLock wolfSSL_CryptHwMutexLock + #define wolfSSL_HwPkMutexUnLock wolfSSL_CryptHwMutexUnLock +#endif /* !defined(NO_PK_MUTEX) && defined(WOLFSSL_ALGO_HW_MUTEX) */ + /* Mutex functions */ WOLFSSL_API int wc_InitMutex(wolfSSL_Mutex* m); WOLFSSL_API wolfSSL_Mutex* wc_InitAndAllocMutex(void);