forked from wolfSSL/wolfssl
Espressif HW acceleration update & cleanup
This commit is contained in:
@ -1,6 +1,24 @@
|
||||
#
|
||||
# Copyright (C) 2014-2022 wolfSSL Inc.
|
||||
#
|
||||
# This file is part of wolfSSH.
|
||||
#
|
||||
# wolfSSH 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 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# wolfSSH 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 wolfSSH. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
#
|
||||
# cmake for wolfssl
|
||||
#
|
||||
#
|
||||
cmake_minimum_required(VERSION 3.5)
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DWOLFSSL_USER_SETTINGS")
|
||||
|
||||
@ -12,15 +30,24 @@ set(COMPONENT_SRCDIRS "./src/"
|
||||
"./wolfcrypt/src/"
|
||||
"./wolfcrypt/src/port/Espressif/"
|
||||
"./wolfcrypt/src/port/atmel/"
|
||||
# "$ENV{IDF_PATH}/components/soc/esp32s3/include/soc"
|
||||
)
|
||||
|
||||
set(COMPONENT_REQUIRES lwip)
|
||||
|
||||
|
||||
# RTOS_IDF_PATH is typically:
|
||||
# "/Users/{username}/Desktop/esp-idf/components/freertos/include/freertos"
|
||||
# depending on the environment, we may need to swap backslashes with forward slashes
|
||||
string(REPLACE "\\" "/" RTOS_IDF_PATH "$ENV{IDF_PATH}/components/freertos/include/freertos")
|
||||
# ESP-IDF after version 4.4x has a different RTOS directory structure
|
||||
string(REPLACE "\\" "/" RTOS_IDF_PATH5 "$ENV{IDF_PATH}/components/freertos/FreeRTOS-Kernel/include/freertos")
|
||||
|
||||
if(IS_DIRECTORY ${IDF_PATH}/components/freertos/FreeRTOS-Kernel/)
|
||||
set(COMPONENT_ADD_INCLUDEDIRS
|
||||
"."
|
||||
"./include"
|
||||
"../freertos/FreeRTOS-Kernel/include/freertos"
|
||||
"${RTOS_IDF_PATH5}"
|
||||
"${WOLFSSL_ROOT}"
|
||||
)
|
||||
else()
|
||||
@ -28,7 +55,7 @@ else()
|
||||
set(COMPONENT_ADD_INCLUDEDIRS
|
||||
"."
|
||||
"./include"
|
||||
"../freertos/include/freertos"
|
||||
"${RTOS_IDF_PATH}"
|
||||
"${WOLFSSL_ROOT}"
|
||||
)
|
||||
endif()
|
||||
@ -49,3 +76,11 @@ set(COMPONENT_SRCEXCLUDE
|
||||
)
|
||||
|
||||
register_component()
|
||||
|
||||
# check to see if there's both a local copy and EDP-IDF copy of the wolfssl components
|
||||
if( EXISTS "${CMAKE_HOME_DIRECTORY}/components/wolfssl/" AND EXISTS "$ENV{IDF_PATH}/components/wolfssl/" )
|
||||
message(STATUS "")
|
||||
message(STATUS "WARNING: Found components/wolfssl in both local project and IDF_PATH")
|
||||
message(STATUS "")
|
||||
endif()
|
||||
# end multiple component check
|
||||
|
@ -1,17 +1,37 @@
|
||||
#
|
||||
# Component Makefile
|
||||
#
|
||||
|
||||
COMPONENT_ADD_INCLUDEDIRS := . ./include
|
||||
COMPONENT_ADD_INCLUDEDIRS += ../freertos/include/freertos/
|
||||
|
||||
COMPONENT_SRCDIRS := src wolfcrypt/src
|
||||
COMPONENT_SRCDIRS += wolfcrypt/src/port/Espressif
|
||||
COMPONENT_SRCDIRS += wolfcrypt/src/port/atmel
|
||||
|
||||
CFLAGS +=-DWOLFSSL_USER_SETTINGS
|
||||
|
||||
COMPONENT_OBJEXCLUDE := wolfcrypt/src/aes_asm.o
|
||||
COMPONENT_OBJEXCLUDE += wolfcrypt/src/evp.o
|
||||
COMPONENT_OBJEXCLUDE += wolfcrypt/src/misc.o
|
||||
COMPONENT_OBJEXCLUDE += src/bio.o
|
||||
#
|
||||
# Copyright (C) 2014-2022 wolfSSL Inc.
|
||||
#
|
||||
# This file is part of wolfSSH.
|
||||
#
|
||||
# wolfSSH 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 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# wolfSSH 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 wolfSSH. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
#
|
||||
# Component Makefile
|
||||
#
|
||||
|
||||
COMPONENT_ADD_INCLUDEDIRS := . ./include
|
||||
|
||||
COMPONENT_ADD_INCLUDEDIRS += "$ENV{IDF_PATH}/components/freertos/include/freertos"
|
||||
# COMPONENT_ADD_INCLUDEDIRS += "$ENV{IDF_PATH}/soc/esp32s3/include/soc"
|
||||
|
||||
COMPONENT_SRCDIRS := src wolfcrypt/src
|
||||
COMPONENT_SRCDIRS += wolfcrypt/src/port/Espressif
|
||||
COMPONENT_SRCDIRS += wolfcrypt/src/port/atmel
|
||||
|
||||
CFLAGS +=-DWOLFSSL_USER_SETTINGS
|
||||
|
||||
COMPONENT_OBJEXCLUDE := wolfcrypt/src/aes_asm.o
|
||||
COMPONENT_OBJEXCLUDE += wolfcrypt/src/evp.o
|
||||
COMPONENT_OBJEXCLUDE += wolfcrypt/src/misc.o
|
||||
COMPONENT_OBJEXCLUDE += src/bio.o
|
||||
|
@ -1,6 +1,6 @@
|
||||
/* user_settings.h
|
||||
*
|
||||
* Copyright (C) 2006-2021 wolfSSL Inc.
|
||||
* Copyright (C) 2006-2022 wolfSSL Inc.
|
||||
*
|
||||
* This file is part of wolfSSL.
|
||||
*
|
||||
@ -19,22 +19,24 @@
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
|
||||
*/
|
||||
#undef WOLFSSL_ESPIDF
|
||||
#undef WOLFSSL_ESPWROOM32
|
||||
#undef WOLFSSL_ESPWROOM32SE
|
||||
#undef WOLFSSL_ESPWROOM32
|
||||
#undef WOLFSSL_ESP8266
|
||||
|
||||
#define WOLFSSL_ESPIDF
|
||||
|
||||
/*
|
||||
* choose ONE of these Espressif chips to define:
|
||||
*
|
||||
*
|
||||
* WOLFSSL_ESPWROOM32
|
||||
* WOLFSSL_ESPWROOM32SE
|
||||
* WOLFSSL_ESP8266
|
||||
*
|
||||
* comment out the others:
|
||||
*/
|
||||
|
||||
#define WOLFSSL_ESPWROOM32
|
||||
/* #define WOLFSSL_ESPWROOM32SE */
|
||||
/* #define WOLFSSL_ESP8266 */
|
||||
|
||||
/* #define DEBUG_WOLFSSL_VERBOSE */
|
||||
|
||||
#define BENCH_EMBEDDED
|
||||
#define USE_CERT_BUFFERS_2048
|
||||
@ -88,7 +90,7 @@
|
||||
/* Define USE_FAST_MATH and SMALL_STACK */
|
||||
#define ESP32_USE_RSA_PRIMITIVE
|
||||
/* threshold for performance adjustment for hw primitive use */
|
||||
/* X bits of G^X mod P greater than */
|
||||
/* X bits of G^X mod P greater than */
|
||||
#define EPS_RSA_EXPT_XBTIS 36
|
||||
/* X and Y of X * Y mod P greater than */
|
||||
#define ESP_RSA_MULM_BITS 2000
|
||||
|
@ -1,6 +1,6 @@
|
||||
/* esp32_aes.c
|
||||
*
|
||||
* Copyright (C) 2006-2021 wolfSSL Inc.
|
||||
* Copyright (C) 2006-2022 wolfSSL Inc.
|
||||
*
|
||||
* This file is part of wolfSSL.
|
||||
*
|
||||
@ -19,6 +19,10 @@
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
|
||||
*/
|
||||
|
||||
/*
|
||||
* WOLFSSL_SUCCESS and WOLFSSL_FAILURE values should only
|
||||
* be used in the ssl layer, not in wolfCrypt
|
||||
**/
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
@ -36,13 +40,18 @@
|
||||
#include "wolfssl/wolfcrypt/port/Espressif/esp32-crypt.h"
|
||||
|
||||
static const char* TAG = "wolf_hw_aes";
|
||||
|
||||
/* mutex */
|
||||
static wolfSSL_Mutex aes_mutex;
|
||||
|
||||
/* keep track as to whether esp aes is initialized */
|
||||
static int espaes_CryptHwMutexInit = 0;
|
||||
|
||||
/*
|
||||
* lock hw engine.
|
||||
* this should be called before using engine.
|
||||
*
|
||||
* returns 0 if the hw lock was initialized and mutex lock
|
||||
*/
|
||||
static int esp_aes_hw_InUse()
|
||||
{
|
||||
@ -50,21 +59,29 @@ static int esp_aes_hw_InUse()
|
||||
|
||||
ESP_LOGV(TAG, "enter esp_aes_hw_InUse");
|
||||
|
||||
if(espaes_CryptHwMutexInit == 0) {
|
||||
if (espaes_CryptHwMutexInit == 0) {
|
||||
ret = esp_CryptHwMutexInit(&aes_mutex);
|
||||
if(ret == 0){
|
||||
if (ret == 0) {
|
||||
/* flag esp aes as initialized */
|
||||
espaes_CryptHwMutexInit = 1;
|
||||
} else {
|
||||
ESP_LOGE(TAG, "aes mutx initialization failed.");
|
||||
}
|
||||
else {
|
||||
ESP_LOGE(TAG, "aes mutex initialization failed.");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* esp aes has already been initialized */
|
||||
}
|
||||
|
||||
/* lock hardware */
|
||||
ret = esp_CryptHwMutexLock(&aes_mutex, portMAX_DELAY);
|
||||
|
||||
if(ret != 0) {
|
||||
ESP_LOGE(TAG, "aes engine lock failed.");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Enable AES hardware */
|
||||
periph_module_enable(PERIPH_AES_MODULE);
|
||||
|
||||
@ -92,23 +109,27 @@ static void esp_aes_hw_Leave( void )
|
||||
*/
|
||||
static void esp_aes_hw_Set_KeyMode(Aes *ctx, ESP32_AESPROCESS mode)
|
||||
{
|
||||
int i;
|
||||
word32 i;
|
||||
word32 mode_ = 0;
|
||||
|
||||
ESP_LOGV(TAG, "enter esp_aes_hw_Set_KeyMode");
|
||||
ESP_LOGV(TAG, " enter esp_aes_hw_Set_KeyMode");
|
||||
|
||||
/* check mode */
|
||||
if(mode == ESP32_AES_UPDATEKEY_ENCRYPT) {
|
||||
mode_ = 0;
|
||||
} else if(mode == ESP32_AES_UPDATEKEY_DECRYPT){
|
||||
mode_ = 4;
|
||||
} else {
|
||||
ESP_LOGE(TAG, "unexpected error.");
|
||||
return;
|
||||
}
|
||||
else {
|
||||
if (mode == ESP32_AES_UPDATEKEY_DECRYPT) {
|
||||
mode_ = 4;
|
||||
}
|
||||
else {
|
||||
ESP_LOGE(TAG, " >> unexpected error.");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* update key */
|
||||
for(i=0;i<(ctx->keylen)/sizeof(word32);i++){
|
||||
for(i=0; i<(ctx->keylen)/sizeof(word32); i++){
|
||||
DPORT_REG_WRITE(AES_KEY_BASE + (i*4), *(((word32*)ctx->key) + i));
|
||||
}
|
||||
|
||||
@ -127,7 +148,7 @@ static void esp_aes_hw_Set_KeyMode(Aes *ctx, ESP32_AESPROCESS mode)
|
||||
}
|
||||
|
||||
DPORT_REG_WRITE(AES_MODE_REG, mode_);
|
||||
ESP_LOGV(TAG, "leave esp_aes_hw_Setkey");
|
||||
ESP_LOGV(TAG, " leave esp_aes_hw_Setkey");
|
||||
}
|
||||
|
||||
/*
|
||||
@ -181,6 +202,7 @@ int wc_esp32AesEncrypt(Aes *aes, const byte* in, byte* out)
|
||||
esp_aes_hw_Leave();
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* wc_esp32AesDecrypt
|
||||
* @brief: a one block decrypt of the input block, into the output block
|
||||
@ -202,6 +224,7 @@ int wc_esp32AesDecrypt(Aes *aes, const byte* in, byte* out)
|
||||
esp_aes_hw_Leave();
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* wc_esp32AesCbcEncrypt
|
||||
* @brief: Encrypts a plain text message from the input buffer, and places the
|
||||
@ -281,8 +304,9 @@ int wc_esp32AesCbcDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
|
||||
esp_aes_bk((in + offset), (out + offset));
|
||||
|
||||
/* XOR block with IV for CBC */
|
||||
for (i = 0; i < AES_BLOCK_SIZE; i++)
|
||||
for (i = 0; i < AES_BLOCK_SIZE; i++) {
|
||||
(out + offset)[i] ^= iv[i];
|
||||
}
|
||||
|
||||
/* store IV for next block */
|
||||
XMEMCPY(iv, temp_block, AES_BLOCK_SIZE);
|
||||
|
@ -1,6 +1,6 @@
|
||||
/* esp32_mp.c
|
||||
*
|
||||
* Copyright (C) 2006-2021 wolfSSL Inc.
|
||||
* Copyright (C) 2006-2022 wolfSSL Inc.
|
||||
*
|
||||
* This file is part of wolfSSL.
|
||||
*
|
||||
@ -58,46 +58,91 @@ static wolfSSL_Mutex mp_mutex;
|
||||
static int espmp_CryptHwMutexInit = 0;
|
||||
/*
|
||||
* check if the hw is ready before accessing it
|
||||
*
|
||||
* When the RSA Accelerator is released from reset, the register RSA_CLEAN_REG
|
||||
* reads 0 and an initialization process begins. Hardware initializes the four
|
||||
* memory blocks by setting them to 0. After initialization is complete,
|
||||
* RSA_CLEAN_REG reads 1. For this reason, software should query RSA_CLEAN_REG
|
||||
* after being released from reset, and before writing to any RSA Accelerator
|
||||
* memory blocks or registers for the first time.
|
||||
*/
|
||||
static int esp_mp_hw_wait_clean()
|
||||
{
|
||||
word32 timeout = 0;
|
||||
while(!ESP_TIMEOUT(++timeout) &&
|
||||
DPORT_REG_READ(RSA_CLEAN_REG) != 1) { }
|
||||
|
||||
if(ESP_TIMEOUT(timeout)) {
|
||||
while(!ESP_TIMEOUT(++timeout) &&
|
||||
DPORT_REG_READ(RSA_CLEAN_REG) != 1) {
|
||||
/* wait. expected delay 1 to 2 uS */
|
||||
}
|
||||
|
||||
if (ESP_TIMEOUT(timeout)) {
|
||||
ESP_LOGE(TAG, "waiting hw ready is timed out.");
|
||||
return MP_NG;
|
||||
}
|
||||
return MP_OKAY;
|
||||
return MP_OKAY;
|
||||
}
|
||||
|
||||
/*
|
||||
* lock hw engine.
|
||||
* this should be called before using engine.
|
||||
*
|
||||
* returns 0 if the hw lock was initialized and mutex lock
|
||||
*
|
||||
* See Chapter 24:
|
||||
* https://www.espressif.com/sites/default/files/documentation/esp32_technical_reference_manual_en.pdf
|
||||
*
|
||||
* The RSA Accelerator is activated by enabling the corresponding peripheral
|
||||
* clock, and by clearing the DPORT_RSA_PD bit in the DPORT_RSA_PD_CTRL_REG
|
||||
* register. This releases the RSA Accelerator from reset.
|
||||
*
|
||||
* When the RSA Accelerator is released from reset, the register RSA_CLEAN_REG
|
||||
* reads 0 and an initialization process begins. Hardware initializes the four
|
||||
* memory blocks by setting them to 0. After initialization is complete,
|
||||
* RSA_CLEAN_REG reads 1. For this reason, software should query RSA_CLEAN_REG
|
||||
* after being released from reset, and before writing to any RSA Accelerator
|
||||
* memory blocks or registers for the first time.
|
||||
*/
|
||||
static int esp_mp_hw_lock()
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
if(espmp_CryptHwMutexInit == 0) {
|
||||
ESP_LOGV(TAG, "enter esp_mp_hw_lock");
|
||||
|
||||
if (espmp_CryptHwMutexInit == 0) {
|
||||
ret = esp_CryptHwMutexInit(&mp_mutex);
|
||||
if(ret == 0){
|
||||
if (ret == 0) {
|
||||
/* flag esp mp as initialized */
|
||||
espmp_CryptHwMutexInit = 1;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
ESP_LOGE(TAG, "mp mutx initialization failed.");
|
||||
return MP_NG;
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* esp aes has already been iniitlized */
|
||||
}
|
||||
|
||||
/* lock hardware */
|
||||
ret = esp_CryptHwMutexLock(&mp_mutex, portMAX_DELAY);
|
||||
if(ret != 0) {
|
||||
|
||||
if (ret != 0) {
|
||||
ESP_LOGE(TAG, "mp engine lock failed.");
|
||||
return MP_NG;
|
||||
}
|
||||
|
||||
/* Enable RSA hardware */
|
||||
periph_module_enable(PERIPH_RSA_MODULE);
|
||||
|
||||
/* clear bit to enable hardware operation; (set to disable)
|
||||
*/
|
||||
DPORT_REG_CLR_BIT(DPORT_RSA_PD_CTRL_REG, DPORT_RSA_PD);
|
||||
|
||||
/* remionder: wait until RSA_CLEAN_REG reads 1
|
||||
* see esp_mp_hw_wait_clean()
|
||||
*/
|
||||
|
||||
ESP_LOGV(TAG, "leave esp_mp_hw_lock");
|
||||
return ret;
|
||||
}
|
||||
/*
|
||||
@ -105,12 +150,17 @@ static int esp_mp_hw_lock()
|
||||
*/
|
||||
static void esp_mp_hw_unlock( void )
|
||||
{
|
||||
/* set bit to disabled hardware operation; (clear to enable)
|
||||
*/
|
||||
DPORT_REG_SET_BIT(DPORT_RSA_PD_CTRL_REG, DPORT_RSA_PD);
|
||||
|
||||
/* Disable RSA hardware */
|
||||
periph_module_disable(PERIPH_RSA_MODULE);
|
||||
|
||||
/* unlock */
|
||||
esp_CryptHwMutexUnLock(&mp_mutex);
|
||||
}
|
||||
|
||||
/* this is based on an article by Cetin Kaya Koc, A New Algorithm for Inversion*/
|
||||
/* mod p^k, June 28 2017. */
|
||||
static int esp_calc_Mdash(mp_int *M, word32 k, mp_digit* md)
|
||||
@ -126,9 +176,9 @@ static int esp_calc_Mdash(mp_int *M, word32 k, mp_digit* md)
|
||||
bi = b0;
|
||||
x = 0;
|
||||
|
||||
for(i = 0; i < k; i++) {
|
||||
for (i = 0; i < k; i++) {
|
||||
xi = bi % 2;
|
||||
if(xi < 0){
|
||||
if (xi < 0) {
|
||||
xi *= -1;
|
||||
}
|
||||
bi = (bi - N * xi) / 2;
|
||||
@ -138,6 +188,7 @@ static int esp_calc_Mdash(mp_int *M, word32 k, mp_digit* md)
|
||||
*md = ~x + 1;
|
||||
return MP_OKAY;
|
||||
}
|
||||
|
||||
/* start hw process */
|
||||
static void process_start(word32 reg)
|
||||
{
|
||||
@ -146,87 +197,100 @@ static void process_start(word32 reg)
|
||||
/* start process */
|
||||
DPORT_REG_WRITE(reg, 1);
|
||||
}
|
||||
|
||||
/* wait until done */
|
||||
static int wait_uitil_done(word32 reg)
|
||||
{
|
||||
word32 timeout = 0;
|
||||
/* wait until done && not timeout */
|
||||
while(!ESP_TIMEOUT(++timeout) &&
|
||||
DPORT_REG_READ(reg) != 1) { }
|
||||
while (!ESP_TIMEOUT(++timeout) &&
|
||||
DPORT_REG_READ(reg) != 1) {
|
||||
/* wait */
|
||||
}
|
||||
|
||||
/* clear interrupt */
|
||||
DPORT_REG_WRITE(RSA_INTERRUPT_REG, 1);
|
||||
|
||||
if(ESP_TIMEOUT(timeout)) {
|
||||
if (ESP_TIMEOUT(timeout)) {
|
||||
ESP_LOGE(TAG, "rsa operation is timed out.");
|
||||
return MP_NG;
|
||||
}
|
||||
|
||||
return MP_OKAY;
|
||||
}
|
||||
|
||||
/* read data from memory into mp_init */
|
||||
static void esp_memblock_to_mpint(word32 mem_address, mp_int* mp, word32 numwords)
|
||||
static void esp_memblock_to_mpint(word32 mem_address,
|
||||
mp_int* mp,
|
||||
word32 numwords)
|
||||
{
|
||||
esp_dport_access_read_buffer((uint32_t*)mp->dp, mem_address, numwords);
|
||||
mp->used = numwords;
|
||||
}
|
||||
|
||||
/* write mp_init into memory block */
|
||||
/* write mp_init into memory block
|
||||
*/
|
||||
static void esp_mpint_to_memblock(word32 mem_address, const mp_int* mp,
|
||||
const word32 bits,
|
||||
const word32 hwords)
|
||||
{
|
||||
/* init */
|
||||
word32 i;
|
||||
word32 len = (bits / 8 + ((bits & 7) != 0 ? 1 : 0));
|
||||
|
||||
len = (len+sizeof(word32)-1)/sizeof(word32);
|
||||
len = (len + sizeof(word32)-1) / sizeof(word32);
|
||||
|
||||
for(i=0;i < hwords; i++) {
|
||||
if(i < len) {
|
||||
for (i=0; i < hwords; i++) {
|
||||
if (i < len) {
|
||||
DPORT_REG_WRITE(mem_address + (i * sizeof(word32)), mp->dp[i]);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
DPORT_REG_WRITE(mem_address + (i * sizeof(word32)), 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
/* return needed hw words. */
|
||||
/* supported words length */
|
||||
/* words : {16 , 32, 48, 64, 80, 96, 112, 128} */
|
||||
/* bits : {512,1024, 1536, 2048, 2560, 3072, 3584, 4096} */
|
||||
/* return needed hw words.
|
||||
* supported words length
|
||||
* words : {16 , 32, 48, 64, 80, 96, 112, 128}
|
||||
* bits : {512,1024, 1536, 2048, 2560, 3072, 3584, 4096}
|
||||
*/
|
||||
static word32 words2hwords(word32 wd)
|
||||
{
|
||||
const word32 shit_ = 4;
|
||||
const word32 bit_shift = 4;
|
||||
|
||||
return (((wd + 0xf)>>shit_)<<shit_);
|
||||
return (((wd + 0xf) >> bit_shift) << bit_shift);
|
||||
}
|
||||
|
||||
/* count the number of words is needed for bits */
|
||||
static word32 bits2words(word32 bits)
|
||||
{
|
||||
/* 32 bits */
|
||||
const word32 d = sizeof(word32) * WOLFSSL_BIT_SIZE;
|
||||
|
||||
return((bits + (d - 1))/d);
|
||||
return ((bits + (d - 1)) / d);
|
||||
}
|
||||
|
||||
/* get rinv */
|
||||
static int esp_get_rinv(mp_int *rinv, mp_int *M, word32 exp)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
/* 2^(exp)*/
|
||||
if((ret = mp_2expt(rinv, exp)) != MP_OKAY) {
|
||||
if ((ret = mp_2expt(rinv, exp)) != MP_OKAY) {
|
||||
ESP_LOGE(TAG, "failed to calculate mp_2expt()");
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* r_inv = R^2 mod M(=P) */
|
||||
if(ret == 0 && (ret = mp_mod(rinv, M, rinv)) != MP_OKAY){
|
||||
if (ret == 0 && (ret = mp_mod(rinv, M, rinv)) != MP_OKAY) {
|
||||
ESP_LOGE(TAG, "failed to calculate mp_mod()");
|
||||
return ret;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
/* Z = X * Y; */
|
||||
|
||||
/* Z = X * Y; */
|
||||
int esp_mp_mul(fp_int* X, fp_int* Y, fp_int* Z)
|
||||
{
|
||||
int ret = 0;
|
||||
@ -268,34 +332,46 @@ int esp_mp_mul(fp_int* X, fp_int* Y, fp_int* Z)
|
||||
* 9. Release the hw engine
|
||||
*/
|
||||
/* lock hw for use */
|
||||
if((ret = esp_mp_hw_lock()) != MP_OKAY)
|
||||
if ((ret = esp_mp_hw_lock()) != MP_OKAY) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
if((ret = esp_mp_hw_wait_clean()) != MP_OKAY){
|
||||
if((ret = esp_mp_hw_wait_clean()) != MP_OKAY) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* step.1 (2*N/512) => N/256. 512 bits => 16 words */
|
||||
DPORT_REG_WRITE(RSA_MULT_MODE_REG, (hwWords_sz >> 3) - 1 + 8);
|
||||
/* step.2 write X, M and r_inv into memory */
|
||||
esp_mpint_to_memblock(RSA_MEM_X_BLOCK_BASE, X, Xs, hwWords_sz);
|
||||
esp_mpint_to_memblock(RSA_MEM_X_BLOCK_BASE,
|
||||
X,
|
||||
Xs,
|
||||
hwWords_sz);
|
||||
/* Y(let-extend) */
|
||||
esp_mpint_to_memblock(RSA_MEM_Z_BLOCK_BASE + (hwWords_sz<<2), Y, Ys, hwWords_sz);
|
||||
esp_mpint_to_memblock(RSA_MEM_Z_BLOCK_BASE + (hwWords_sz<<2),
|
||||
Y,
|
||||
Ys,
|
||||
hwWords_sz);
|
||||
/* step.3 start process */
|
||||
process_start(RSA_MULT_START_REG);
|
||||
|
||||
/* step.4,5 wait until done */
|
||||
wait_uitil_done(RSA_INTERRUPT_REG);
|
||||
ret = wait_uitil_done(RSA_INTERRUPT_REG);
|
||||
if (ret != MP_OKAY) {
|
||||
ESP_LOGE(TAG, "wait_uitil_done failed.");
|
||||
return ret;
|
||||
}
|
||||
/* step.6 read the result form MEM_Z */
|
||||
esp_memblock_to_mpint(RSA_MEM_Z_BLOCK_BASE, Z, BITS_TO_WORDS(Zs));
|
||||
|
||||
/* step.7 clear and release hw */
|
||||
esp_mp_hw_unlock();
|
||||
|
||||
Z->sign = (Z->used > 0)? neg : MP_ZPOS;
|
||||
Z->sign = (Z->used > 0) ? neg : MP_ZPOS;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Z = X * Y (mod M) */
|
||||
int esp_mp_mulmod(fp_int* X, fp_int* Y, fp_int* M, fp_int* Z)
|
||||
{
|
||||
@ -313,7 +389,7 @@ int esp_mp_mulmod(fp_int* X, fp_int* Y, fp_int* M, fp_int* Z)
|
||||
mp_digit mp;
|
||||
|
||||
/* neg check */
|
||||
if(X->sign != Y->sign) {
|
||||
if (X->sign != Y->sign) {
|
||||
/* X*Y becomes negative */
|
||||
negcheck = 1;
|
||||
}
|
||||
@ -327,7 +403,7 @@ int esp_mp_mulmod(fp_int* X, fp_int* Y, fp_int* M, fp_int* Z)
|
||||
zwords = bits2words(min(Ms, Xs + Ys));
|
||||
hwWords_sz = words2hwords(maxWords_sz);
|
||||
|
||||
if((hwWords_sz<<5) > ESP_HW_RSAMAX_BIT) {
|
||||
if ((hwWords_sz << 5) > ESP_HW_RSAMAX_BIT) {
|
||||
ESP_LOGE(TAG, "exceeds hw maximum bits");
|
||||
return -2;
|
||||
}
|
||||
@ -336,20 +412,20 @@ int esp_mp_mulmod(fp_int* X, fp_int* Y, fp_int* M, fp_int* Z)
|
||||
* accordingly R^2 = 2^(n*32*2)
|
||||
*/
|
||||
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, (hwWords_sz << 6))) != 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){
|
||||
if ((ret = esp_mp_hw_lock()) != MP_OKAY) {
|
||||
mp_clear(&tmpZ);
|
||||
mp_clear(&r_inv);
|
||||
return ret;
|
||||
}
|
||||
/* Calculate M' */
|
||||
if((ret = esp_calc_Mdash(M, 32/* bits */, &mp)) != MP_OKAY) {
|
||||
if ((ret = esp_calc_Mdash(M, 32/* bits */, &mp)) != MP_OKAY) {
|
||||
ESP_LOGE(TAG, "failed to calculate M dash");
|
||||
mp_clear(&tmpZ);
|
||||
mp_clear(&r_inv);
|
||||
@ -374,7 +450,7 @@ int esp_mp_mulmod(fp_int* X, fp_int* Y, fp_int* M, fp_int* Z)
|
||||
* 13. Release the hw engine
|
||||
*/
|
||||
|
||||
if((ret = esp_mp_hw_wait_clean()) != MP_OKAY){
|
||||
if ((ret = esp_mp_hw_wait_clean()) != MP_OKAY) {
|
||||
return ret;
|
||||
}
|
||||
/* step.1 512 bits => 16 words */
|
||||
@ -383,8 +459,11 @@ int esp_mp_mulmod(fp_int* X, fp_int* Y, fp_int* M, fp_int* Z)
|
||||
/* step.2 write X, M and r_inv into memory */
|
||||
esp_mpint_to_memblock(RSA_MEM_X_BLOCK_BASE, X, Xs, 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_Z_BLOCK_BASE,
|
||||
&r_inv,
|
||||
mp_count_bits(&r_inv),
|
||||
hwWords_sz);
|
||||
|
||||
/* step.3 write M' into memory */
|
||||
DPORT_REG_WRITE(RSA_M_DASH_REG, mp);
|
||||
/* step.4 start process */
|
||||
@ -409,11 +488,11 @@ int esp_mp_mulmod(fp_int* X, fp_int* Y, fp_int* M, fp_int* Z)
|
||||
|
||||
/* additional steps */
|
||||
/* this needs for known issue when Z is greater than M */
|
||||
if(mp_cmp(&tmpZ, M)==FP_GT) {
|
||||
/* Z -= M */
|
||||
mp_sub(&tmpZ, M, &tmpZ);
|
||||
if (mp_cmp(&tmpZ, M) == FP_GT) {
|
||||
/* Z -= M */
|
||||
mp_sub(&tmpZ, M, &tmpZ);
|
||||
}
|
||||
if(negcheck) {
|
||||
if (negcheck) {
|
||||
mp_sub(M, &tmpZ, &tmpZ);
|
||||
}
|
||||
|
||||
@ -424,7 +503,25 @@ int esp_mp_mulmod(fp_int* X, fp_int* Y, fp_int* M, fp_int* Z)
|
||||
|
||||
return ret;
|
||||
}
|
||||
/* Z = X^Y mod M */
|
||||
|
||||
/* Large Number Modular Exponentiation
|
||||
*
|
||||
* Z = X^Y mod M
|
||||
*
|
||||
* See Chapter 24:
|
||||
* https://www.espressif.com/sites/default/files/documentation/esp32_technical_reference_manual_en.pdf
|
||||
*
|
||||
* The operation is based on Montgomery multiplication. Aside from the
|
||||
* arguments X, Y , and M, two additional ones are needed —r and M′
|
||||
.* These arguments are calculated in advance by software.
|
||||
.*
|
||||
.* The RSA Accelerator supports operand lengths of N ∈ {512, 1024, 1536, 2048,
|
||||
.* 2560, 3072, 3584, 4096} bits. The bit length of arguments Z, X, Y , M,
|
||||
.* and r can be any one from the N set, but all numbers in a calculation must
|
||||
.* be of the same length. The bit length of M′ is always 32.
|
||||
.*
|
||||
.* Note some DH references may use: Y = (G ^ X) mod P
|
||||
*/
|
||||
int esp_mp_exptmod(fp_int* X, fp_int* Y, word32 Ys, fp_int* M, fp_int* Z)
|
||||
{
|
||||
int ret = 0;
|
||||
@ -444,7 +541,7 @@ int esp_mp_exptmod(fp_int* X, fp_int* Y, word32 Ys, fp_int* M, fp_int* Z)
|
||||
maxWords_sz = bits2words(max(Xs, max(Ys, Ms)));
|
||||
hwWords_sz = words2hwords(maxWords_sz);
|
||||
|
||||
if((hwWords_sz<<5) > ESP_HW_RSAMAX_BIT) {
|
||||
if ((hwWords_sz << 5) > ESP_HW_RSAMAX_BIT) {
|
||||
ESP_LOGE(TAG, "exceeds hw maximum bits");
|
||||
return -2;
|
||||
}
|
||||
@ -453,19 +550,19 @@ int esp_mp_exptmod(fp_int* X, fp_int* Y, word32 Ys, fp_int* M, fp_int* Z)
|
||||
* accordingly R^2 = 2^(n*32*2)
|
||||
*/
|
||||
ret = mp_init(&r_inv);
|
||||
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, (hwWords_sz << 6))) != MP_OKAY) {
|
||||
ESP_LOGE(TAG, "calculate r_inv failed.");
|
||||
mp_clear(&r_inv);
|
||||
return ret;
|
||||
}
|
||||
/* lock and init the hw */
|
||||
if((ret = esp_mp_hw_lock()) != MP_OKAY) {
|
||||
if ((ret = esp_mp_hw_lock()) != MP_OKAY) {
|
||||
mp_clear(&r_inv);
|
||||
return ret;
|
||||
}
|
||||
/* calc M' */
|
||||
/* if Pm is odd, uses mp_montgomery_setup() */
|
||||
if((ret = esp_calc_Mdash(M, 32/* bits */, &mp)) != MP_OKAY) {
|
||||
if ((ret = esp_calc_Mdash(M, 32/* bits */, &mp)) != MP_OKAY) {
|
||||
ESP_LOGE(TAG, "failed to calculate M dash");
|
||||
mp_clear(&r_inv);
|
||||
return -1;
|
||||
@ -483,7 +580,7 @@ int esp_mp_exptmod(fp_int* X, fp_int* Y, word32 Ys, fp_int* M, fp_int* Z)
|
||||
* 6. Read the result Z(=Y) from Z_MEM
|
||||
* 7. Write 1 to INTERRUPT_REG to clear the interrupt.
|
||||
*/
|
||||
if((ret = esp_mp_hw_wait_clean()) != MP_OKAY){
|
||||
if ((ret = esp_mp_hw_wait_clean()) != MP_OKAY) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -493,8 +590,10 @@ int esp_mp_exptmod(fp_int* X, fp_int* Y, word32 Ys, fp_int* M, fp_int* Z)
|
||||
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_Z_BLOCK_BASE,
|
||||
&r_inv,
|
||||
mp_count_bits(&r_inv),
|
||||
hwWords_sz);
|
||||
/* step.3 write M' into memory */
|
||||
DPORT_REG_WRITE(RSA_M_DASH_REG, mp);
|
||||
/* step.4 start process */
|
||||
@ -512,4 +611,5 @@ int esp_mp_exptmod(fp_int* X, fp_int* Y, word32 Ys, fp_int* M, fp_int* Z)
|
||||
return ret;
|
||||
}
|
||||
#endif /* !NO_RSA || HAVE_ECC */
|
||||
|
||||
#endif /* (WOLFSS_ESP32WROOM32_CRYPT) && (NO_WOLFSSL_ESP32WROOM32_CRYPT_RES_PRI)*/
|
||||
|
@ -18,23 +18,28 @@
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
|
||||
*/
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
#include <wolfssl/wolfcrypt/settings.h>
|
||||
|
||||
#include <wolfssl/wolfcrypt/settings.h>
|
||||
/*****************************************************************************/
|
||||
/* this entire file content is excluded when NO_SHA, NO_SHA256
|
||||
* or when using WC_SHA384 or WC_SHA512
|
||||
*/
|
||||
#if !defined(NO_SHA) || !defined(NO_SHA256) || defined(WC_SHA384) || \
|
||||
defined(WC_SHA512)
|
||||
|
||||
#include "wolfssl/wolfcrypt/logging.h"
|
||||
|
||||
|
||||
/* this entire file content is excluded if not using HW hash acceleration */
|
||||
#if defined(WOLFSSL_ESP32WROOM32_CRYPT) && \
|
||||
!defined(NO_WOLFSSL_ESP32WROOM32_CRYPT_HASH)
|
||||
|
||||
/* TODO this may be chip type dependent: add support for others */
|
||||
#include <hal/clk_gate_ll.h> /* ESP32-WROOM */
|
||||
|
||||
#include <wolfssl/wolfcrypt/sha.h>
|
||||
#include <wolfssl/wolfcrypt/sha256.h>
|
||||
#include <wolfssl/wolfcrypt/sha512.h>
|
||||
@ -50,20 +55,29 @@
|
||||
#endif
|
||||
|
||||
static const char* TAG = "wolf_hw_sha";
|
||||
/* continue register offset */
|
||||
#define CONTINUE_REG_OFFSET (0x04) /* start_reg + 0x04 */
|
||||
|
||||
#ifdef NO_SHA
|
||||
#define WC_SHA_DIGEST_SIZE 20
|
||||
#endif
|
||||
|
||||
/* mutex */
|
||||
#if defined(SINGLE_THREADED)
|
||||
static int InUse = 0;
|
||||
static int InUse = 0;
|
||||
#else
|
||||
static wolfSSL_Mutex sha_mutex;
|
||||
static int espsha_CryptHwMutexInit = 0;
|
||||
static wolfSSL_Mutex sha_mutex;
|
||||
static int espsha_CryptHwMutexInit = 0;
|
||||
|
||||
#if defined(DEBUG_WOLFSSL)
|
||||
static int this_block_num = 0;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
* determine the digest size, depending on SHA type.
|
||||
*
|
||||
* See FIPS PUB 180-4, Instruction Section 1.
|
||||
*
|
||||
*
|
||||
enum SHA_TYPE {
|
||||
SHA1 = 0,
|
||||
SHA2_256,
|
||||
@ -72,43 +86,112 @@ static int espsha_CryptHwMutexInit = 0;
|
||||
SHA_INVALID = -1,
|
||||
};
|
||||
*/
|
||||
static word32 esp_sha_digest_size(enum SHA_TYPE type)
|
||||
static word32 wc_esp_sha_digest_size(enum SHA_TYPE type)
|
||||
{
|
||||
ESP_LOGV(TAG, "enter esp_sha_digest_size");
|
||||
ESP_LOGV(TAG, " esp_sha_digest_size");
|
||||
|
||||
switch(type){
|
||||
#ifndef NO_SHA
|
||||
case SHA1:
|
||||
return WC_SHA_DIGEST_SIZE;
|
||||
#endif
|
||||
#ifndef NO_SHA256
|
||||
case SHA2_256:
|
||||
return WC_SHA256_DIGEST_SIZE;
|
||||
#endif
|
||||
#ifdef WOLFSSL_SHA384
|
||||
case SHA2_384:
|
||||
return WC_SHA384_DIGEST_SIZE;
|
||||
#endif
|
||||
#ifdef WOLFSSL_SHA512
|
||||
case SHA2_512:
|
||||
return WC_SHA512_DIGEST_SIZE;
|
||||
#endif
|
||||
#ifndef NO_SHA
|
||||
case SHA1: /* typically 20 bytes */
|
||||
return WC_SHA_DIGEST_SIZE;
|
||||
#endif
|
||||
|
||||
#ifndef NO_SHA256
|
||||
case SHA2_256: /* typically 32 bytes */
|
||||
return WC_SHA256_DIGEST_SIZE;
|
||||
#endif
|
||||
|
||||
#ifdef WOLFSSL_SHA384
|
||||
case SHA2_384:
|
||||
return WC_SHA384_DIGEST_SIZE;
|
||||
#endif
|
||||
|
||||
#ifdef WOLFSSL_SHA512
|
||||
case SHA2_512: /* typically 64 bytes */
|
||||
return WC_SHA512_DIGEST_SIZE;
|
||||
#endif
|
||||
|
||||
default:
|
||||
ESP_LOGE(TAG, "Bad sha type");
|
||||
return WC_SHA_DIGEST_SIZE;
|
||||
}
|
||||
ESP_LOGV(TAG, "leave esp_sha_digest_size");
|
||||
/* we never get here, as all the above switches should have a return */
|
||||
}
|
||||
|
||||
/*
|
||||
* wait until engines becomes idle
|
||||
* wait until all engines becomes idle
|
||||
*/
|
||||
static void esp_wait_until_idle()
|
||||
static void wc_esp_wait_until_idle()
|
||||
{
|
||||
while((DPORT_REG_READ(SHA_1_BUSY_REG) !=0) ||
|
||||
(DPORT_REG_READ(SHA_256_BUSY_REG)!=0) ||
|
||||
(DPORT_REG_READ(SHA_384_BUSY_REG)!=0) ||
|
||||
(DPORT_REG_READ(SHA_512_BUSY_REG)!=0)){ }
|
||||
while((DPORT_REG_READ(SHA_1_BUSY_REG) != 0) ||
|
||||
(DPORT_REG_READ(SHA_256_BUSY_REG) != 0) ||
|
||||
(DPORT_REG_READ(SHA_384_BUSY_REG) != 0) ||
|
||||
(DPORT_REG_READ(SHA_512_BUSY_REG) != 0)) {
|
||||
/* do nothing while waiting. */
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* hack alert. there really should have been something implemented
|
||||
* in periph_ctrl.c to detect ref_counts[periph] depth.
|
||||
*
|
||||
* since there is not at this time, we have this brute-force method.
|
||||
*
|
||||
* when trying to unwrap an arbitrary depth of peripheral-enable(s),
|
||||
* we'll check the register upon *enable* to see if we actually did.
|
||||
*
|
||||
* Note that enable / disable only occurs when ref_counts[periph] == 0
|
||||
*
|
||||
* TODO: check if this works with other ESP32 platforms ESP32-C3, ESP32-S3, etc
|
||||
*/
|
||||
int esp_unroll_sha_module_enable(WC_ESP32SHA* ctx)
|
||||
{
|
||||
/* if we end up here, there was a prior unexpected fail and
|
||||
* we need to unroll enables */
|
||||
int ret = 0; /* assume success unless proven otherwise */
|
||||
uint32_t this_sha_mask; /* this is the bit-mask for our SHA CLK_EN_REG */
|
||||
int actual_unroll_count = 0;
|
||||
int max_unroll_count = 1000; /* never get stuck in a hardware wait loop */
|
||||
|
||||
this_sha_mask = periph_ll_get_clk_en_mask(PERIPH_SHA_MODULE);
|
||||
|
||||
/* unwind prior calls to THIS ctx. decrement ref_counts[periph] */
|
||||
/* only when ref_counts[periph] == 0 does something actually happen */
|
||||
|
||||
/* once the value we read is a 0 in the DPORT_PERI_CLK_EN_REG bit
|
||||
* then we have fully unrolled the enables via ref_counts[periph]==0 */
|
||||
while ((this_sha_mask & *(uint32_t*)DPORT_PERI_CLK_EN_REG) != 0) {
|
||||
periph_module_disable(PERIPH_SHA_MODULE);
|
||||
actual_unroll_count++;
|
||||
ESP_LOGI(TAG, "unroll not yet successful. try #%d",
|
||||
actual_unroll_count);
|
||||
|
||||
/* we'll only try this some unreasonable number of times
|
||||
* before giving up */
|
||||
if (actual_unroll_count > max_unroll_count) {
|
||||
ret = -1; /* failed to unroll */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (ret == 0) {
|
||||
if (ctx->lockDepth != actual_unroll_count) {
|
||||
/* this could be a warning of wonkiness in RTOS environment.
|
||||
* we were successful, but not expected depth count*/
|
||||
|
||||
ESP_LOGE(TAG, "warning lockDepth mismatch.");
|
||||
}
|
||||
ctx->lockDepth = 0;
|
||||
ctx->mode = ESP32_SHA_INIT;
|
||||
}
|
||||
else {
|
||||
ESP_LOGE(TAG, "Failed to unroll after %d attempts.",
|
||||
actual_unroll_count);
|
||||
ctx->mode = ESP32_SHA_SW;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* lock hw engine.
|
||||
* this should be called before using engine.
|
||||
@ -119,160 +202,375 @@ int esp_sha_try_hw_lock(WC_ESP32SHA* ctx)
|
||||
|
||||
ESP_LOGV(TAG, "enter esp_sha_hw_lock");
|
||||
|
||||
/* Init mutex */
|
||||
if (ctx == NULL) {
|
||||
ESP_LOGE(TAG, " esp_sha_try_hw_lock called with NULL ctx");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Init mutex
|
||||
*
|
||||
* Note that even single thread mode may calculate hashes
|
||||
* concurrently, so we still need to keep track of the
|
||||
* engine being busy or not.
|
||||
**/
|
||||
#if defined(SINGLE_THREADED)
|
||||
if(ctx->mode == ESP32_SHA_INIT) {
|
||||
if(!InUse) {
|
||||
ctx->mode = ESP32_SHA_HW;
|
||||
InUse = 1;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
ctx->mode = ESP32_SHA_SW;
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
/* this should not happens */
|
||||
ESP_LOGE(TAG, "unexpected error in esp_sha_try_hw_lock.");
|
||||
return -1;
|
||||
}
|
||||
#else
|
||||
if(espsha_CryptHwMutexInit == 0){
|
||||
#else /* not defined(SINGLE_THREADED) */
|
||||
/*
|
||||
* there's only one SHA engine for all the hash types
|
||||
* so when any hash is in use, no others can use it.
|
||||
* fall back to SW.
|
||||
**/
|
||||
|
||||
/*
|
||||
* here is some sample code to test the unrolling of sha enables:
|
||||
*
|
||||
periph_module_enable(PERIPH_SHA_MODULE);
|
||||
ctx->lockDepth++;
|
||||
periph_module_enable(PERIPH_SHA_MODULE);
|
||||
ctx->lockDepth++;
|
||||
ctx->mode = ESP32_FAIL_NEED_INIT;
|
||||
|
||||
*/
|
||||
|
||||
if (espsha_CryptHwMutexInit == 0) {
|
||||
ESP_LOGV(TAG, "set esp_CryptHwMutexInit");
|
||||
ret = esp_CryptHwMutexInit(&sha_mutex);
|
||||
if(ret == 0) {
|
||||
if (ret == 0) {
|
||||
espsha_CryptHwMutexInit = 1;
|
||||
} else {
|
||||
ESP_LOGE(TAG, " mutex initialization failed.");
|
||||
}
|
||||
else {
|
||||
ESP_LOGE(TAG, " mutex initialization failed. revert to software");
|
||||
ctx->mode = ESP32_SHA_SW;
|
||||
return 0;
|
||||
/* espsha_CryptHwMutexInit is still zero */
|
||||
return 0; /* success, just not using HW */
|
||||
}
|
||||
}
|
||||
|
||||
/* check if this sha has been operated as sw or hw, or not yet init */
|
||||
if(ctx->mode == ESP32_SHA_INIT){
|
||||
if (ctx->mode == ESP32_SHA_INIT) {
|
||||
/* try to lock the hw engine */
|
||||
if(esp_CryptHwMutexLock(&sha_mutex, (TickType_t)0) == 0) {
|
||||
ctx->mode = ESP32_SHA_HW;
|
||||
} else {
|
||||
ESP_LOGI(TAG, "someone used. hw is locked.....");
|
||||
ESP_LOGI(TAG, "the rest of operation will use sw implementation for this sha");
|
||||
ctx->mode = ESP32_SHA_SW;
|
||||
return 0;
|
||||
ESP_LOGV(TAG, "ESP32_SHA_INIT\n");
|
||||
|
||||
/* we don't wait:
|
||||
* either the engine is free, or we fall back to SW
|
||||
*/
|
||||
if (esp_CryptHwMutexLock(&sha_mutex, (TickType_t)0) == 0) {
|
||||
/* check to see if we had a prior fail and need to unroll enables */
|
||||
ret = esp_unroll_sha_module_enable(ctx);
|
||||
ESP_LOGV(TAG, "Hardware Mode, lock depth = %d", ctx->lockDepth);
|
||||
}
|
||||
} else {
|
||||
/* this should not happens */
|
||||
else {
|
||||
ESP_LOGI(TAG, ">>>> Hardware in use; Mode REVERT to ESP32_SHA_SW");
|
||||
ctx->mode = ESP32_SHA_SW;
|
||||
return 0; /* success, but revert to SW */
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* this should not happen: called during mode != ESP32_SHA_INIT */
|
||||
ESP_LOGE(TAG, "unexpected error in esp_sha_try_hw_lock.");
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
/* Enable SHA hardware */
|
||||
periph_module_enable(PERIPH_SHA_MODULE);
|
||||
#endif /* not defined(SINGLE_THREADED) */
|
||||
|
||||
if (ret == 0) {
|
||||
ctx->lockDepth++; /* depth for THIS ctx (there could be others!) */
|
||||
periph_module_enable(PERIPH_SHA_MODULE);
|
||||
ctx->mode = ESP32_SHA_HW;
|
||||
}
|
||||
else {
|
||||
ESP_LOGI(TAG, ">>>> Other problem; Mode REVERT to ESP32_SHA_SW");
|
||||
ctx->mode = ESP32_SHA_SW;
|
||||
}
|
||||
|
||||
ESP_LOGV(TAG, "leave esp_sha_hw_lock");
|
||||
return ret;
|
||||
}
|
||||
} /* esp_sha_try_hw_lock */
|
||||
|
||||
/*
|
||||
* release hw engine
|
||||
* release hw engine. when we don't have it locked, SHA module is DISABLED
|
||||
*/
|
||||
void esp_sha_hw_unlock( void )
|
||||
int esp_sha_hw_unlock(WC_ESP32SHA* ctx)
|
||||
{
|
||||
ESP_LOGV(TAG, "enter esp_sha_hw_unlock");
|
||||
|
||||
/* Disable AES hardware */
|
||||
periph_module_disable(PERIPH_SHA_MODULE);
|
||||
#if defined(SINGLE_THREADED)
|
||||
InUse = 0;
|
||||
#else
|
||||
/* unlock hw engine for next use */
|
||||
esp_CryptHwMutexUnLock(&sha_mutex);
|
||||
#endif
|
||||
|
||||
#if defined(SINGLE_THREADED)
|
||||
InUse = 0;
|
||||
#else
|
||||
/* unlock hw engine for next use */
|
||||
esp_CryptHwMutexUnLock(&sha_mutex);
|
||||
#endif
|
||||
|
||||
/* we'll keep track of our lock depth.
|
||||
* in case of unexpected results, all the periph_module_disable() calls
|
||||
* and periph_module_disable() need to be unwound.
|
||||
*
|
||||
* see ref_counts[periph] in file: periph_ctrl.c */
|
||||
if (ctx->lockDepth > 0) {
|
||||
ctx->lockDepth--;
|
||||
}
|
||||
else {
|
||||
ctx->lockDepth = 0;
|
||||
}
|
||||
|
||||
ESP_LOGV(TAG, "leave esp_sha_hw_unlock");
|
||||
}
|
||||
return 0;
|
||||
} /* esp_sha_hw_unlock */
|
||||
|
||||
/*
|
||||
* start sha process by using hw engine
|
||||
* start sha process by using hw engine.
|
||||
* assumes register already loaded.
|
||||
*/
|
||||
static void esp_sha_start_process(WC_ESP32SHA* sha, word32 address)
|
||||
static int esp_sha_start_process(WC_ESP32SHA* sha)
|
||||
{
|
||||
ESP_LOGV(TAG, "enter esp_sha_start_process");
|
||||
int ret = 0;
|
||||
if (sha == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
ESP_LOGV(TAG, " enter esp_sha_start_process");
|
||||
|
||||
if(sha->isfirstblock){
|
||||
/* start first message block */
|
||||
DPORT_REG_WRITE(address, 1);
|
||||
/* start registers for first message block
|
||||
* we don't make any relational memory position assumptions.
|
||||
*/
|
||||
switch (sha->sha_type) {
|
||||
case SHA1:
|
||||
DPORT_REG_WRITE(SHA_1_START_REG, 1);
|
||||
break;
|
||||
|
||||
case SHA2_256:
|
||||
DPORT_REG_WRITE(SHA_256_START_REG, 1);
|
||||
break;
|
||||
|
||||
#if defined(WOLFSSL_SHA384)
|
||||
case SHA2_384:
|
||||
DPORT_REG_WRITE(SHA_384_START_REG, 1);
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if defined(WOLFSSL_SHA512)
|
||||
case SHA2_512:
|
||||
DPORT_REG_WRITE(SHA_512_START_REG, 1);
|
||||
break;
|
||||
#endif
|
||||
|
||||
default:
|
||||
sha->mode = ESP32_SHA_FAIL_NEED_UNROLL;
|
||||
ret = -1;
|
||||
break;
|
||||
}
|
||||
|
||||
sha->isfirstblock = 0;
|
||||
} else {
|
||||
/* CONTINU_REG */
|
||||
DPORT_REG_WRITE(address + CONTINUE_REG_OFFSET , 1);
|
||||
ESP_LOGV(TAG, " set sha->isfirstblock = 0");
|
||||
|
||||
#if defined(DEBUG_WOLFSSL)
|
||||
this_block_num = 1; /* one-based counter, just for debug info */
|
||||
#endif
|
||||
|
||||
}
|
||||
else {
|
||||
/* continue */
|
||||
/* continue registers for next message block.
|
||||
* we don't make any relational memory position assumptions
|
||||
* for future chip architecture changes.
|
||||
*/
|
||||
switch (sha->sha_type) {
|
||||
case SHA1:
|
||||
DPORT_REG_WRITE(SHA_1_CONTINUE_REG, 1);
|
||||
break;
|
||||
|
||||
case SHA2_256:
|
||||
DPORT_REG_WRITE(SHA_256_CONTINUE_REG, 1);
|
||||
break;
|
||||
|
||||
#if defined(WOLFSSL_SHA384)
|
||||
case SHA2_384:
|
||||
DPORT_REG_WRITE(SHA_384_CONTINUE_REG, 1);
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if defined(WOLFSSL_SHA512)
|
||||
case SHA2_512:
|
||||
DPORT_REG_WRITE(SHA_512_CONTINUE_REG, 1);
|
||||
break;
|
||||
#endif
|
||||
|
||||
default:
|
||||
/* error for unsupported other values */
|
||||
sha->mode = ESP32_SHA_FAIL_NEED_UNROLL;
|
||||
ret = -1;
|
||||
break;
|
||||
}
|
||||
#if defined(DEBUG_WOLFSSL)
|
||||
this_block_num++; /* one-based counter */
|
||||
ESP_LOGV(TAG, " continue block #%d", this_block_num);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
ESP_LOGV(TAG, "leave esp_sha_start_process");
|
||||
ESP_LOGV(TAG, " leave esp_sha_start_process");
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* process message block
|
||||
*/
|
||||
static void esp_process_block(WC_ESP32SHA* ctx, word32 address,
|
||||
const word32* data, word32 len)
|
||||
static void wc_esp_process_block(WC_ESP32SHA* ctx, /* see ctx->sha_type */
|
||||
const word32* data,
|
||||
word32 len)
|
||||
{
|
||||
int i;
|
||||
|
||||
ESP_LOGV(TAG, "enter esp_process_block");
|
||||
int word32_to_save = (len) / (sizeof(word32));
|
||||
ESP_LOGV(TAG, " enter esp_process_block");
|
||||
if (word32_to_save > 0x31) {
|
||||
word32_to_save = 0x31;
|
||||
ESP_LOGE(TAG, " ERROR esp_process_block len exceeds 0x31 words");
|
||||
}
|
||||
|
||||
/* check if there are any busy engine */
|
||||
esp_wait_until_idle();
|
||||
/* load message data into hw */
|
||||
for(i=0;i<((len)/(sizeof(word32)));++i){
|
||||
DPORT_REG_WRITE(SHA_TEXT_BASE+(i*sizeof(word32)),*(data+i));
|
||||
wc_esp_wait_until_idle();
|
||||
|
||||
/* load [len] words of message data into hw */
|
||||
for (i = 0; i < word32_to_save; i++) {
|
||||
/* by using DPORT_REG_WRITE, we avoid the need
|
||||
* to call __builtin_bswap32 to address endiness
|
||||
*
|
||||
* a useful watch array cast to watch at runtime:
|
||||
* ((uint32_t[32]) (*(volatile uint32_t *)(SHA_TEXT_BASE)))
|
||||
*
|
||||
* Write value to DPORT register (does not require protecting)
|
||||
*/
|
||||
DPORT_REG_WRITE(SHA_TEXT_BASE + (i*sizeof(word32)), *(data + i));
|
||||
/* memw confirmed auto inserted by compiler here */
|
||||
}
|
||||
/* notify hw to start process */
|
||||
esp_sha_start_process(ctx, address);
|
||||
|
||||
ESP_LOGV(TAG, "leave esp_process_block");
|
||||
/* notify hw to start process
|
||||
* see ctx->sha_type
|
||||
* reg data does not change until we are ready to read */
|
||||
esp_sha_start_process(ctx);
|
||||
|
||||
ESP_LOGV(TAG, " leave esp_process_block");
|
||||
}
|
||||
/*
|
||||
* retrieve sha digest from memory
|
||||
*/
|
||||
static void esp_digest_state(WC_ESP32SHA* ctx, byte* hash, enum SHA_TYPE sha_type)
|
||||
{
|
||||
/* registers */
|
||||
word32 SHA_LOAD_REG = SHA_1_LOAD_REG;
|
||||
word32 SHA_BUSY_REG = SHA_1_BUSY_REG;
|
||||
|
||||
/*
|
||||
* retrieve sha digest from memory
|
||||
*/
|
||||
int wc_esp_digest_state(WC_ESP32SHA* ctx, byte* hash)
|
||||
{
|
||||
ESP_LOGV(TAG, "enter esp_digest_state");
|
||||
|
||||
/* sanity check */
|
||||
if(sha_type == SHA_INVALID) {
|
||||
ESP_LOGE(TAG, "unexpected error. sha_type is invalid.");
|
||||
return;
|
||||
if (ctx == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
SHA_LOAD_REG += (sha_type << 4);
|
||||
SHA_BUSY_REG += (sha_type << 4);
|
||||
/* sanity check */
|
||||
if (ctx->sha_type == SHA_INVALID) {
|
||||
ctx->mode = ESP32_SHA_FAIL_NEED_UNROLL;
|
||||
ESP_LOGE(TAG, "unexpected error. sha_type is invalid.");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(ctx->isfirstblock == 1){
|
||||
/* no hardware use yet. Nothing to do yet */
|
||||
return ;
|
||||
if (ctx == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* wait until idle */
|
||||
esp_wait_until_idle();
|
||||
wc_esp_wait_until_idle();
|
||||
|
||||
/* each sha_type register is at a different location */
|
||||
switch (ctx->sha_type) {
|
||||
case SHA1:
|
||||
DPORT_REG_WRITE(SHA_1_LOAD_REG, 1);
|
||||
break;
|
||||
|
||||
case SHA2_256:
|
||||
DPORT_REG_WRITE(SHA_256_LOAD_REG, 1);
|
||||
break;
|
||||
|
||||
#if defined(WOLFSSL_SHA384)
|
||||
case SHA2_384:
|
||||
SHA_LOAD_REG = SHA_384_LOAD_REG;
|
||||
SHA_BUSY_REG = SHA_384_BUSY_REG;
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if defined(WOLFSSL_SHA512)
|
||||
case SHA2_512:
|
||||
DPORT_REG_WRITE(SHA_512_LOAD_REG, 1);
|
||||
break;
|
||||
#endif
|
||||
|
||||
default:
|
||||
ctx->mode = ESP32_SHA_FAIL_NEED_UNROLL;
|
||||
return -1;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
if(ctx->isfirstblock == 1){
|
||||
/* no hardware use yet. Nothing to do yet */
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* LOAD final digest */
|
||||
DPORT_REG_WRITE(SHA_LOAD_REG, 1);
|
||||
/* wait until done */
|
||||
while(DPORT_REG_READ(SHA_BUSY_REG) == 1){ }
|
||||
|
||||
esp_dport_access_read_buffer((word32*)(hash), SHA_TEXT_BASE,
|
||||
esp_sha_digest_size(sha_type)/sizeof(word32));
|
||||
wc_esp_wait_until_idle();
|
||||
|
||||
/* MEMW instructions before volatile memory references to guarantee
|
||||
* sequential consistency. At least one MEMW should be executed in
|
||||
* between every load or store to a volatile variable
|
||||
*/
|
||||
asm volatile("memw");
|
||||
|
||||
/* put result in hash variable.
|
||||
*
|
||||
* ALERT - hardware specific. See esp_hw_support\port\esp32\dport_access.c
|
||||
*
|
||||
* note we read 4-byte word32's here via DPORT_SEQUENCE_REG_READ
|
||||
*
|
||||
* example:
|
||||
* DPORT_SEQUENCE_REG_READ(address + i * 4);
|
||||
*/
|
||||
esp_dport_access_read_buffer(
|
||||
(word32*)(hash), /* the result will be found in hash upon exit */
|
||||
SHA_TEXT_BASE, /* there's a fixed reg addy for all SHA */
|
||||
wc_esp_sha_digest_size(ctx->sha_type) / sizeof(word32) /* # 4-byte */
|
||||
);
|
||||
|
||||
#if defined(WOLFSSL_SHA512) || defined(WOLFSSL_SHA384)
|
||||
if(sha_type==SHA2_384||sha_type==SHA2_512) {
|
||||
if (ctx->sha_type == SHA2_384 || ctx->sha_type == SHA2_512) {
|
||||
word32 i;
|
||||
word32* pwrd1 = (word32*)(hash);
|
||||
/* swap value */
|
||||
for(i = 0; i <WC_SHA512_DIGEST_SIZE/4; i+=2 ) {
|
||||
pwrd1[i] ^= pwrd1[i+1];
|
||||
pwrd1[i+1]^= pwrd1[i];
|
||||
pwrd1[i] ^= pwrd1[i+1];
|
||||
for (i = 0; i < WC_SHA512_DIGEST_SIZE / 4; i += 2) {
|
||||
pwrd1[i] ^= pwrd1[i + 1];
|
||||
pwrd1[i + 1] ^= pwrd1[i];
|
||||
pwrd1[i] ^= pwrd1[i + 1];
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
ESP_LOGV(TAG, "leave esp_digest_state");
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifndef NO_SHA
|
||||
@ -285,31 +583,26 @@ int esp_sha_process(struct wc_Sha* sha, const byte* data)
|
||||
|
||||
ESP_LOGV(TAG, "enter esp_sha_process");
|
||||
|
||||
word32 SHA_START_REG = SHA_1_START_REG;
|
||||
|
||||
esp_process_block(&sha->ctx, SHA_START_REG, (const word32*)data,
|
||||
WC_SHA_BLOCK_SIZE);
|
||||
wc_esp_process_block(&sha->ctx, (const word32*)data, WC_SHA_BLOCK_SIZE);
|
||||
|
||||
ESP_LOGV(TAG, "leave esp_sha_process");
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* retrieve sha1 digest
|
||||
*/
|
||||
int esp_sha_digest_process(struct wc_Sha* sha, byte blockproc)
|
||||
int esp_sha_digest_process(struct wc_Sha* sha, byte blockprocess)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
ESP_LOGV(TAG, "enter esp_sha_digest_process");
|
||||
|
||||
if(blockproc) {
|
||||
word32 SHA_START_REG = SHA_1_START_REG;
|
||||
|
||||
esp_process_block(&sha->ctx, SHA_START_REG, sha->buffer,
|
||||
WC_SHA_BLOCK_SIZE);
|
||||
if (blockprocess) {
|
||||
wc_esp_process_block(&sha->ctx, sha->buffer, WC_SHA_BLOCK_SIZE);
|
||||
}
|
||||
|
||||
esp_digest_state(&sha->ctx, (byte*)sha->digest, SHA1);
|
||||
wc_esp_digest_state(&sha->ctx, (byte*)sha->digest);
|
||||
|
||||
ESP_LOGV(TAG, "leave esp_sha_digest_process");
|
||||
|
||||
@ -321,69 +614,79 @@ int esp_sha_digest_process(struct wc_Sha* sha, byte blockproc)
|
||||
#ifndef NO_SHA256
|
||||
/*
|
||||
* sha256 process
|
||||
*
|
||||
* repeatedly call this for [N] blocks of [WC_SHA256_BLOCK_SIZE] bytes of data
|
||||
*/
|
||||
int esp_sha256_process(struct wc_Sha256* sha, const byte* data)
|
||||
{
|
||||
int ret = 0;
|
||||
word32 SHA_START_REG = SHA_1_START_REG;
|
||||
|
||||
ESP_LOGV(TAG, "enter esp_sha256_process");
|
||||
ESP_LOGV(TAG, " enter esp_sha256_process");
|
||||
|
||||
/* start register offset */
|
||||
SHA_START_REG += (SHA2_256 << 4);
|
||||
if ((&sha->ctx)->sha_type == SHA2_256) {
|
||||
#if defined(DEBUG_WOLFSSL_VERBOSE)
|
||||
ESP_LOGV(TAG, " confirmed sha type call match");
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
ret = -1;
|
||||
ESP_LOGE(TAG, " ERROR sha type call mismatch");
|
||||
}
|
||||
|
||||
esp_process_block(&sha->ctx, SHA_START_REG, (const word32*)data,
|
||||
WC_SHA256_BLOCK_SIZE);
|
||||
wc_esp_process_block(&sha->ctx, (const word32*)data, WC_SHA256_BLOCK_SIZE);
|
||||
|
||||
ESP_LOGV(TAG, "leave esp_sha256_process");
|
||||
ESP_LOGV(TAG, " leave esp_sha256_process");
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* retrieve sha256 digest
|
||||
*
|
||||
* note that wc_Sha256Final() in sha256.c expects to need to reverse byte
|
||||
* order, even though we could have returned them in the right order.
|
||||
*/
|
||||
int esp_sha256_digest_process(struct wc_Sha256* sha, byte blockproc)
|
||||
int esp_sha256_digest_process(struct wc_Sha256* sha, byte blockprocess)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
ESP_LOGV(TAG, "enter esp_sha256_digest_process");
|
||||
|
||||
if(blockproc) {
|
||||
word32 SHA_START_REG = SHA_1_START_REG + (SHA2_256 << 4);
|
||||
if(blockprocess) {
|
||||
|
||||
esp_process_block(&sha->ctx, SHA_START_REG, sha->buffer,
|
||||
WC_SHA256_BLOCK_SIZE);
|
||||
wc_esp_process_block(&sha->ctx, sha->buffer, WC_SHA256_BLOCK_SIZE);
|
||||
}
|
||||
|
||||
esp_digest_state(&sha->ctx, (byte*)sha->digest, SHA2_256);
|
||||
wc_esp_digest_state(&sha->ctx, (byte*)sha->digest);
|
||||
|
||||
ESP_LOGV(TAG, "leave esp_sha256_digest_process");
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
#endif /* NO_SHA256 */
|
||||
|
||||
#if defined(WOLFSSL_SHA512) || defined(WOLFSSL_SHA384)
|
||||
/*
|
||||
* sha512 proess. this is used for sha384 too.
|
||||
* sha512 process. this is used for sha384 too.
|
||||
*/
|
||||
void esp_sha512_block(struct wc_Sha512* sha, const word32* data, byte isfinal)
|
||||
{
|
||||
enum SHA_TYPE sha_type = sha->ctx.sha_type;
|
||||
word32 SHA_START_REG = SHA_1_START_REG;
|
||||
|
||||
ESP_LOGV(TAG, "enter esp_sha512_block");
|
||||
/* start register offset */
|
||||
SHA_START_REG += (sha_type << 4);
|
||||
|
||||
if(sha->ctx.mode == ESP32_SHA_SW){
|
||||
ByteReverseWords64(sha->buffer, sha->buffer,
|
||||
WC_SHA512_BLOCK_SIZE);
|
||||
if(isfinal){
|
||||
sha->buffer[WC_SHA512_BLOCK_SIZE / sizeof(word64) - 2] = sha->hiLen;
|
||||
sha->buffer[WC_SHA512_BLOCK_SIZE / sizeof(word64) - 1] = sha->loLen;
|
||||
if(isfinal) {
|
||||
sha->buffer[WC_SHA512_BLOCK_SIZE / sizeof(word64) - 2] =
|
||||
sha->hiLen;
|
||||
sha->buffer[WC_SHA512_BLOCK_SIZE / sizeof(word64) - 1] =
|
||||
sha->loLen;
|
||||
}
|
||||
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
ByteReverseWords((word32*)sha->buffer, (word32*)sha->buffer,
|
||||
WC_SHA512_BLOCK_SIZE);
|
||||
if(isfinal){
|
||||
@ -393,7 +696,7 @@ void esp_sha512_block(struct wc_Sha512* sha, const word32* data, byte isfinal)
|
||||
rotlFixed64(sha->loLen, 32U);
|
||||
}
|
||||
|
||||
esp_process_block(&sha->ctx, SHA_START_REG, data, WC_SHA512_BLOCK_SIZE);
|
||||
wc_esp_process_block(&sha->ctx, data, WC_SHA512_BLOCK_SIZE);
|
||||
}
|
||||
ESP_LOGV(TAG, "leave esp_sha512_block");
|
||||
}
|
||||
@ -424,7 +727,7 @@ int esp_sha512_digest_process(struct wc_Sha512* sha, byte blockproc)
|
||||
esp_sha512_block(sha, data, 1);
|
||||
}
|
||||
if(sha->ctx.mode != ESP32_SHA_SW)
|
||||
esp_digest_state(&sha->ctx, (byte*)sha->digest, sha->ctx.sha_type);
|
||||
wc_esp_digest_state(&sha->ctx, (byte*)sha->digest);
|
||||
|
||||
ESP_LOGV(TAG, "leave esp_sha512_digest_process");
|
||||
return 0;
|
||||
|
@ -1,6 +1,6 @@
|
||||
/* esp32_util.c
|
||||
*
|
||||
* Copyright (C) 2006-2021 wolfSSL Inc.
|
||||
* Copyright (C) 2006-2022 wolfSSL Inc.
|
||||
*
|
||||
* This file is part of wolfSSL.
|
||||
*
|
||||
@ -26,21 +26,57 @@
|
||||
|
||||
#include <wolfssl/wolfcrypt/wc_port.h>
|
||||
#include <wolfssl/wolfcrypt/error-crypt.h>
|
||||
|
||||
#include <wolfssl/wolfcrypt/logging.h>
|
||||
/*
|
||||
* initialize our mutex used to lock hardware access
|
||||
*
|
||||
* returns:
|
||||
* 0 upon success,
|
||||
* BAD_MUTEX_E for null mutex
|
||||
* other value from wc_InitMutex()
|
||||
*
|
||||
*/
|
||||
int esp_CryptHwMutexInit(wolfSSL_Mutex* mutex) {
|
||||
if (mutex == NULL) {
|
||||
return BAD_MUTEX_E;
|
||||
}
|
||||
|
||||
return wc_InitMutex(mutex);
|
||||
}
|
||||
|
||||
/*
|
||||
* call the ESP-IDF mutex lock; xSemaphoreTake
|
||||
*
|
||||
*/
|
||||
int esp_CryptHwMutexLock(wolfSSL_Mutex* mutex, TickType_t xBlockTime) {
|
||||
if (mutex == NULL) {
|
||||
WOLFSSL_ERROR_MSG("esp_CryptHwMutexLock called with null mutex");
|
||||
return BAD_MUTEX_E;
|
||||
}
|
||||
|
||||
#ifdef SINGLE_THREADED
|
||||
return wc_LockMutex(mutex);
|
||||
return wc_LockMutex(mutex); /* xSemaphoreTake take with portMAX_DELAY */
|
||||
#else
|
||||
return ((xSemaphoreTake( *mutex, xBlockTime ) == pdTRUE) ? 0 : BAD_MUTEX_E);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* call the ESP-IDF mutex UNlock; xSemaphoreGive
|
||||
*
|
||||
*/
|
||||
int esp_CryptHwMutexUnLock(wolfSSL_Mutex* mutex) {
|
||||
if (mutex == NULL) {
|
||||
WOLFSSL_ERROR_MSG("esp_CryptHwMutexLock called with null mutex");
|
||||
return BAD_MUTEX_E;
|
||||
}
|
||||
|
||||
#ifdef SINGLE_THREADED
|
||||
return wc_UnLockMutex(mutex);
|
||||
#else
|
||||
xSemaphoreGive(*mutex);
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -1,6 +1,6 @@
|
||||
/* sha.c
|
||||
*
|
||||
* Copyright (C) 2006-2021 wolfSSL Inc.
|
||||
* Copyright (C) 2006-2022 wolfSSL Inc.
|
||||
*
|
||||
* This file is part of wolfSSL.
|
||||
*
|
||||
@ -311,14 +311,15 @@
|
||||
sha->ctx.isfirstblock = 1;
|
||||
sha->ctx.sha_type = SHA1;
|
||||
if(sha->ctx.mode == ESP32_SHA_HW){
|
||||
sha->ctx.lockDepth = 0;
|
||||
/* release hw engine */
|
||||
esp_sha_hw_unlock();
|
||||
esp_sha_hw_unlock(&(sha->ctx));
|
||||
}
|
||||
/* always set mode as INIT
|
||||
* whether using HW or SW is determined at first call of update()
|
||||
*/
|
||||
sha->ctx.mode = ESP32_SHA_INIT;
|
||||
|
||||
sha->ctx.lockDepth = 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -538,6 +539,7 @@ int wc_InitSha_ex(wc_Sha* sha, void* heap, int devId)
|
||||
!defined(NO_WOLFSSL_ESP32WROOM32_CRYPT_HASH)
|
||||
sha->ctx.mode = ESP32_SHA_INIT;
|
||||
sha->ctx.isfirstblock = 1;
|
||||
sha->ctx.lockDepth = 0; /* keep track of how many times lock is called */
|
||||
#endif
|
||||
ret = InitSha(sha);
|
||||
if (ret != 0)
|
||||
@ -616,7 +618,8 @@ int wc_ShaUpdate(wc_Sha* sha, const byte* data, word32 len)
|
||||
}
|
||||
if (sha->ctx.mode == ESP32_SHA_SW) {
|
||||
ret = XTRANSFORM(sha, (const byte*)local);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
esp_sha_process(sha, (const byte*)local);
|
||||
}
|
||||
#else
|
||||
@ -670,7 +673,8 @@ int wc_ShaUpdate(wc_Sha* sha, const byte* data, word32 len)
|
||||
}
|
||||
if (sha->ctx.mode == ESP32_SHA_SW){
|
||||
ret = XTRANSFORM(sha, (const byte*)local32);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
esp_sha_process(sha, (const byte*)local32);
|
||||
}
|
||||
#else
|
||||
@ -753,7 +757,8 @@ int wc_ShaFinal(wc_Sha* sha, byte* hash)
|
||||
}
|
||||
if (sha->ctx.mode == ESP32_SHA_SW) {
|
||||
ret = XTRANSFORM(sha, (const byte*)local);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
ret = esp_sha_process(sha, (const byte*)local);
|
||||
}
|
||||
#else
|
||||
@ -793,7 +798,8 @@ int wc_ShaFinal(wc_Sha* sha, byte* hash)
|
||||
}
|
||||
if (sha->ctx.mode == ESP32_SHA_SW) {
|
||||
ret = XTRANSFORM(sha, (const byte*)local);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
ret = esp_sha_digest_process(sha, 1);
|
||||
}
|
||||
#else
|
||||
@ -886,13 +892,16 @@ int wc_ShaGetHash(wc_Sha* sha, byte* hash)
|
||||
if(sha->ctx.mode == ESP32_SHA_INIT){
|
||||
esp_sha_try_hw_lock(&sha->ctx);
|
||||
}
|
||||
if(sha->ctx.mode != ESP32_SHA_SW)
|
||||
if (sha->ctx.mode != ESP32_SHA_SW) {
|
||||
/* TODO check SW/HW logic */
|
||||
esp_sha_digest_process(sha, 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
ret = wc_ShaCopy(sha, &tmpSha);
|
||||
if (ret == 0) {
|
||||
ret = wc_ShaFinal(&tmpSha, hash);
|
||||
/* if HW failed, use SW */
|
||||
ret = wc_ShaFinal(&tmpSha, hash);
|
||||
#if defined(WOLFSSL_ESP32WROOM32_CRYPT) && \
|
||||
!defined(NO_WOLFSSL_ESP32WROOM32_CRYPT_HASH)
|
||||
sha->ctx.mode = ESP32_SHA_SW;
|
||||
|
@ -1,6 +1,6 @@
|
||||
/* sha256.c
|
||||
*
|
||||
* Copyright (C) 2006-2021 wolfSSL Inc.
|
||||
* Copyright (C) 2006-2022 wolfSSL Inc.
|
||||
*
|
||||
* This file is part of wolfSSL.
|
||||
*
|
||||
@ -19,7 +19,12 @@
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
|
||||
*/
|
||||
|
||||
/* For more info on the algorithm, see https://tools.ietf.org/html/rfc6234 */
|
||||
/* For more info on the algorithm, see https://tools.ietf.org/html/rfc6234
|
||||
*
|
||||
* For more information on NIST FIPS PUB 180-4, see
|
||||
* https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.180-4.pdf
|
||||
*/
|
||||
|
||||
/*
|
||||
|
||||
DESCRIPTION
|
||||
@ -28,7 +33,11 @@ SHA-256 performs processing on message blocks to produce a final hash digest
|
||||
output. It can be used to hash a message, M, having a length of L bits,
|
||||
where 0 <= L < 2^64.
|
||||
|
||||
Note that in some cases, hardware acceleration may be enabled, depending
|
||||
on the specific device platform.
|
||||
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
@ -74,6 +83,19 @@ where 0 <= L < 2^64.
|
||||
#include <wolfssl/wolfcrypt/cryptocb.h>
|
||||
#endif
|
||||
|
||||
/* determine if we are using Espressif SHA hardware acceleration */
|
||||
#if defined(WOLFSSL_ESP32WROOM32_CRYPT) && \
|
||||
!defined(NO_WOLFSSL_ESP32WROOM32_CRYPT_HASH)
|
||||
/* define a single keyword for simplicity & readability
|
||||
*
|
||||
* by default the HW acceleration is on for ESP32-WROOM32
|
||||
* but individual components can be turned off.
|
||||
*/
|
||||
#define WOLFSSL_USE_ESP32WROOM32_CRYPT_HASH_HW
|
||||
#else
|
||||
#undef USE_ESP32WROOM32_CRYPT_HASH
|
||||
#endif
|
||||
|
||||
/* fips wrapper calls, user can call direct */
|
||||
#if defined(HAVE_FIPS) && \
|
||||
(!defined(HAVE_FIPS_VERSION) || (HAVE_FIPS_VERSION < 2))
|
||||
@ -694,14 +716,17 @@ static int InitSha256(wc_Sha256* sha256)
|
||||
return ret;
|
||||
}
|
||||
|
||||
#elif defined(WOLFSSL_ESP32WROOM32_CRYPT) && \
|
||||
!defined(NO_WOLFSSL_ESP32WROOM32_CRYPT_HASH)
|
||||
#elif defined(WOLFSSL_USE_ESP32WROOM32_CRYPT_HASH_HW)
|
||||
|
||||
/* HW may fail since there's only one, so we still need SW */
|
||||
#define NEED_SOFT_SHA256
|
||||
|
||||
/*
|
||||
* soft SHA needs initialization digest, but HW does not.
|
||||
*/
|
||||
static int InitSha256(wc_Sha256* sha256)
|
||||
{
|
||||
int ret = 0;
|
||||
int ret = 0; /* zero = success */
|
||||
|
||||
if (sha256 == NULL)
|
||||
return BAD_FUNC_ARG;
|
||||
@ -725,8 +750,9 @@ static int InitSha256(wc_Sha256* sha256)
|
||||
sha256->ctx.sha_type = SHA2_256;
|
||||
if(sha256->ctx.mode == ESP32_SHA_HW) {
|
||||
/* release hw */
|
||||
esp_sha_hw_unlock();
|
||||
esp_sha_hw_unlock(&(sha256->ctx));
|
||||
}
|
||||
|
||||
/* always set mode as INIT
|
||||
* whether using HW or SW is determined at first call of update()
|
||||
*/
|
||||
@ -734,9 +760,13 @@ static int InitSha256(wc_Sha256* sha256)
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* wolfCrypt InitSha256 external wrapper
|
||||
*/
|
||||
int wc_InitSha256_ex(wc_Sha256* sha256, void* heap, int devId)
|
||||
{
|
||||
int ret = 0;
|
||||
int ret = 0; /* zero = success */
|
||||
|
||||
if (sha256 == NULL)
|
||||
return BAD_FUNC_ARG;
|
||||
@ -744,6 +774,7 @@ static int InitSha256(wc_Sha256* sha256)
|
||||
XMEMSET(sha256, 0, sizeof(wc_Sha256));
|
||||
sha256->ctx.mode = ESP32_SHA_INIT;
|
||||
sha256->ctx.isfirstblock = 1;
|
||||
sha256->ctx.lockDepth = 0; /* we'll keep track of our own lock depth */
|
||||
(void)devId;
|
||||
|
||||
ret = InitSha256(sha256);
|
||||
@ -786,7 +817,6 @@ static int InitSha256(wc_Sha256* sha256)
|
||||
int ret = 0;
|
||||
if (sha256 == NULL)
|
||||
return BAD_FUNC_ARG;
|
||||
|
||||
ret = InitSha256(sha256);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
@ -1052,14 +1082,16 @@ static int InitSha256(wc_Sha256* sha256)
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(WOLFSSL_ESP32WROOM32_CRYPT) && \
|
||||
!defined(NO_WOLFSSL_ESP32WROOM32_CRYPT_HASH)
|
||||
if (sha256->ctx.mode == ESP32_SHA_INIT){
|
||||
#if defined(WOLFSSL_USE_ESP32WROOM32_CRYPT_HASH_HW)
|
||||
if (sha256->ctx.mode == ESP32_SHA_INIT ||
|
||||
sha256->ctx.mode == ESP32_SHA_FAIL_NEED_UNROLL) {
|
||||
esp_sha_try_hw_lock(&sha256->ctx);
|
||||
}
|
||||
if (sha256->ctx.mode == ESP32_SHA_SW){
|
||||
|
||||
if (sha256->ctx.mode == ESP32_SHA_SW) {
|
||||
ret = XTRANSFORM(sha256, (const byte*)local);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
esp_sha256_process(sha256, (const byte*)local);
|
||||
}
|
||||
#else
|
||||
@ -1129,17 +1161,17 @@ static int InitSha256(wc_Sha256* sha256)
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(WOLFSSL_ESP32WROOM32_CRYPT) && \
|
||||
!defined(NO_WOLFSSL_ESP32WROOM32_CRYPT_HASH)
|
||||
#if defined(WOLFSSL_USE_ESP32WROOM32_CRYPT_HASH_HW)
|
||||
if (sha256->ctx.mode == ESP32_SHA_INIT){
|
||||
esp_sha_try_hw_lock(&sha256->ctx);
|
||||
}
|
||||
if (sha256->ctx.mode == ESP32_SHA_SW){
|
||||
if (sha256->ctx.mode == ESP32_SHA_SW) {
|
||||
ret = XTRANSFORM(sha256, (const byte*)local32);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
esp_sha256_process(sha256, (const byte*)local32);
|
||||
}
|
||||
#else
|
||||
#else
|
||||
ret = XTRANSFORM(sha256, (const byte*)local32);
|
||||
#endif
|
||||
|
||||
@ -1223,14 +1255,14 @@ static int InitSha256(wc_Sha256* sha256)
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(WOLFSSL_ESP32WROOM32_CRYPT) && \
|
||||
!defined(NO_WOLFSSL_ESP32WROOM32_CRYPT_HASH)
|
||||
#if defined(WOLFSSL_USE_ESP32WROOM32_CRYPT_HASH_HW)
|
||||
if (sha256->ctx.mode == ESP32_SHA_INIT) {
|
||||
esp_sha_try_hw_lock(&sha256->ctx);
|
||||
}
|
||||
if (sha256->ctx.mode == ESP32_SHA_SW) {
|
||||
ret = XTRANSFORM(sha256, (const byte*)local);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
ret = esp_sha256_process(sha256, (const byte*)local);
|
||||
}
|
||||
#else
|
||||
@ -1280,14 +1312,14 @@ static int InitSha256(wc_Sha256* sha256)
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(WOLFSSL_ESP32WROOM32_CRYPT) && \
|
||||
!defined(NO_WOLFSSL_ESP32WROOM32_CRYPT_HASH)
|
||||
#if defined(WOLFSSL_USE_ESP32WROOM32_CRYPT_HASH_HW)
|
||||
if (sha256->ctx.mode == ESP32_SHA_INIT) {
|
||||
esp_sha_try_hw_lock(&sha256->ctx);
|
||||
}
|
||||
if (sha256->ctx.mode == ESP32_SHA_SW) {
|
||||
ret = XTRANSFORM(sha256, (const byte*)local);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
ret = esp_sha256_digest_process(sha256, 1);
|
||||
}
|
||||
#else
|
||||
@ -1385,7 +1417,6 @@ static int InitSha256(wc_Sha256* sha256)
|
||||
{
|
||||
if (sha224 == NULL)
|
||||
return BAD_FUNC_ARG;
|
||||
|
||||
(void)devId;
|
||||
(void)heap;
|
||||
|
||||
@ -1848,9 +1879,15 @@ int wc_Sha256GetHash(wc_Sha256* sha256, byte* hash)
|
||||
if (sha256 == NULL || hash == NULL)
|
||||
return BAD_FUNC_ARG;
|
||||
|
||||
#if defined(WOLFSSL_ESP32WROOM32_CRYPT) && \
|
||||
!defined(NO_WOLFSSL_ESP32WROOM32_CRYPT_HASH)
|
||||
if(sha256->ctx.mode == ESP32_SHA_INIT){
|
||||
#if defined(WOLFSSL_USE_ESP32WROOM32_CRYPT_HASH_HW)
|
||||
|
||||
/* ESP32 hardware can only handle only 1 active hardware hashing
|
||||
* at a time. If the mutex lock is acquired the first time then
|
||||
* that Sha256 instance has exclusive access to hardware. The
|
||||
* final or free needs to release the mutex. Operations that
|
||||
* do not get the lock fallback to software based Sha256 */
|
||||
|
||||
if(sha256->ctx.mode == ESP32_SHA_INIT){
|
||||
esp_sha_try_hw_lock(&sha256->ctx);
|
||||
}
|
||||
if(sha256->ctx.mode == ESP32_SHA_HW)
|
||||
@ -1861,13 +1898,20 @@ int wc_Sha256GetHash(wc_Sha256* sha256, byte* hash)
|
||||
ret = wc_Sha256Copy(sha256, &tmpSha256);
|
||||
if (ret == 0) {
|
||||
ret = wc_Sha256Final(&tmpSha256, hash);
|
||||
#if defined(WOLFSSL_ESP32WROOM32_CRYPT) && \
|
||||
!defined(NO_WOLFSSL_ESP32WROOM32_CRYPT_HASH)
|
||||
|
||||
#if defined(WOLFSSL_USE_ESP32WROOM32_CRYPT_HASH_HW)
|
||||
{
|
||||
sha256->ctx.mode = ESP32_SHA_SW;
|
||||
}
|
||||
#endif
|
||||
|
||||
wc_Sha256Free(&tmpSha256);
|
||||
}
|
||||
|
||||
#if defined(WOLFSSL_USE_ESP32WROOM32_CRYPT_HASH_HW)
|
||||
/* TODO: Make sure the ESP32 crypto mutex is released (in case final is not
|
||||
* called */
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
int wc_Sha256Copy(wc_Sha256* src, wc_Sha256* dst)
|
||||
@ -1893,12 +1937,14 @@ int wc_Sha256Copy(wc_Sha256* src, wc_Sha256* dst)
|
||||
#ifdef WOLFSSL_PIC32MZ_HASH
|
||||
ret = wc_Pic32HashCopy(&src->cache, &dst->cache);
|
||||
#endif
|
||||
#if defined(WOLFSSL_ESP32WROOM32_CRYPT) && \
|
||||
!defined(NO_WOLFSSL_ESP32WROOM32_CRYPT_HASH)
|
||||
dst->ctx.mode = src->ctx.mode;
|
||||
dst->ctx.isfirstblock = src->ctx.isfirstblock;
|
||||
dst->ctx.sha_type = src->ctx.sha_type;
|
||||
|
||||
#if defined(WOLFSSL_USE_ESP32WROOM32_CRYPT_HASH_HW)
|
||||
dst->ctx.mode = src->ctx.mode;
|
||||
dst->ctx.isfirstblock = src->ctx.isfirstblock;
|
||||
dst->ctx.sha_type = src->ctx.sha_type;
|
||||
dst->ctx.lockDepth = src->ctx.lockDepth;
|
||||
#endif
|
||||
|
||||
#ifdef WOLFSSL_HASH_FLAGS
|
||||
dst->flags |= WC_HASH_FLAG_ISCOPY;
|
||||
#endif
|
||||
|
@ -285,7 +285,7 @@ static int InitSha512(wc_Sha512* sha512)
|
||||
sha512->ctx.isfirstblock = 1;
|
||||
if(sha512->ctx.mode == ESP32_SHA_HW) {
|
||||
/* release hw */
|
||||
esp_sha_hw_unlock();
|
||||
esp_sha_hw_unlock(&(sha512->ctx));
|
||||
}
|
||||
/* always set mode as INIT
|
||||
* whether using HW or SW is determined at first call of update()
|
||||
@ -332,7 +332,7 @@ static int InitSha512_224(wc_Sha512* sha512)
|
||||
sha512->ctx.isfirstblock = 1;
|
||||
if(sha512->ctx.mode == ESP32_SHA_HW) {
|
||||
/* release hw */
|
||||
esp_sha_hw_unlock();
|
||||
esp_sha_hw_unlock(&(sha512->ctx));
|
||||
}
|
||||
/* always set mode as INIT
|
||||
* whether using HW or SW is determined at first call of update()
|
||||
@ -381,7 +381,7 @@ static int InitSha512_256(wc_Sha512* sha512)
|
||||
sha512->ctx.isfirstblock = 1;
|
||||
if(sha512->ctx.mode == ESP32_SHA_HW) {
|
||||
/* release hw */
|
||||
esp_sha_hw_unlock();
|
||||
esp_sha_hw_unlock(&(sha512->ctx));
|
||||
}
|
||||
/* always set mode as INIT
|
||||
* whether using HW or SW is determined at first call of update()
|
||||
@ -1310,7 +1310,7 @@ static int InitSha384(wc_Sha384* sha384)
|
||||
sha384->ctx.isfirstblock = 1;
|
||||
if(sha384->ctx.mode == ESP32_SHA_HW) {
|
||||
/* release hw */
|
||||
esp_sha_hw_unlock();
|
||||
esp_sha_hw_unlock(&(sha512->ctx));
|
||||
}
|
||||
/* always set mode as INIT
|
||||
* whether using HW or SW is determined at first call of update()
|
||||
|
@ -22,39 +22,44 @@
|
||||
|
||||
#define __ESP32_CRYPT_H__
|
||||
|
||||
#ifdef WOLFSSL_USER_SETTINGS
|
||||
#include "user_settings.h"
|
||||
#endif
|
||||
|
||||
#include "esp_idf_version.h"
|
||||
#include "esp_types.h"
|
||||
#include "esp_log.h"
|
||||
|
||||
#ifdef WOLFSSL_ESP32WROOM32_CRYPT_DEBUG
|
||||
#undef LOG_LOCAL_LEVEL
|
||||
#define LOG_LOCAL_LEVEL ESP_LOG_DEBUG
|
||||
#undef LOG_LOCAL_LEVEL
|
||||
#define LOG_LOCAL_LEVEL ESP_LOG_DEBUG
|
||||
#else
|
||||
#undef LOG_LOCAL_LEVEL
|
||||
#define LOG_LOCAL_LEVEL ESP_LOG_ERROR
|
||||
#undef LOG_LOCAL_LEVEL
|
||||
#define LOG_LOCAL_LEVEL ESP_LOG_DEBUG
|
||||
#endif
|
||||
|
||||
#include <freertos/FreeRTOS.h>
|
||||
#include "soc/dport_reg.h"
|
||||
#include "soc/hwcrypto_reg.h"
|
||||
|
||||
#if ESP_IDF_VERSION_MAJOR < 5
|
||||
#include "soc/cpu.h"
|
||||
#include "soc/cpu.h"
|
||||
#endif
|
||||
|
||||
#if ESP_IDF_VERSION_MAJOR >= 5
|
||||
#include "esp_private/periph_ctrl.h"
|
||||
#include "esp_private/periph_ctrl.h"
|
||||
#else
|
||||
#include "driver/periph_ctrl.h"
|
||||
#include "driver/periph_ctrl.h"
|
||||
#endif
|
||||
|
||||
#if ESP_IDF_VERSION_MAJOR >= 4
|
||||
#include <esp32/rom/ets_sys.h>
|
||||
#include <esp32/rom/ets_sys.h>
|
||||
#else
|
||||
#include <rom/ets_sys.h>
|
||||
#include <rom/ets_sys.h>
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
int esp_CryptHwMutexInit(wolfSSL_Mutex* mutex);
|
||||
@ -63,31 +68,31 @@ int esp_CryptHwMutexUnLock(wolfSSL_Mutex* mutex);
|
||||
|
||||
#ifndef NO_AES
|
||||
|
||||
#if ESP_IDF_VERSION_MAJOR >= 4
|
||||
#include "esp32/rom/aes.h"
|
||||
#else
|
||||
#include "rom/aes.h"
|
||||
#endif
|
||||
#if ESP_IDF_VERSION_MAJOR >= 4
|
||||
#include "esp32/rom/aes.h"
|
||||
#else
|
||||
#include "rom/aes.h"
|
||||
#endif
|
||||
|
||||
typedef enum tagES32_AES_PROCESS {
|
||||
ESP32_AES_LOCKHW = 1,
|
||||
ESP32_AES_UPDATEKEY_ENCRYPT = 2,
|
||||
ESP32_AES_UPDATEKEY_DECRYPT = 3,
|
||||
ESP32_AES_UNLOCKHW = 4
|
||||
} ESP32_AESPROCESS;
|
||||
typedef enum tagES32_AES_PROCESS {
|
||||
ESP32_AES_LOCKHW = 1,
|
||||
ESP32_AES_UPDATEKEY_ENCRYPT = 2,
|
||||
ESP32_AES_UPDATEKEY_DECRYPT = 3,
|
||||
ESP32_AES_UNLOCKHW = 4
|
||||
} ESP32_AESPROCESS;
|
||||
|
||||
struct Aes;
|
||||
int wc_esp32AesCbcEncrypt(struct Aes* aes, byte* out, const byte* in, word32 sz);
|
||||
int wc_esp32AesCbcDecrypt(struct Aes* aes, byte* out, const byte* in, word32 sz);
|
||||
int wc_esp32AesEncrypt(struct Aes *aes, const byte* in, byte* out);
|
||||
int wc_esp32AesDecrypt(struct Aes *aes, const byte* in, byte* out);
|
||||
struct Aes; /* see aes.h */
|
||||
int wc_esp32AesCbcEncrypt(struct Aes* aes, byte* out, const byte* in, word32 sz);
|
||||
int wc_esp32AesCbcDecrypt(struct Aes* aes, byte* out, const byte* in, word32 sz);
|
||||
int wc_esp32AesEncrypt(struct Aes *aes, const byte* in, byte* out);
|
||||
int wc_esp32AesDecrypt(struct Aes *aes, const byte* in, byte* out);
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef WOLFSSL_ESP32WROOM32_CRYPT_DEBUG
|
||||
|
||||
void wc_esp32TimerStart();
|
||||
uint64_t wc_esp32elapsedTime();
|
||||
void wc_esp32TimerStart();
|
||||
uint64_t wc_esp32elapsedTime();
|
||||
|
||||
#endif /* WOLFSSL_ESP32WROOM32_CRYPT_DEBUG */
|
||||
|
||||
@ -95,66 +100,107 @@ uint64_t wc_esp32elapsedTime();
|
||||
defined(WOLFSSL_SHA512)) && \
|
||||
!defined(NO_WOLFSSL_ESP32WROOM32_CRYPT_HASH)
|
||||
|
||||
/* RAW hash function APIs are not implemented with esp32 hardware acceleration*/
|
||||
#define WOLFSSL_NO_HASH_RAW
|
||||
#define SHA_CTX ETS_SHAContext
|
||||
#if ESP_IDF_VERSION_MAJOR >= 4
|
||||
#include "esp32/rom/sha.h"
|
||||
#else
|
||||
#include "rom/sha.h"
|
||||
#endif
|
||||
#undef SHA_CTX
|
||||
/* RAW hash function APIs are not implemented with esp32 hardware acceleration*/
|
||||
#define WOLFSSL_NO_HASH_RAW
|
||||
#define SHA_CTX ETS_SHAContext
|
||||
|
||||
typedef enum {
|
||||
ESP32_SHA_INIT = 0,
|
||||
ESP32_SHA_HW = 1,
|
||||
ESP32_SHA_SW = 2,
|
||||
} ESP32_DOSHA;
|
||||
#if ESP_IDF_VERSION_MAJOR >= 4
|
||||
#include "esp32/rom/sha.h"
|
||||
#else
|
||||
#include "rom/sha.h"
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
byte isfirstblock;
|
||||
/* 0 , 1 hard, 2 soft */
|
||||
byte mode;
|
||||
/* sha_type */
|
||||
enum SHA_TYPE sha_type;
|
||||
} WC_ESP32SHA;
|
||||
#undef SHA_CTX
|
||||
|
||||
int esp_sha_try_hw_lock(WC_ESP32SHA* ctx);
|
||||
void esp_sha_hw_unlock( void );
|
||||
typedef enum {
|
||||
ESP32_SHA_INIT = 0,
|
||||
ESP32_SHA_HW = 1,
|
||||
ESP32_SHA_SW = 2,
|
||||
ESP32_SHA_FAIL_NEED_UNROLL = -1
|
||||
} ESP32_MODE;
|
||||
|
||||
struct wc_Sha;
|
||||
int esp_sha_digest_process(struct wc_Sha* sha, byte bockprocess);
|
||||
int esp_sha_process(struct wc_Sha* sha, const byte* data);
|
||||
typedef struct {
|
||||
byte isfirstblock;
|
||||
|
||||
#ifndef NO_SHA256
|
||||
struct wc_Sha256;
|
||||
int esp_sha256_digest_process(struct wc_Sha256* sha, byte bockprocess);
|
||||
int esp_sha256_process(struct wc_Sha256* sha, const byte* data);
|
||||
#endif
|
||||
ESP32_MODE mode; /* typically 0 init, 1 HW, 2 SW */
|
||||
|
||||
#if defined(WOLFSSL_SHA512) || defined(WOLFSSL_SHA384)
|
||||
struct wc_Sha512;
|
||||
int esp_sha512_process(struct wc_Sha512* sha);
|
||||
int esp_sha512_digest_process(struct wc_Sha512* sha, byte blockproc);
|
||||
#endif
|
||||
/* we'll keep track of our own locks.
|
||||
* actual enable/disable only occurs for ref_counts[periph] == 0 */
|
||||
int lockDepth; /* see ref_counts[periph] in periph_ctrl.c */
|
||||
|
||||
enum SHA_TYPE sha_type;
|
||||
} WC_ESP32SHA;
|
||||
|
||||
int esp_sha_try_hw_lock(WC_ESP32SHA* ctx);
|
||||
int esp_sha_hw_unlock(WC_ESP32SHA* ctx);
|
||||
|
||||
struct wc_Sha;
|
||||
int esp_sha_digest_process(struct wc_Sha* sha, byte blockprocess);
|
||||
int esp_sha_process(struct wc_Sha* sha, const byte* data);
|
||||
|
||||
#ifndef NO_SHA256
|
||||
struct wc_Sha256;
|
||||
int esp_sha256_digest_process(struct wc_Sha256* sha, byte blockprocess);
|
||||
int esp_sha256_process(struct wc_Sha256* sha, const byte* data);
|
||||
int esp32_Transform_Sha256_demo(struct wc_Sha256* sha256, const byte* data);
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
/* TODO do we really call esp_sha512_process for WOLFSSL_SHA384 ? */
|
||||
#if defined(WOLFSSL_SHA512) || defined(WOLFSSL_SHA384)
|
||||
struct wc_Sha512;
|
||||
int esp_sha512_process(struct wc_Sha512* sha);
|
||||
int esp_sha512_digest_process(struct wc_Sha512* sha, byte blockproc);
|
||||
#endif
|
||||
|
||||
#endif /* NO_SHA && */
|
||||
|
||||
|
||||
#if !defined(NO_RSA) || defined(HAVE_ECC)
|
||||
|
||||
#if !defined(ESP_RSA_TIMEOUT_CNT)
|
||||
#define ESP_RSA_TIMEOUT_CNT 0x249F00
|
||||
#endif
|
||||
#if !defined(ESP_RSA_TIMEOUT_CNT)
|
||||
#define ESP_RSA_TIMEOUT_CNT 0x249F00
|
||||
#endif
|
||||
|
||||
struct fp_int;
|
||||
int esp_mp_mul(struct fp_int* X, struct fp_int* Y, struct fp_int* Z);
|
||||
int esp_mp_exptmod(struct fp_int* G, struct fp_int* X, word32 Xbits, struct fp_int* P,
|
||||
struct fp_int* Y);
|
||||
int esp_mp_mulmod(struct fp_int* X, struct fp_int* Y, struct fp_int* M,
|
||||
struct fp_int* Z);
|
||||
/* operands can be up to 4096 bits long.
|
||||
* here we store the bits in wolfSSL fp_int struct.
|
||||
* see wolfCrypt tfm.h
|
||||
*/
|
||||
struct fp_int;
|
||||
|
||||
|
||||
/*
|
||||
* The parameter names in the Espressif implementation are arbitrary.
|
||||
*
|
||||
* The wolfSSL names come from DH: Y=G^x mod M (see wolfcrypt/tfm.h)
|
||||
*
|
||||
* G=base, X is the private exponent, Y is the public value w
|
||||
**/
|
||||
|
||||
/* Z = (X ^ Y) mod M : Espressif generic notation */
|
||||
/* Y = (G ^ X) mod P : wolfSSL DH reference notation */
|
||||
int esp_mp_exptmod(struct fp_int* X, /* G */
|
||||
struct fp_int* Y, /* X */
|
||||
word32 Xbits, /* Ys typically = fp_count_bits (X) */
|
||||
struct fp_int* M, /* P */
|
||||
struct fp_int* Z); /* Y */
|
||||
|
||||
/* Z = X * Y */
|
||||
int esp_mp_mul(struct fp_int* X,
|
||||
struct fp_int* Y,
|
||||
struct fp_int* Z);
|
||||
|
||||
|
||||
/* Z = X * Y (mod M) */
|
||||
int esp_mp_mulmod(struct fp_int* X,
|
||||
struct fp_int* Y,
|
||||
struct fp_int* M,
|
||||
struct fp_int* Z);
|
||||
|
||||
#endif /* NO_RSA || HAVE_ECC*/
|
||||
|
||||
/* end c++ wrapper */
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -1,6 +1,6 @@
|
||||
/* types.h
|
||||
*
|
||||
* Copyright (C) 2006-2021 wolfSSL Inc.
|
||||
* Copyright (C) 2006-2022 wolfSSL Inc.
|
||||
*
|
||||
* This file is part of wolfSSL.
|
||||
*
|
||||
@ -714,7 +714,7 @@ typedef struct w64wrapper {
|
||||
/* In cases when truncation is expected the caller needs*/
|
||||
/* to check the return value from the function so that */
|
||||
/* compiler doesn't complain. */
|
||||
/* xtensa-esp32-elf v8.2.0 warns trancation at */
|
||||
/* xtensa-esp32-elf v8.2.0 warns truncation at */
|
||||
/* GetAsnTimeString() */
|
||||
static WC_INLINE
|
||||
int _xsnprintf_(char *s, size_t n, const char *format, ...)
|
||||
|
Reference in New Issue
Block a user