diff --git a/IDE/Espressif/ESP-IDF/user_settings.h b/IDE/Espressif/ESP-IDF/user_settings.h index 7c512dc469..1a9b8e6841 100644 --- a/IDE/Espressif/ESP-IDF/user_settings.h +++ b/IDE/Espressif/ESP-IDF/user_settings.h @@ -38,6 +38,18 @@ /* #define DEBUG_WOLFSSL_VERBOSE */ +// Enable key generation: +// https://www.wolfssl.com/documentation/manuals/wolfssl/chapter07.html#rsa-key-generation +#define WOLFSSL_KEY_GEN + +// Enable certificate generation: +// https://www.wolfssl.com/documentation/manuals/wolfssl/chapter07.html#certificate-generation +#define WOLFSSL_CERT_GEN + +// Enable certificate request generation: +// https://www.wolfssl.com/documentation/manuals/wolfssl/chapter07.html#certificate-signing-request-csr-generation +#define WOLFSSL_CERT_REQ + #define BENCH_EMBEDDED #define USE_CERT_BUFFERS_2048 @@ -60,7 +72,13 @@ #define HAVE_ECC #define HAVE_CURVE25519 #define CURVE25519_SMALL -#define HAVE_ED25519 + +// ED25519 test fails on ESP32 & ESP32s3 +// #define HAVE_ED25519 + +/* AES-192 is not supported on the ESP32s3; is available for ESP32 + * and may be available for other devices. */ +#define NO_AES_192 /* when you want to use pkcs7 */ /* #define HAVE_PKCS7 */ diff --git a/wolfcrypt/src/aes.c b/wolfcrypt/src/aes.c index 13e8fbbf68..a514bfe877 100644 --- a/wolfcrypt/src/aes.c +++ b/wolfcrypt/src/aes.c @@ -2676,6 +2676,23 @@ static WARN_UNUSED_RESULT int wc_AesDecrypt( return BAD_FUNC_ARG; } +#if !defined(WOLFSSL_AES_128) + if (keylen == 16) { + return BAD_FUNC_ARG; + } +#endif + +#if !defined(WOLFSSL_AES_192) + if (keylen == 24) { + return BAD_FUNC_ARG; + } +#endif +#if !defined(WOLFSSL_AES_256) + if (keylen == 32) { + return BAD_FUNC_ARG; + } +#endif + aes->keylen = keylen; aes->rounds = keylen/4 + 6; diff --git a/wolfcrypt/src/port/Espressif/README.md b/wolfcrypt/src/port/Espressif/README.md index fe98e3be65..d57bbc654f 100644 --- a/wolfcrypt/src/port/Espressif/README.md +++ b/wolfcrypt/src/port/Espressif/README.md @@ -1,6 +1,9 @@ # ESP32 Port Support for the ESP32-WROOM-32 on-board crypto hardware acceleration for symmetric AES, SHA1/SHA256/SHA384/SHA512 and RSA primitive including mul, mulmod and exptmod. +Supported hardware includes: +* ESP32 +* ESP32s3 ## ESP32 Acceleration diff --git a/wolfcrypt/src/port/Espressif/esp32_aes.c b/wolfcrypt/src/port/Espressif/esp32_aes.c index 66d5830733..d3f13c7734 100644 --- a/wolfcrypt/src/port/Espressif/esp32_aes.c +++ b/wolfcrypt/src/port/Espressif/esp32_aes.c @@ -38,7 +38,8 @@ #include #include "wolfssl/wolfcrypt/port/Espressif/esp32-crypt.h" - +#include + static const char* TAG = "wolf_hw_aes"; /* mutex */ @@ -56,7 +57,6 @@ static int espaes_CryptHwMutexInit = 0; static int esp_aes_hw_InUse() { int ret = 0; - printf("esp_aes_hw_InUse\n"); ESP_LOGV(TAG, "enter esp_aes_hw_InUse"); @@ -114,8 +114,9 @@ static void esp_aes_hw_Leave( void ) /* * set key to hardware key registers. + * return 0 on success; -1 if mode isn't supported. */ -static void esp_aes_hw_Set_KeyMode(Aes *ctx, ESP32_AESPROCESS mode) +static int esp_aes_hw_Set_KeyMode(Aes *ctx, ESP32_AESPROCESS mode) { word32 i; word32 mode_ = 0; @@ -132,7 +133,7 @@ static void esp_aes_hw_Set_KeyMode(Aes *ctx, ESP32_AESPROCESS mode) } else { ESP_LOGE(TAG, " >> unexpected error."); - return; + return -1; } } @@ -161,10 +162,13 @@ static void esp_aes_hw_Set_KeyMode(Aes *ctx, ESP32_AESPROCESS mode) if (mode_ == 1 || mode_ == 5 || mode_ == 7) { ESP_LOGE(TAG, " unsupported mode"); + return -1; } #endif DPORT_REG_WRITE(AES_MODE_REG, mode_); ESP_LOGV(TAG, " leave esp_aes_hw_Setkey"); + + return 0; } /* @@ -232,6 +236,7 @@ static void esp_aes_bk(const byte* in, byte* out) * @param in : a pointer of the input buffer containing plain text to be encrypted * @param out: a pointer of the output buffer in which to store the cipher text of * the encrypted message +* @return: 0 on success, BAD_FUNC_ARG if the AES algorithm isn't supported. */ int wc_esp32AesEncrypt(Aes *aes, const byte* in, byte* out) { @@ -239,7 +244,12 @@ int wc_esp32AesEncrypt(Aes *aes, const byte* in, byte* out) /* lock the hw engine */ esp_aes_hw_InUse(); /* load the key into the register */ - esp_aes_hw_Set_KeyMode(aes, ESP32_AES_UPDATEKEY_ENCRYPT); + if (0 != esp_aes_hw_Set_KeyMode(aes, ESP32_AES_UPDATEKEY_ENCRYPT)) + { + /* release hw */ + esp_aes_hw_Leave(); + return BAD_FUNC_ARG; + } /* process a one block of AES */ esp_aes_bk(in, out); /* release hw */ @@ -254,6 +264,7 @@ int wc_esp32AesEncrypt(Aes *aes, const byte* in, byte* out) * @param in : a pointer of the input buffer containing plain text to be decrypted * @param out: a pointer of the output buffer in which to store the cipher text of * the decrypted message +* @return: 0 on success, BAD_FUNC_ARG if the AES algorithm isn't supported. */ int wc_esp32AesDecrypt(Aes *aes, const byte* in, byte* out) { @@ -261,7 +272,12 @@ int wc_esp32AesDecrypt(Aes *aes, const byte* in, byte* out) /* lock the hw engine */ esp_aes_hw_InUse(); /* load the key into the register */ - esp_aes_hw_Set_KeyMode(aes, ESP32_AES_UPDATEKEY_DECRYPT); + if (0 != esp_aes_hw_Set_KeyMode(aes, ESP32_AES_UPDATEKEY_DECRYPT)) + { + /* release hw */ + esp_aes_hw_Leave(); + return BAD_FUNC_ARG; + } /* process a one block of AES */ esp_aes_bk(in, out); /* release hw engine */ @@ -279,6 +295,7 @@ int wc_esp32AesDecrypt(Aes *aes, const byte* in, byte* out) * the encrypted message * @param in : a pointer of the input buffer containing plain text to be encrypted * @param sz : size of input message +* @return: 0 on success, BAD_FUNC_ARG if the AES algorithm isn't supported. */ int wc_esp32AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz) { @@ -294,7 +311,12 @@ int wc_esp32AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz) esp_aes_hw_InUse(); - esp_aes_hw_Set_KeyMode(aes, ESP32_AES_UPDATEKEY_ENCRYPT); + if (0 != esp_aes_hw_Set_KeyMode(aes, ESP32_AES_UPDATEKEY_ENCRYPT)) + { + /* release hw */ + esp_aes_hw_Leave(); + return BAD_FUNC_ARG; + } while (blocks--) { XMEMCPY(temp_block, in + offset, AES_BLOCK_SIZE); @@ -325,6 +347,7 @@ int wc_esp32AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz) * the decrypted message * @param in : a pointer of the input buffer containing plain text to be decrypted * @param sz : size of input message +* @return: 0 on success, BAD_FUNC_ARG if the AES algorithm isn't supported. */ int wc_esp32AesCbcDecrypt(Aes* aes, byte* out, const byte* in, word32 sz) { @@ -340,7 +363,12 @@ int wc_esp32AesCbcDecrypt(Aes* aes, byte* out, const byte* in, word32 sz) esp_aes_hw_InUse(); - esp_aes_hw_Set_KeyMode(aes, ESP32_AES_UPDATEKEY_DECRYPT); + if (0 != esp_aes_hw_Set_KeyMode(aes, ESP32_AES_UPDATEKEY_DECRYPT)) + { + /* release hw */ + esp_aes_hw_Leave(); + return BAD_FUNC_ARG; + } while (blocks--) { XMEMCPY(temp_block, in + offset, AES_BLOCK_SIZE); diff --git a/wolfcrypt/src/port/Espressif/esp32_mp.c b/wolfcrypt/src/port/Espressif/esp32_mp.c index 4e1fa3c3a3..48780fb6ce 100644 --- a/wolfcrypt/src/port/Espressif/esp32_mp.c +++ b/wolfcrypt/src/port/Espressif/esp32_mp.c @@ -48,6 +48,7 @@ static const char* const TAG = "wolfssl_mp"; #define ESP_HW_RSAMIN_BIT 512 #define BYTE_TO_WORDS(s) (((s+3)>>2)) /* (s+(4-1))/ 4 */ #define BITS_TO_WORDS(s) (((s+31)>>3)>>2) /* (s+(32-1))/ 8/ 4*/ +#define BITS_IN_ONE_WORD 32 #define MP_NG -1 @@ -146,7 +147,7 @@ static int esp_mp_hw_lock() /* Activate teh RSA accelerator. See §20.3 of ESP32-S3 technical manual. * periph_module_enable doesn't seem to be documented and in private folder * with v5 release. Maybe it will be deprecated? */ - DPORT_REG_SET_BIT(SYSTEM_CRYPTO_RSA_CLK_EN, SYSTEM_PERIP_CLK_EN1_REG); + periph_module_enable(PERIPH_RSA_MODULE); /* clear bit to enable hardware operation; (set to disable) */ DPORT_REG_CLR_BIT(SYSTEM_RSA_PD_CTRL_REG, SYSTEM_RSA_MEM_PD); @@ -175,7 +176,7 @@ static void esp_mp_hw_unlock( void ) * periph_module_enable doesn't seem to be documented and in private folder * with v5 release. Maybe it will be deprecated? */ DPORT_REG_SET_BIT(SYSTEM_RSA_PD_CTRL_REG, SYSTEM_RSA_MEM_PD); - DPORT_REG_CLR_BIT(SYSTEM_CRYPTO_RSA_CLK_EN, SYSTEM_PERIP_CLK_EN1_REG); + periph_module_disable(PERIPH_RSA_MODULE); #else /* set bit to disabled hardware operation; (clear to enable) @@ -237,12 +238,8 @@ static int wait_until_done(word32 reg) /* wait */ } -#if CONFIG_IDF_TARGET_ESP32S3 - // ESP32S3 doesn't use interrupt register for completion. -#else /* clear interrupt */ DPORT_REG_WRITE(RSA_INTERRUPT_REG, 1); -#endif if (ESP_TIMEOUT(timeout)) { ESP_LOGE(TAG, "rsa operation is timed out."); @@ -328,40 +325,36 @@ int esp_mp_mul(fp_int* X, fp_int* Y, fp_int* Z) { int ret = 0; int neg = (X->sign == Y->sign)? MP_ZPOS : MP_NEG; + +#if CONFIG_IDF_TARGET_ESP32S3 + + int nBitsInX = mp_count_bits(X); + int nBitsInY = mp_count_bits(Y); + + /* X & Y must be represented by the same number of bits. Must be + * enough to represent the larger one. */ + int nMinXYBits = max(nBitsInX, nBitsInY); + + /* Figure out how many words we need to represent each operand & the result. */ + int nWordsForOperand = bits2words(nMinXYBits); + int nWordsForResult = bits2words(nBitsInX + nBitsInY); - word32 Xs; - word32 Ys; - word32 Zs; - word32 maxWords_sz; - word32 hwWords_sz; - - /* ask bits number */ - Xs = mp_count_bits(X); - Ys = mp_count_bits(Y); - Zs = Xs + Ys; - - /* maximum bits and words for writing to hw */ - maxWords_sz = bits2words(max(Xs, Ys)); - hwWords_sz = words2hwords(maxWords_sz); - - /* sanity check */ - if((hwWords_sz<<5) > ESP_HW_MULTI_RSAMAX_BITS) { - ESP_LOGW(TAG, "exceeds max bit length(2048)"); - return -2; + /* Make sure we are within capabilities of hardware. */ + if ((nWordsForOperand * 8) > ESP_HW_MULTI_RSAMAX_BITS) { + ESP_LOGW(TAG, "exceeds max bit length(2048)"); + return -2; } -#if CONFIG_IDF_TARGET_ESP32S3 /* Steps to perform large number multiplication. Calculates Z = X x Y. The number of * bits in the operands (X, Y) is N. N can be 32x, where x = {1,2,3,...64}, so the * maximum number of bits in the X and Y is 2048. * See §20.3.3 of ESP32-S3 technical manual * 1. Lock the hardware so no-one else uses it and wait until it is ready. * 2. Enable/disable interrupt that signals completion -- we don't use the interrupt. - * 3. Write (N_result_bits/32 - 1) to the RSA_MODE_REG (now called RSA_LENGTH_REG). - * Here N_result_bits is the number of bits in the multiplication result, which - * is 2x the number of bits in the operands. + * 3. Write number of words required for result to the RSA_MODE_REG (now called RSA_LENGTH_REG). + * Number of words required for the result is 2 * words for operand - 1 * 4. Load X, Y operands to memory blocks. Note the Y value must be written to - * offset of 4 x N_bits_Y + * right aligned. * 5. Start the operation by writing 1 to RSA_MULT_START_REG, then wait for it * to complete by monitoring RSA_IDLE_REG (which is now called RSA_QUERY_INTERRUPT_REG). * 6. Read the result out. @@ -378,21 +371,21 @@ int esp_mp_mul(fp_int* X, fp_int* Y, fp_int* Z) /* 2. Disable completion interrupt singal; we don't use. */ DPORT_REG_WRITE(RSA_INTERRUPT_REG, 0); // 0 => no interrupt; 1 => interrupt on completion. - /* 3. Write (N_result_bits/32 - 1) to the RSA_MODE_REG. */ - uint32_t uResultBits = max(Xs, Ys) * 2; - if (uResultBits > ESP_HW_RSAMAX_BIT) + /* 3. Write number of words required for result. */ + if (nWordsForOperand * 2 > ESP_HW_RSAMAX_BIT) { ESP_LOGW(TAG, "result exceeds max bit length"); return -2; } - DPORT_REG_WRITE(RSA_LENGTH_REG, (uResultBits / 32) - 1); + DPORT_REG_WRITE(RSA_LENGTH_REG, (nWordsForOperand * 2 - 1) ); /* 4. Load X, Y operands. Maximum is 64 words (64*8*4 = 2048 bits) */ - esp_mpint_to_memblock(RSA_MEM_X_BLOCK_BASE, X, Xs, hwWords_sz); - esp_mpint_to_memblock(RSA_MEM_Z_BLOCK_BASE + (hwWords_sz << 2), Y, Ys, hwWords_sz); + esp_mpint_to_memblock(RSA_MEM_X_BLOCK_BASE, X, nBitsInX, nWordsForOperand); + esp_mpint_to_memblock(RSA_MEM_Z_BLOCK_BASE + nWordsForOperand * 4, Y, nBitsInY, nWordsForOperand); + /* 5. Start operation and wait until it completes. */ - DPORT_REG_WRITE(RSA_MULT_START_REG, 1); + process_start(RSA_MULT_START_REG); ret = wait_until_done(RSA_QUERY_INTERRUPT_REG); if (MP_OKAY != ret) { @@ -400,7 +393,7 @@ int esp_mp_mul(fp_int* X, fp_int* Y, fp_int* Z) } /* 6. read the result form MEM_Z */ - esp_memblock_to_mpint(RSA_MEM_Z_BLOCK_BASE, Z, BITS_TO_WORDS(Zs)); + esp_memblock_to_mpint(RSA_MEM_Z_BLOCK_BASE, Z, nWordsForResult); /* 7. clear and release hw */ esp_mp_hw_unlock(); @@ -409,6 +402,27 @@ int esp_mp_mul(fp_int* X, fp_int* Y, fp_int* Z) return ret; #else + word32 Xs; + word32 Ys; + word32 Zs; + word32 maxWords_sz; + word32 hwWords_sz; + + /* ask bits number */ + Xs = mp_count_bits(X); + Ys = mp_count_bits(Y); + Zs = Xs + Ys; + + /* maximum bits and words for writing to hw */ + maxWords_sz = bits2words(max(Xs, Ys)); + hwWords_sz = words2hwords(maxWords_sz); + + /* sanity check */ + if((hwWords_sz<<5) > ESP_HW_MULTI_RSAMAX_BITS) { + ESP_LOGW(TAG, "exceeds max bit length(2048)"); + return -2; + } + /*Steps to use hw in the following order: * 1. wait until clean hw engine * 2. Write(2*N/512bits - 1 + 8) to MULT_MODE_REG @@ -504,13 +518,19 @@ int esp_mp_mulmod(fp_int* X, fp_int* Y, fp_int* M, fp_int* Z) * where: R = b^n, and b = 2^32 * accordingly R^2 = 2^(n*32*2) */ +#if CONFIG_IDF_TARGET_ESP32S3 + word32 Exponent = maxWords_sz * BITS_IN_ONE_WORD * 2; +#else + word32 Exponent = hwWords_sz << 6; +#endif ret = mp_init_multi(&tmpZ, &r_inv, NULL, NULL, NULL, NULL); - if (ret == 0 && (ret = esp_get_rinv(&r_inv, M, (hwWords_sz << 6))) != MP_OKAY) { + if (ret == 0 && (ret = esp_get_rinv(&r_inv, M, Exponent)) != MP_OKAY) { ESP_LOGE(TAG, "calculate r_inv failed."); mp_clear(&tmpZ); mp_clear(&r_inv); return ret; } + /* lock hw for use */ if ((ret = esp_mp_hw_lock()) != MP_OKAY) { mp_clear(&tmpZ); @@ -524,16 +544,17 @@ int esp_mp_mulmod(fp_int* X, fp_int* Y, fp_int* M, fp_int* Z) mp_clear(&r_inv); return -1; } - + #if CONFIG_IDF_TARGET_ESP32S3 /* Steps to perform large number modular multiplication. Calculates Z = (X x Y) modulo M. * The number of bits in the operands (X, Y) is N. N can be 32x, where x = {1,2,3,...64}, so the - * maximum number of bits in the X and Y is 2048. + * maximum number of bits in the X and Y is 2048. We must use the same number of words to represent + * the bits in X, Y and M. * See §20.3.3 of ESP32-S3 technical manual * 1. Wait until the hardware is ready. * 2. Enable/disable interrupt that signals completion -- we don't use the interrupt. - * 3. Write (N_bits/32 - 1) to the RSA_MODE_REG (now called RSA_LENGTH_REG). - * Here N_bits is the maximum number of bits in X, Y and M. + * 3. Write the number of words required to represent the operands to the + * RSA_MODE_REG (now called RSA_LENGTH_REG). * 4. Write M' value into RSA_M_PRIME_REG (now called RSA_M_DASH_REG). * 5. Load X, Y, M, r' operands to memory blocks. * 6. Start the operation by writing 1 to RSA_MOD_MULT_START_REG, then wait for it @@ -558,19 +579,24 @@ int esp_mp_mulmod(fp_int* X, fp_int* Y, fp_int* M, fp_int* Z) ESP_LOGW(TAG, "result exceeds max bit length"); return -2; } - DPORT_REG_WRITE(RSA_LENGTH_REG, (uOperandBits / 32) - 1); + int nWordsForOperand = bits2words(uOperandBits); + DPORT_REG_WRITE(RSA_LENGTH_REG, nWordsForOperand - 1); /* 4. Write M' value into RSA_M_PRIME_REG (now called RSA_M_DASH_REG) */ DPORT_REG_WRITE(RSA_M_DASH_REG, mp); + + /* Select acceleration options. */ + DPORT_REG_WRITE(RSA_CONSTANT_TIME_REG, 0); - /* 5. Load X, Y, M, r' operands. */ + /* 5. Load X, Y, M, r' operands. + * Note RSA_MEM_RB_BLOCK_BASE == RSA_MEM_Z_BLOC_BASE on ESP32s3*/ esp_mpint_to_memblock(RSA_MEM_X_BLOCK_BASE, X, Xs, hwWords_sz); esp_mpint_to_memblock(RSA_MEM_Y_BLOCK_BASE, Y, Ys, hwWords_sz); esp_mpint_to_memblock(RSA_MEM_M_BLOCK_BASE, M, Ms, hwWords_sz); - esp_mpint_to_memblock(RSA_MEM_Z_BLOCK_BASE, &r_inv, mp_count_bits(&r_inv), hwWords_sz); + esp_mpint_to_memblock(RSA_MEM_RB_BLOCK_BASE, &r_inv, mp_count_bits(&r_inv), hwWords_sz); /* 6. Start operation and wait until it completes. */ - DPORT_REG_WRITE(RSA_MOD_MULT_START_REG, 1); + process_start(RSA_MOD_MULT_START_REG); ret = wait_until_done(RSA_QUERY_INTERRUPT_REG); if (MP_OKAY != ret) { @@ -583,7 +609,9 @@ int esp_mp_mulmod(fp_int* X, fp_int* Y, fp_int* M, fp_int* Z) /* 8. clear and release hw */ esp_mp_hw_unlock(); - // todo: implement work-arounds for known issues with ESP32 version (see below) if needed. + if (negcheck) { + mp_sub(M, &tmpZ, &tmpZ); + } mp_copy(&tmpZ, Z); mp_clear(&tmpZ); @@ -627,6 +655,7 @@ int esp_mp_mulmod(fp_int* X, fp_int* Y, fp_int* M, fp_int* Z) /* step.3 write M' into memory */ DPORT_REG_WRITE(RSA_M_DASH_REG, mp); + /* step.4 start process */ process_start(RSA_MULT_START_REG); @@ -764,7 +793,8 @@ int esp_mp_exptmod(fp_int* X, fp_int* Y, word32 Ys, fp_int* M, fp_int* Z) ESP_LOGW(TAG, "result exceeds max bit length"); return -2; } - DPORT_REG_WRITE(RSA_LENGTH_REG, (uOperandBits / 32) - 1); + int nWordsForOperand = bits2words(uOperandBits); + DPORT_REG_WRITE(RSA_LENGTH_REG, nWordsForOperand - 1); /* 4. Write M' value into RSA_M_PRIME_REG (now called RSA_M_DASH_REG) */ DPORT_REG_WRITE(RSA_M_DASH_REG, mp); @@ -776,7 +806,7 @@ int esp_mp_exptmod(fp_int* X, fp_int* Y, word32 Ys, fp_int* M, fp_int* Z) esp_mpint_to_memblock(RSA_MEM_Z_BLOCK_BASE, &r_inv, mp_count_bits(&r_inv), hwWords_sz); /* 6. Start operation and wait until it completes. */ - DPORT_REG_WRITE(RSA_MODEXP_START_REG, 1); + process_start(RSA_MODEXP_START_REG); ret = wait_until_done(RSA_QUERY_INTERRUPT_REG); if (MP_OKAY != ret) { diff --git a/wolfcrypt/src/port/Espressif/esp32_sha.c b/wolfcrypt/src/port/Espressif/esp32_sha.c index 7574483f89..1cc87c730f 100644 --- a/wolfcrypt/src/port/Espressif/esp32_sha.c +++ b/wolfcrypt/src/port/Espressif/esp32_sha.c @@ -391,7 +391,7 @@ static int esp_sha_start_process(WC_ESP32SHA* sha) sha->mode = ESP32_SHA_FAIL_NEED_UNROLL; return -1; } - + REG_WRITE(SHA_MODE_REG, uHardwareAlgorithm); if (sha->isfirstblock) @@ -509,7 +509,6 @@ static void wc_esp_process_block(WC_ESP32SHA* ctx, /* see ctx->sha_type */ const word32* data, word32 len) { - int i; int word32_to_save = (len) / (sizeof(word32)); ESP_LOGV(TAG, " enter esp_process_block"); if (word32_to_save > 0x31) { @@ -524,16 +523,19 @@ static void wc_esp_process_block(WC_ESP32SHA* ctx, /* see ctx->sha_type */ #if CONFIG_IDF_TARGET_ESP32S3 uint32_t *pMessageSource = (uint32_t *)data; uint32_t *pAcceleratorMessage = (uint32_t *)(SHA_TEXT_BASE); - while(word32_to_save--) + while (word32_to_save--) { - /* Must swap endiness of data loaded into harware accelerator to produce - * correct result. Using DPORT_REG_WRITE doesn't avoid this for ESP32s3. */ - DPORT_REG_WRITE(pAcceleratorMessage, __builtin_bswap32(*pMessageSource)); - ++pAcceleratorMessage; - ++pMessageSource; + /* Must swap endiness of data loaded into harware accelerator to produce + * correct result. Using DPORT_REG_WRITE doesn't avoid this for ESP32s3. + * Note: data sheet claims we also need to swap endian across 64 byte words + * when doing SHA-512, but the SHA-512 result is not correct if you do that. */ + DPORT_REG_WRITE(pAcceleratorMessage, __builtin_bswap32(*pMessageSource)); + ++pAcceleratorMessage; + ++pMessageSource; } - + #else + int i; for (i = 0; i < word32_to_save; i++) { /* by using DPORT_REG_WRITE, we avoid the need * to call __builtin_bswap32 to address endiness @@ -578,20 +580,46 @@ int wc_esp_digest_state(WC_ESP32SHA* ctx, byte* hash) return -1; } +#if CONFIG_IDF_TARGET_ESP32S3 + if (ctx->isfirstblock == 1) + { + /* no hardware use yet. Nothing to do yet */ + return 0; + } + /* wait until idle */ wc_esp_wait_until_idle(); -#if CONFIG_IDF_TARGET_ESP32S3 /* read hash result into buffer & flip endiness */ uint32_t* pHashDestination = (uint32_t*)hash; size_t szHashWords = wc_esp_sha_digest_size(ctx->sha_type) / sizeof(uint32_t); esp_dport_access_read_buffer(pHashDestination, SHA_H_BASE, szHashWords); - while(szHashWords--) + + if (ctx->sha_type == SHA2_512) + { + /* Although we don't have to swap endian on 64-bit words at the input, + * we do for the output. */ + size_t szHash64Words = szHashWords / 2; + uint64_t *pHash64Buffer = (uint64_t*)pHashDestination; + while (szHash64Words--) + { + *pHash64Buffer = __builtin_bswap64(*pHash64Buffer); + ++pHash64Buffer; + } + } + else { - *pHashDestination = __builtin_bswap32(*pHashDestination); - ++pHashDestination; + while (szHashWords--) + { + *pHashDestination = __builtin_bswap32(*pHashDestination); + ++pHashDestination; + } } #else + + /* wait until idle */ + wc_esp_wait_until_idle(); + /* each sha_type register is at a different location */ switch (ctx->sha_type) { case SHA1: @@ -672,7 +700,7 @@ int wc_esp_digest_state(WC_ESP32SHA* ctx, byte* hash) } #endif #endif - + ESP_LOGV(TAG, "leave esp_digest_state"); return 0; } diff --git a/wolfcrypt/src/random.c b/wolfcrypt/src/random.c index 81daadfd1d..4036165c17 100644 --- a/wolfcrypt/src/random.c +++ b/wolfcrypt/src/random.c @@ -3397,6 +3397,7 @@ int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz) /* Espressif ESP32 */ #include + #include int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz) { diff --git a/wolfssl/wolfcrypt/port/Espressif/esp32-crypt.h b/wolfssl/wolfcrypt/port/Espressif/esp32-crypt.h index 32d4107dee..7ac9e596ac 100644 --- a/wolfssl/wolfcrypt/port/Espressif/esp32-crypt.h +++ b/wolfssl/wolfcrypt/port/Espressif/esp32-crypt.h @@ -51,7 +51,9 @@ #include "driver/periph_ctrl.h" #endif -#if ESP_IDF_VERSION_MAJOR >= 4 +#if ESP_IDF_VERSION_MAJOR >= 5 + // ets_sys.h isn't required for ESP32; breaks ESP32s3 build. +#elif ESP_IDF_VERSION_MAJOR >= 4 #include #else #include