SHA: add HAL layer and refactor driver

Add a LL and HAL layer for SHA.
pull/5682/merge
Marius Vikhammer 2020-08-13 16:30:59 +08:00 zatwierdzone przez bot
rodzic a587cd1774
commit 949fb8e63a
42 zmienionych plików z 1752 dodań i 2166 usunięć

Wyświetl plik

@ -16,7 +16,7 @@
#include "soc/rtc.h"
#include "esp_log.h"
#include "mbedtls/sha256.h"
#include "esp32/sha.h"
#include "sha/sha_parallel_engine.h"
#include "esp32/aes.h"
#include "mbedtls/rsa.h"

Wyświetl plik

@ -13,7 +13,7 @@
#include "mbedtls/sha1.h"
#include "mbedtls/sha256.h"
#include "mbedtls/sha512.h"
#include "esp32/sha.h"
#include "sha/sha_parallel_engine.h"
#include "ccomp_timer.h"
/* Note: Most of the SHA functions are called as part of mbedTLS, so

Wyświetl plik

@ -13,7 +13,7 @@
#include "mbedtls/sha1.h"
#include "mbedtls/sha256.h"
#include "mbedtls/sha512.h"
#include "esp32s2/sha.h"
#include "sha/sha_dma.h"
/* Note: Most of the SHA functions are called as part of mbedTLS, so
are tested as part of mbedTLS tests. Only esp_sha() is different.

Wyświetl plik

@ -16,6 +16,7 @@ else()
"clk.c"
"crosscore_int.c"
"dport_access.c"
"esp_crypto_lock.c"
"hw_random.c"
"memprot.c"

Wyświetl plik

@ -0,0 +1,56 @@
// Copyright 2015-2020 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include <sys/lock.h>
#include "esp_crypto_lock.h"
/* Lock for the SHA peripheral, also used by the HMAC and DS peripheral */
static _lock_t s_crypto_sha_lock;
/* Lock for the AES peripheral, also used by DS peripheral */
static _lock_t s_crypto_aes_lock;
/* Lock for the MPI/RSA peripheral, also used by the DS peripheral */
static _lock_t s_crypto_mpi_lock;
void esp_crypto_sha_lock_acquire(void)
{
_lock_acquire(&s_crypto_sha_lock);
}
void esp_crypto_sha_lock_release(void)
{
_lock_release(&s_crypto_sha_lock);
}
void esp_crypto_aes_lock_acquire(void)
{
_lock_acquire(&s_crypto_aes_lock);
}
void esp_crypto_aes_lock_release(void)
{
_lock_release(&s_crypto_aes_lock);
}
void esp_crypto_mpi_lock_acquire(void)
{
_lock_acquire(&s_crypto_mpi_lock);
}
void esp_crypto_mpi_lock_release(void)
{
_lock_release(&s_crypto_mpi_lock);
}

Wyświetl plik

@ -0,0 +1,61 @@
// Copyright 2015-2020 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
/**
* This API should be used by all components which use the SHA, AES, HMAC and DS crypto hardware on the ESP32S3.
* Not all of them can be used in parallel because they use the same underlying module.
* E.g., HMAC uses SHA or DS uses HMAC and AES. See the ESP32S3 Technical Reference Manual for more details.
*
* Other unrelated components must not use it.
*/
/**
* Acquire lock for the SHA cryptography peripheral
*/
void esp_crypto_sha_lock_acquire(void);
/**
* Release lock for the SHA cryptography peripheral
*/
void esp_crypto_sha_lock_release(void);
/**
* Acquire lock for the AES cryptography peripheral
*/
void esp_crypto_aes_lock_acquire(void);
/**
* Release lock for the AES cryptography peripheral
*/
void esp_crypto_aes_lock_release(void);
/**
* Acquire lock for the MPI/RSA cryptography peripheral
*/
void esp_crypto_mpi_lock_acquire(void);
/**
* Release lock for the MPI/RSA cryptography peripheral
*/
void esp_crypto_mpi_lock_release(void);
#ifdef __cplusplus
}
#endif

Wyświetl plik

@ -24,6 +24,7 @@
#include <stdint.h>
#include <stdbool.h>
#include <stddef.h>
#ifdef __cplusplus
extern "C" {
@ -44,7 +45,7 @@ enum SHA_TYPE {
SHA_INVALID = -1,
};
/* Do not use these function in multi core mode due to
/* Do not use these function in multi core mode due to
* inside they have no safe implementation (without DPORT workaround).
*/
void ets_sha_init(SHA_CTX *ctx);

Wyświetl plik

@ -32,6 +32,7 @@ if(NOT BOOTLOADER_BUILD)
"soc_hal.c"
"twai_hal.c"
"interrupt_controller_hal.c"
"sha_hal.c"
"${target}/interrupt_descriptor_table.c")
if(${target} STREQUAL "esp32")

Wyświetl plik

@ -0,0 +1,156 @@
// Copyright 2020 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once
#include <stdbool.h>
#include "hal/sha_types.h"
#include "soc/hwcrypto_reg.h"
#include "soc/dport_access.h"
#ifdef __cplusplus
extern "C" {
#endif
#define SHA_LL_TYPE_OFFSET 0x10
/**
* @brief Returns the LOAD_REG register address for the given sha type
*
* @param sha_type The SHA algorithm type
* @return uint32_t the LOAD_REG register address
*/
inline static uint32_t SHA_LOAD_REG(esp_sha_type sha_type)
{
return SHA_1_LOAD_REG + sha_type * SHA_LL_TYPE_OFFSET;
}
/**
* @brief Returns the BUSY register address for the given sha type
*
* @param sha_type The SHA algorithm type
* @return uint32_t the BUSY register address
*/
inline static uint32_t SHA_BUSY_REG(esp_sha_type sha_type)
{
return SHA_1_BUSY_REG + sha_type * SHA_LL_TYPE_OFFSET;
}
/**
* @brief Returns the START register address for the given sha type
*
* @param sha_type The SHA algorithm type
* @return uint32_t the START register address
*/
inline static uint32_t SHA_START_REG(esp_sha_type sha_type)
{
return SHA_1_START_REG + sha_type * SHA_LL_TYPE_OFFSET;
}
/**
* @brief Returns the CONTINUE register address for the given sha type
*
* @param sha_type The SHA algorithm type
* @return uint32_t the CONTINUE register address
*/
inline static uint32_t SHA_CONTINUE_REG(esp_sha_type sha_type)
{
return SHA_1_CONTINUE_REG + sha_type * SHA_LL_TYPE_OFFSET;
}
/**
* @brief Start a new SHA block conversion (no initial hash in HW)
*
* @param sha_type The SHA algorithm type
*/
static inline void sha_ll_start_block(esp_sha_type sha_type)
{
DPORT_REG_WRITE(SHA_START_REG(sha_type), 1);
}
/**
* @brief Continue a SHA block conversion (initial hash in HW)
*
* @param sha_type The SHA algorithm type
*/
static inline void sha_ll_continue_block(esp_sha_type sha_type)
{
DPORT_REG_WRITE(SHA_CONTINUE_REG(sha_type), 1);
}
/**
* @brief Load the current hash digest to digest register
*
* @param sha_type The SHA algorithm type
*/
static inline void sha_ll_load(esp_sha_type sha_type)
{
DPORT_REG_WRITE(SHA_LOAD_REG(sha_type), 1);
}
/**
* @brief Checks if the SHA engine is currently busy hashing a block
*
* @return true SHA engine busy
* @return false SHA engine idle
*/
static inline bool sha_ll_busy(void)
{
return (DPORT_REG_READ(SHA_1_BUSY_REG) || DPORT_REG_READ(SHA_256_BUSY_REG)
|| DPORT_REG_READ(SHA_384_BUSY_REG) || DPORT_REG_READ(SHA_512_BUSY_REG));
}
/**
* @brief Write a text (message) block to the SHA engine
*
* @param input_text Input buffer to be written to the SHA engine
* @param block_word_len Number of words in block
*/
static inline void sha_ll_fill_text_block(const void *input_text, size_t block_word_len)
{
uint32_t *reg_addr_buf = NULL;
uint32_t *data_words = NULL;
reg_addr_buf = (uint32_t *)(SHA_TEXT_BASE);
data_words = (uint32_t *)input_text;
for (int i = 0; i < block_word_len; i++) {
reg_addr_buf[i] = __builtin_bswap32(data_words[i]);
}
}
/**
* @brief Read the message digest from the SHA engine
*
* @param sha_type The SHA algorithm type
* @param digest_state Buffer that message digest will be written to
* @param digest_word_len Length of the message digest
*/
static inline void sha_ll_read_digest(esp_sha_type sha_type, void *digest_state, size_t digest_word_len)
{
uint32_t *digest_state_words = (uint32_t *)digest_state;
uint32_t *reg_addr_buf = (uint32_t *)(SHA_TEXT_BASE);
if (sha_type == SHA2_384 || sha_type == SHA2_512) {
/* for these ciphers using 64-bit states, swap each pair of words */
DPORT_INTERRUPT_DISABLE(); // Disable interrupt only on current CPU.
for (int i = 0; i < digest_word_len; i += 2) {
digest_state_words[i + 1] = DPORT_SEQUENCE_REG_READ((uint32_t)&reg_addr_buf[i]);
digest_state_words[i] = DPORT_SEQUENCE_REG_READ((uint32_t)&reg_addr_buf[i + 1]);
}
DPORT_INTERRUPT_RESTORE(); // restore the previous interrupt level
} else {
esp_dport_access_read_buffer(digest_state_words, (uint32_t)&reg_addr_buf[0], digest_word_len);
}
}
#ifdef __cplusplus
}
#endif

Wyświetl plik

@ -0,0 +1,81 @@
// Copyright 2020 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/*******************************************************************************
* NOTICE
* The ll is not public api, don't use in application code.
* See readme.md in soc/include/hal/readme.md
******************************************************************************/
#pragma once
#include "soc/hwcrypto_reg.h"
#include "soc/dport_reg.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef enum {
CRYPTO_DMA_AES = 0,
CRYPTO_DMA_SHA,
} crypto_dma_mode_t;
/**
* @brief Resets set the outlink
*
*/
static inline void crypto_dma_ll_outlink_reset(void)
{
SET_PERI_REG_MASK(CRYPTO_DMA_CONF0_REG, CONF0_REG_AHBM_RST | CONF0_REG_OUT_RST | CONF0_REG_AHBM_FIFO_RST);
CLEAR_PERI_REG_MASK(CRYPTO_DMA_CONF0_REG, CONF0_REG_AHBM_RST | CONF0_REG_OUT_RST | CONF0_REG_AHBM_FIFO_RST);
}
/**
* @brief Selects the crypto DMA mode
*
* @param mode Mode to use, AES or SHA
*/
static inline void crypto_dma_ll_set_mode(crypto_dma_mode_t mode)
{
REG_WRITE(CRYPTO_DMA_AES_SHA_SELECT_REG, mode);
}
/**
* @brief Sets up the outlink for a transfer
*
* @param outlink_addr Address of the outlink buffer
*/
static inline void crypto_dma_ll_outlink_set(uint32_t outlink_addr)
{
CLEAR_PERI_REG_MASK(CRYPTO_DMA_OUT_LINK_REG, OUT_LINK_REG_OUTLINK_ADDR);
SET_PERI_REG_MASK(CRYPTO_DMA_OUT_LINK_REG, outlink_addr & OUT_LINK_REG_OUTLINK_ADDR);
}
/**
* @brief Starts the outlink
*
*/
static inline void crypto_dma_ll_outlink_start(void)
{
SET_PERI_REG_MASK(CRYPTO_DMA_OUT_LINK_REG, OUT_LINK_REG_OUTLINK_START);
}
#ifdef __cplusplus
}
#endif

Wyświetl plik

@ -0,0 +1,173 @@
// Copyright 2020 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once
#include <stdbool.h>
#include "soc/hwcrypto_reg.h"
#include "hal/sha_types.h"
#include "soc/dport_reg.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Start a new SHA block conversions (no initial hash in HW)
*
* @param sha_type The SHA algorithm type
*/
static inline void sha_ll_start_block(esp_sha_type sha_type)
{
REG_WRITE(SHA_MODE_REG, sha_type);
REG_WRITE(SHA_START_REG, 1);
}
/**
* @brief Continue a SHA block conversion (initial hash in HW)
*
* @param sha_type The SHA algorithm type
*/
static inline void sha_ll_continue_block(esp_sha_type sha_type)
{
REG_WRITE(SHA_MODE_REG, sha_type);
REG_WRITE(SHA_CONTINUE_REG, 1);
}
/**
* @brief Start a new SHA message conversion using DMA (no initial hash in HW)
*
* @param sha_type The SHA algorithm type
*/
static inline void sha_ll_start_dma(esp_sha_type sha_type)
{
REG_WRITE(SHA_MODE_REG, sha_type);
REG_WRITE(SHA_DMA_START_REG, 1);
}
/**
* @brief Continue a SHA message conversion using DMA (initial hash in HW)
*
* @param sha_type The SHA algorithm type
*/
static inline void sha_ll_continue_dma(esp_sha_type sha_type)
{
REG_WRITE(SHA_MODE_REG, sha_type);
REG_WRITE(SHA_DMA_CONTINUE_REG, 1);
}
/**
* @brief Load the current hash digest to digest register
*
* @note Happens automatically on ESP32S2
*
* @param sha_type The SHA algorithm type
*/
static inline void sha_ll_load(esp_sha_type sha_type)
{
}
/**
* @brief Sets the number of message blocks to be hashed
*
* @note DMA operation only
*
* @param num_blocks Number of message blocks to process
*/
static inline void sha_ll_set_block_num(size_t num_blocks)
{
REG_WRITE(SHA_BLOCK_NUM_REG, num_blocks);
}
/**
* @brief Checks if the SHA engine is currently busy hashing a block
*
* @return true SHA engine busy
* @return false SHA engine idle
*/
static inline bool sha_ll_busy(void)
{
return REG_READ(SHA_BUSY_REG);
}
/**
* @brief Write a text (message) block to the SHA engine
*
* @param input_text Input buffer to be written to the SHA engine
* @param block_word_len Number of words in block
*/
static inline void sha_ll_fill_text_block(const void *input_text, size_t block_word_len)
{
uint32_t *data_words = (uint32_t *)input_text;
uint32_t *reg_addr_buf = (uint32_t *)(SHA_TEXT_BASE);
for (int i = 0; i < block_word_len; i++) {
REG_WRITE(&reg_addr_buf[i], data_words[i]);
}
}
/**
* @brief Read the message digest from the SHA engine
*
* @param sha_type The SHA algorithm type
* @param digest_state Buffer that message digest will be written to
* @param digest_word_len Length of the message digest
*/
static inline void sha_ll_read_digest(esp_sha_type sha_type, void *digest_state, size_t digest_word_len)
{
uint32_t *digest_state_words = (uint32_t *)digest_state;
esp_dport_access_read_buffer(digest_state_words, SHA_H_BASE, digest_word_len);
}
/**
* @brief Write the message digest to the SHA engine
*
* @param sha_type The SHA algorithm type
* @param digest_state Message digest to be written to SHA engine
* @param digest_word_len Length of the message digest
*/
static inline void sha_ll_write_digest(esp_sha_type sha_type, void *digest_state, size_t digest_word_len)
{
uint32_t *digest_state_words = (uint32_t *)digest_state;
uint32_t *reg_addr_buf = (uint32_t *)(SHA_H_BASE);
for (int i = 0; i < digest_word_len; i++) {
REG_WRITE(&reg_addr_buf[i], digest_state_words[i]);
}
}
/**
* @brief Sets SHA512_t T_string parameter
*
* @param t_string T_string parameter
*/
static inline void sha_ll_t_string_set(uint32_t t_string)
{
REG_WRITE(SHA_T_STRING_REG, t_string);
}
/**
* @brief Sets SHA512_t T_string parameter's length
*
* @param t_len T_string parameter length
*/
static inline void sha_ll_t_len_set(uint8_t t_len)
{
REG_WRITE(SHA_T_LENGTH_REG, t_len);
}
#ifdef __cplusplus
}
#endif

Wyświetl plik

@ -230,6 +230,7 @@ static uint32_t periph_ll_get_rst_en_reg(periph_module_t periph)
case PERIPH_SDMMC_MODULE:
case PERIPH_GDMA_MODULE:
case PERIPH_AES_MODULE:
case PERIPH_SHA_MODULE:
case PERIPH_RSA_MODULE:
return SYSTEM_PERIP_RST_EN1_REG;
default:

Wyświetl plik

@ -0,0 +1,173 @@
// Copyright 2020 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once
#include <stdbool.h>
#include "soc/hwcrypto_reg.h"
#include "hal/sha_types.h"
#include "soc/dport_reg.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Start a new SHA block conversions (no initial hash in HW)
*
* @param sha_type The SHA algorithm type
*/
static inline void sha_ll_start_block(esp_sha_type sha_type)
{
REG_WRITE(SHA_MODE_REG, sha_type);
REG_WRITE(SHA_START_REG, 1);
}
/**
* @brief Continue a SHA block conversion (initial hash in HW)
*
* @param sha_type The SHA algorithm type
*/
static inline void sha_ll_continue_block(esp_sha_type sha_type)
{
REG_WRITE(SHA_MODE_REG, sha_type);
REG_WRITE(SHA_CONTINUE_REG, 1);
}
/**
* @brief Start a new SHA message conversion using DMA (no initial hash in HW)
*
* @param sha_type The SHA algorithm type
*/
static inline void sha_ll_start_dma(esp_sha_type sha_type)
{
REG_WRITE(SHA_MODE_REG, sha_type);
REG_WRITE(SHA_DMA_START_REG, 1);
}
/**
* @brief Continue a SHA message conversion using DMA (initial hash in HW)
*
* @param sha_type The SHA algorithm type
*/
static inline void sha_ll_continue_dma(esp_sha_type sha_type)
{
REG_WRITE(SHA_MODE_REG, sha_type);
REG_WRITE(SHA_DMA_CONTINUE_REG, 1);
}
/**
* @brief Load the current hash digest to digest register
*
* @note Happens automatically on ESP32S3
*
* @param sha_type The SHA algorithm type
*/
static inline void sha_ll_load(esp_sha_type sha_type)
{
}
/**
* @brief Sets the number of message blocks to be hashed
*
* @note DMA operation only
*
* @param num_blocks Number of message blocks to process
*/
static inline void sha_ll_set_block_num(size_t num_blocks)
{
REG_WRITE(SHA_BLOCK_NUM_REG, num_blocks);
}
/**
* @brief Checks if the SHA engine is currently busy hashing a block
*
* @return true SHA engine busy
* @return false SHA engine idle
*/
static inline bool sha_ll_busy(void)
{
return REG_READ(SHA_BUSY_REG);
}
/**
* @brief Write a text (message) block to the SHA engine
*
* @param input_text Input buffer to be written to the SHA engine
* @param block_word_len Number of words in block
*/
static inline void sha_ll_fill_text_block(const void *input_text, size_t block_word_len)
{
uint32_t *data_words = (uint32_t *)input_text;
uint32_t *reg_addr_buf = (uint32_t *)(SHA_TEXT_BASE);
for (int i = 0; i < block_word_len; i++) {
REG_WRITE(&reg_addr_buf[i], data_words[i]);
}
}
/**
* @brief Read the message digest from the SHA engine
*
* @param sha_type The SHA algorithm type
* @param digest_state Buffer that message digest will be written to
* @param digest_word_len Length of the message digest
*/
static inline void sha_ll_read_digest(esp_sha_type sha_type, void *digest_state, size_t digest_word_len)
{
uint32_t *digest_state_words = (uint32_t *)digest_state;
esp_dport_access_read_buffer(digest_state_words, SHA_H_BASE, digest_word_len);
}
/**
* @brief Write the message digest to the SHA engine
*
* @param sha_type The SHA algorithm type
* @param digest_state Message digest to be written to SHA engine
* @param digest_word_len Length of the message digest
*/
static inline void sha_ll_write_digest(esp_sha_type sha_type, void *digest_state, size_t digest_word_len)
{
uint32_t *digest_state_words = (uint32_t *)digest_state;
uint32_t *reg_addr_buf = (uint32_t *)(SHA_H_BASE);
for (int i = 0; i < digest_word_len; i++) {
REG_WRITE(&reg_addr_buf[i], digest_state_words[i]);
}
}
/**
* @brief Sets SHA512_t T_string parameter
*
* @param t_string T_string parameter
*/
static inline void sha_ll_t_string_set(uint32_t t_string)
{
REG_WRITE(SHA_T_STRING_REG, t_string);
}
/**
* @brief Sets SHA512_t T_string parameter's length
*
* @param t_len T_string parameter length
*/
static inline void sha_ll_t_len_set(uint8_t t_len)
{
REG_WRITE(SHA_T_LENGTH_REG, t_len);
}
#ifdef __cplusplus
}
#endif

Wyświetl plik

@ -0,0 +1,38 @@
// Copyright 2020 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once
#include "sdkconfig.h"
/* Use enum from rom for backwards compatibility */
#if CONFIG_IDF_TARGET_ESP32
#include "esp32/rom/sha.h"
typedef enum SHA_TYPE esp_sha_type;
#elif CONFIG_IDF_TARGET_ESP32S2
#include "esp32s2/rom/sha.h"
typedef SHA_TYPE esp_sha_type;
#elif CONFIG_IDF_TARGET_ESP32S3
#include "esp32s3/rom/sha.h"
typedef SHA_TYPE esp_sha_type;
#endif
#ifdef __cplusplus
extern "C" {
#endif
#ifdef __cplusplus
}
#endif

Wyświetl plik

@ -0,0 +1,199 @@
// Copyright 2020 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// The HAL layer for SHA
#include "hal/sha_hal.h"
#include "hal/sha_types.h"
#include "hal/sha_ll.h"
#include "soc/soc_caps.h"
#include <stdlib.h>
#include <stdio.h>
#if SOC_SHA_CRYPTO_DMA
#include "soc/crypto_dma_reg.h"
#include "hal/crypto_dma_ll.h"
#elif SOC_SHA_GENERAL_DMA
#include "hal/gdma_ll.h"
#define DMA_PERIPH_SHA 7
#endif
#define SHA1_STATE_LEN_WORDS (160 / 32)
#define SHA256_STATE_LEN_WORDS (256 / 32)
#define SHA512_STATE_LEN_WORDS (512 / 32)
#if CONFIG_IDF_TARGET_ESP32
/* Return state size (in words) for a given SHA type */
inline static size_t state_length(esp_sha_type type)
{
switch (type) {
case SHA1:
return SHA1_STATE_LEN_WORDS;
case SHA2_256:
return SHA256_STATE_LEN_WORDS;
case SHA2_384:
case SHA2_512:
return SHA512_STATE_LEN_WORDS;
default:
return 0;
}
}
#else
/* Return state size (in words) for a given SHA type */
inline static size_t state_length(esp_sha_type type)
{
switch (type) {
case SHA1:
return SHA1_STATE_LEN_WORDS;
case SHA2_224:
case SHA2_256:
return SHA256_STATE_LEN_WORDS;
case SHA2_384:
case SHA2_512:
case SHA2_512224:
case SHA2_512256:
case SHA2_512T:
return SHA512_STATE_LEN_WORDS;
default:
return 0;
}
}
#endif
/* Hash a single block */
void sha_hal_hash_block(esp_sha_type sha_type, const void *data_block, size_t block_word_len, bool first_block)
{
sha_hal_wait_idle();
sha_ll_fill_text_block(data_block, block_word_len);
/* Start hashing */
if (first_block) {
sha_ll_start_block(sha_type);
} else {
sha_ll_continue_block(sha_type);
}
}
#if SOC_SHA_SUPPORT_DMA
#if SOC_SHA_GENERAL_DMA
static inline void sha_hal_dma_init(lldesc_t *input)
{
/* Update driver when centralized DMA interface implemented, IDF-2192 */
gdma_ll_tx_enable_descriptor_burst(&GDMA, SOC_GDMA_SHA_DMA_CHANNEL, false);
gdma_ll_tx_enable_data_burst(&GDMA, SOC_GDMA_SHA_DMA_CHANNEL, false);
gdma_ll_tx_enable_auto_write_back(&GDMA, SOC_GDMA_SHA_DMA_CHANNEL, false);
gdma_ll_tx_connect_to_periph(&GDMA, SOC_GDMA_SHA_DMA_CHANNEL, DMA_PERIPH_SHA);
/* Atleast 40 bytes when accessing external RAM */
gdma_ll_tx_extend_fifo_size_to(&GDMA, SOC_GDMA_SHA_DMA_CHANNEL, 40);
gdma_ll_tx_set_block_size_psram(&GDMA, SOC_GDMA_SHA_DMA_CHANNEL, GDMA_OUT_EXT_MEM_BK_SIZE_16B);
/* Set descriptors */
gdma_ll_tx_set_desc_addr(&GDMA, SOC_GDMA_SHA_DMA_CHANNEL, (uint32_t)input);
gdma_ll_rx_reset_channel(&GDMA, SOC_GDMA_SHA_DMA_CHANNEL);
gdma_ll_tx_reset_channel(&GDMA, SOC_GDMA_SHA_DMA_CHANNEL);
/* Start transfer */
gdma_ll_tx_start(&GDMA, SOC_GDMA_SHA_DMA_CHANNEL);
}
#endif //SOC_SHA_GENERAL_DMA
#if SOC_SHA_CRYPTO_DMA
static inline void sha_hal_dma_init(lldesc_t *input)
{
crypto_dma_ll_set_mode(CRYPTO_DMA_SHA);
crypto_dma_ll_outlink_reset();
crypto_dma_ll_outlink_set((uint32_t)input);
crypto_dma_ll_outlink_start();
}
#endif
/* Hashes a number of message blocks using DMA */
void sha_hal_hash_dma(esp_sha_type sha_type, lldesc_t *input, size_t num_blocks, bool first_block)
{
sha_hal_wait_idle();
sha_hal_dma_init(input);
sha_ll_set_block_num(num_blocks);
/* Start hashing */
if (first_block) {
sha_ll_start_dma(sha_type);
} else {
sha_ll_continue_dma(sha_type);
}
}
#endif //SOC_SHA_SUPPORT_DMA
void sha_hal_wait_idle()
{
while (sha_ll_busy()) {
}
}
/* Reads the current message digest from the SHA engine */
void sha_hal_read_digest(esp_sha_type sha_type, void *digest_state)
{
uint32_t *digest_state_words = (uint32_t *)digest_state;
sha_ll_load(sha_type);
uint32_t word_len = state_length(sha_type);
sha_hal_wait_idle();
sha_ll_read_digest(sha_type, digest_state, word_len);
/* Fault injection check: verify SHA engine actually ran,
state is not all zeroes.
*/
for (int i = 0; i < word_len; i++) {
if (digest_state_words[i] != 0) {
return;
}
}
abort(); // SHA peripheral returned all zero state, probably due to fault injection
}
#if SOC_SHA_SUPPORT_RESUME
/* Writes the message digest to the SHA engine */
void sha_hal_write_digest(esp_sha_type sha_type, void *digest_state)
{
sha_ll_write_digest(sha_type, digest_state, state_length(sha_type));
}
#endif //SOC_SHA_SUPPORT_RESUME
#if SOC_SHA_SUPPORT_SHA512_T
/* Calculates and sets the initial digiest for SHA512_t */
void sha_hal_sha512_init_hash(uint32_t t_string, uint8_t t_len)
{
sha_ll_t_string_set(t_string);
sha_ll_t_len_set(t_len);
sha_ll_start_block(SHA2_512T);
sha_hal_wait_idle();
}
#endif //SOC_SHA_SUPPORT_SHA512_T

Wyświetl plik

@ -81,13 +81,20 @@ endif()
# Add port files to mbedtls targets
target_sources(mbedtls PRIVATE ${mbedtls_target_sources})
# Choose perihperal type
if(CONFIG_IDF_TARGET_ESP32)
set(SHA_PERIPHERAL_TYPE "parallel_engine")
else()
set(SHA_PERIPHERAL_TYPE "dma")
endif()
target_sources(mbedcrypto PRIVATE "${COMPONENT_DIR}/port/esp_hardware.c"
"${COMPONENT_DIR}/port/esp_mem.c"
"${COMPONENT_DIR}/port/esp_timing.c"
"${COMPONENT_DIR}/port/esp_sha.c"
"${COMPONENT_DIR}/port/sha/esp_sha.c"
"${COMPONENT_DIR}/port/esp_aes_xts.c"
"${COMPONENT_DIR}/port/${idf_target}/aes.c"
"${COMPONENT_DIR}/port/${idf_target}/sha.c"
"${COMPONENT_DIR}/port/sha/${SHA_PERIPHERAL_TYPE}/sha.c"
)
if(CONFIG_ESP_TLS_USE_DS_PERIPHERAL)
@ -108,9 +115,9 @@ if(CONFIG_MBEDTLS_HARDWARE_MPI)
endif()
if(CONFIG_MBEDTLS_HARDWARE_SHA)
target_sources(mbedcrypto PRIVATE "${COMPONENT_DIR}/port/${idf_target}/esp_sha1.c"
"${COMPONENT_DIR}/port/${idf_target}/esp_sha256.c"
"${COMPONENT_DIR}/port/${idf_target}/esp_sha512.c"
target_sources(mbedcrypto PRIVATE "${COMPONENT_DIR}/port/sha/${SHA_PERIPHERAL_TYPE}/esp_sha1.c"
"${COMPONENT_DIR}/port/sha/${SHA_PERIPHERAL_TYPE}/esp_sha256.c"
"${COMPONENT_DIR}/port/sha/${SHA_PERIPHERAL_TYPE}/esp_sha512.c"
)
endif()

Wyświetl plik

@ -2,14 +2,16 @@
# Component Makefile
#
COMPONENT_ADD_INCLUDEDIRS := port/include mbedtls/include esp_crt_bundle/include
COMPONENT_SRCDIRS := mbedtls/library port port/$(IDF_TARGET) esp_crt_bundle
COMPONENT_SRCDIRS := mbedtls/library port port/$(IDF_TARGET) port/sha port/sha/parallel_engine esp_crt_bundle
COMPONENT_OBJEXCLUDE := mbedtls/library/net_sockets.o
COMPONENT_SUBMODULES += mbedtls
# Note: some mbedTLS hardware acceleration can be enabled/disabled by config.
#
# We don't need to exclude aes.o as these functions use a different prefix (esp_aes_x) and the
@ -21,8 +23,10 @@ ifndef CONFIG_MBEDTLS_HARDWARE_MPI
COMPONENT_OBJEXCLUDE += port/esp_bignum.o port/$(IDF_TARGET)/bignum.o
endif
ifndef CONFIG_MBEDTLS_HARDWARE_SHA
COMPONENT_OBJEXCLUDE += port/$(IDF_TARGET)/esp_sha1.o port/$(IDF_TARGET)/esp_sha256.o port/$(IDF_TARGET)/esp_sha512.o
COMPONENT_OBJEXCLUDE += port/parallel_engine/esp_sha1.o port/parallel_engine/esp_sha256.o port/parallel_engine/esp_sha512.o
endif
ifdef CONFIG_MBEDTLS_CERTIFICATE_BUNDLE

Wyświetl plik

@ -1,255 +0,0 @@
/*
* SHA-1 implementation with hardware ESP32 support added.
* Uses mbedTLS software implementation for failover when concurrent
* SHA operations are in use.
*
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
* Additions Copyright (C) 2016-2020, Espressif Systems (Shanghai) PTE LTD
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
/*
* The SHA-1 standard was published by NIST in 1993.
*
* http://www.itl.nist.gov/fipspubs/fip180-1.htm
*/
#if !defined(MBEDTLS_CONFIG_FILE)
#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#if defined(MBEDTLS_SHA1_C) && defined(MBEDTLS_SHA1_ALT)
#include "mbedtls/sha1.h"
#include <string.h>
#if defined(MBEDTLS_SELF_TEST)
#if defined(MBEDTLS_PLATFORM_C)
#include "mbedtls/platform.h"
#else
#include <stdio.h>
#define mbedtls_printf printf
#endif /* MBEDTLS_PLATFORM_C */
#endif /* MBEDTLS_SELF_TEST */
#include "esp32s2/sha.h"
/* Implementation that should never be optimized out by the compiler */
static void mbedtls_zeroize( void *v, size_t n )
{
volatile unsigned char *p = (unsigned char *)v; while ( n-- ) *p++ = 0;
}
/*
* 32-bit integer manipulation macros (big endian)
*/
#ifndef PUT_UINT32_BE
#define PUT_UINT32_BE(n,b,i) \
{ \
(b)[(i) ] = (unsigned char) ( (n) >> 24 ); \
(b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \
(b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \
(b)[(i) + 3] = (unsigned char) ( (n) ); \
}
#endif
void mbedtls_sha1_init( mbedtls_sha1_context *ctx )
{
memset( ctx, 0, sizeof( mbedtls_sha1_context ) );
}
void mbedtls_sha1_free( mbedtls_sha1_context *ctx )
{
if ( ctx == NULL ) {
return;
}
mbedtls_zeroize( ctx, sizeof( mbedtls_sha1_context ) );
}
void mbedtls_sha1_clone( mbedtls_sha1_context *dst,
const mbedtls_sha1_context *src )
{
memcpy(dst, src, sizeof(mbedtls_sha1_context));
}
/*
* SHA-1 context setup
*/
int mbedtls_sha1_starts_ret( mbedtls_sha1_context *ctx )
{
ctx->total[0] = 0;
ctx->total[1] = 0;
memset( ctx, 0, sizeof( mbedtls_sha1_context ) );
ctx->mode = SHA1;
return 0;
}
#if !defined(MBEDTLS_DEPRECATED_REMOVED)
void mbedtls_sha1_starts( mbedtls_sha1_context *ctx )
{
mbedtls_sha1_starts_ret( ctx );
}
#endif
static int esp_internal_sha1_dma_process(mbedtls_sha1_context *ctx,
const uint8_t *data, size_t len,
uint8_t *buf, size_t buf_len)
{
return esp_sha_dma(SHA1, data, len, buf, buf_len, ctx->first_block);
}
int mbedtls_internal_sha1_process( mbedtls_sha1_context *ctx, const unsigned char data[64] )
{
int ret;
esp_sha_acquire_hardware();
ret = esp_sha_dma(ctx->mode, data, 64, 0, 0, ctx->first_block);
esp_sha_release_hardware();
return ret;
}
#if !defined(MBEDTLS_DEPRECATED_REMOVED)
void mbedtls_sha1_process( mbedtls_sha1_context *ctx,
const unsigned char data[64] )
{
mbedtls_internal_sha1_process( ctx, data );
}
#endif
int mbedtls_sha1_update_ret( mbedtls_sha1_context *ctx, const unsigned char *input, size_t ilen )
{
int ret;
size_t fill;
uint32_t left, len, local_len = 0;
if ( !ilen || (input == NULL)) {
return 0;
}
left = ctx->total[0] & 0x3F;
fill = 64 - left;
ctx->total[0] += (uint32_t) ilen;
ctx->total[0] &= 0xFFFFFFFF;
if ( ctx->total[0] < (uint32_t) ilen ) {
ctx->total[1]++;
}
if ( left && ilen >= fill ) {
memcpy( (void *) (ctx->buffer + left), input, fill );
input += fill;
ilen -= fill;
left = 0;
local_len = 64;
}
len = (ilen / 64) * 64;
if ( len || local_len) {
esp_sha_acquire_hardware();
if (ctx->sha_state == ESP_SHA1_STATE_INIT) {
ctx->first_block = true;
ctx->sha_state = ESP_SHA1_STATE_IN_PROCESS;
} else if (ctx->sha_state == ESP_SHA1_STATE_IN_PROCESS) {
ctx->first_block = false;
esp_sha_write_digest_state(SHA1, ctx->state);
}
ret = esp_internal_sha1_dma_process(ctx, input, len, ctx->buffer, local_len);
esp_sha_read_digest_state(SHA1, ctx->state);
esp_sha_release_hardware();
if (ret != 0) {
return ret;
}
}
if ( ilen > 0 ) {
memcpy( (void *) (ctx->buffer + left), input + len, ilen - len );
}
return 0;
}
#if !defined(MBEDTLS_DEPRECATED_REMOVED)
void mbedtls_sha1_update( mbedtls_sha1_context *ctx,
const unsigned char *input,
size_t ilen )
{
mbedtls_sha1_update_ret( ctx, input, ilen );
}
#endif
static const unsigned char sha1_padding[64] = {
0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
/*
* SHA-1 final digest
*/
int mbedtls_sha1_finish_ret( mbedtls_sha1_context *ctx, unsigned char output[20] )
{
int ret;
uint32_t last, padn;
uint32_t high, low;
unsigned char msglen[8];
high = ( ctx->total[0] >> 29 )
| ( ctx->total[1] << 3 );
low = ( ctx->total[0] << 3 );
PUT_UINT32_BE( high, msglen, 0 );
PUT_UINT32_BE( low, msglen, 4 );
last = ctx->total[0] & 0x3F;
padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
if ( ( ret = mbedtls_sha1_update_ret( ctx, sha1_padding, padn ) ) != 0 ) {
return ret;
}
if ( ( ret = mbedtls_sha1_update_ret( ctx, msglen, 8 ) ) != 0 ) {
return ret;
}
memcpy(output, ctx->state, 20);
return ret;
}
#if !defined(MBEDTLS_DEPRECATED_REMOVED)
void mbedtls_sha1_finish( mbedtls_sha1_context *ctx,
unsigned char output[20] )
{
mbedtls_sha1_finish_ret( ctx, output );
}
#endif
#endif /* MBEDTLS_SHA1_C && MBEDTLS_SHA1_ALT */

Wyświetl plik

@ -1,267 +0,0 @@
/*
* SHA-256 implementation with hardware ESP32 support added.
* Uses mbedTLS software implementation for failover when concurrent
* SHA operations are in use.
*
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
* Additions Copyright (C) 2016-2020, Espressif Systems (Shanghai) PTE LTD
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
/*
* The SHA-256 Secure Hash Standard was published by NIST in 2002.
*
* http://csrc.nist.gov/publications/fips/fips180-2/fips180-2.pdf
*/
#if !defined(MBEDTLS_CONFIG_FILE)
#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#if defined(MBEDTLS_SHA256_C) && defined(MBEDTLS_SHA256_ALT)
#include "mbedtls/sha256.h"
#include <string.h>
#if defined(MBEDTLS_SELF_TEST)
#if defined(MBEDTLS_PLATFORM_C)
#include "mbedtls/platform.h"
#else
#include <stdio.h>
#define mbedtls_printf printf
#endif /* MBEDTLS_PLATFORM_C */
#endif /* MBEDTLS_SELF_TEST */
#include "esp32s2/sha.h"
/* Implementation that should never be optimized out by the compiler */
static void mbedtls_zeroize( void *v, size_t n )
{
volatile unsigned char *p = v; while ( n-- ) *p++ = 0;
}
/*
* 32-bit integer manipulation macros (big endian)
*/
#ifndef GET_UINT32_BE
#define GET_UINT32_BE(n,b,i) \
do { \
(n) = ( (uint32_t) (b)[(i) ] << 24 ) \
| ( (uint32_t) (b)[(i) + 1] << 16 ) \
| ( (uint32_t) (b)[(i) + 2] << 8 ) \
| ( (uint32_t) (b)[(i) + 3] ); \
} while( 0 )
#endif
#ifndef PUT_UINT32_BE
#define PUT_UINT32_BE(n,b,i) \
do { \
(b)[(i) ] = (unsigned char) ( (n) >> 24 ); \
(b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \
(b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \
(b)[(i) + 3] = (unsigned char) ( (n) ); \
} while( 0 )
#endif
void mbedtls_sha256_init( mbedtls_sha256_context *ctx )
{
memset( ctx, 0, sizeof( mbedtls_sha256_context ) );
}
void mbedtls_sha256_free( mbedtls_sha256_context *ctx )
{
if ( ctx == NULL ) {
return;
}
mbedtls_zeroize( ctx, sizeof( mbedtls_sha256_context ) );
}
void mbedtls_sha256_clone( mbedtls_sha256_context *dst,
const mbedtls_sha256_context *src )
{
*dst = *src;
}
/*
* SHA-256 context setup
*/
int mbedtls_sha256_starts_ret( mbedtls_sha256_context *ctx, int is224 )
{
memset( ctx, 0, sizeof( mbedtls_sha256_context ) );
if ( is224 ) {
ctx->mode = SHA2_224;
} else {
ctx->mode = SHA2_256;
}
return 0;
}
#if !defined(MBEDTLS_DEPRECATED_REMOVED)
void mbedtls_sha256_starts( mbedtls_sha256_context *ctx,
int is224 )
{
mbedtls_sha256_starts_ret( ctx, is224 );
}
#endif
int mbedtls_internal_sha256_process( mbedtls_sha256_context *ctx, const unsigned char data[64] )
{
int ret;
esp_sha_acquire_hardware();
ret = esp_sha_dma(ctx->mode, data, 64, 0, 0, ctx->first_block);
esp_sha_release_hardware();
return ret;
}
#if !defined(MBEDTLS_DEPRECATED_REMOVED)
void mbedtls_sha256_process( mbedtls_sha256_context *ctx,
const unsigned char data[64] )
{
mbedtls_internal_sha256_process( ctx, data );
}
#endif
/*
* SHA-256 process buffer
*/
int mbedtls_sha256_update_ret( mbedtls_sha256_context *ctx, const unsigned char *input,
size_t ilen )
{
int ret = 0;
size_t fill;
uint32_t left, len, local_len = 0;
if ( ilen == 0 ) {
return 0;
}
left = ctx->total[0] & 0x3F;
fill = 64 - left;
ctx->total[0] += (uint32_t) ilen;
ctx->total[0] &= 0xFFFFFFFF;
if ( ctx->total[0] < (uint32_t) ilen ) {
ctx->total[1]++;
}
/* Check if any data pending from previous call to this API */
if ( left && ilen >= fill ) {
memcpy( (void *) (ctx->buffer + left), input, fill );
input += fill;
ilen -= fill;
left = 0;
local_len = 64;
}
len = (ilen / 64) * 64;
if ( len || local_len) {
esp_sha_acquire_hardware();
if (ctx->sha_state == ESP_SHA256_STATE_INIT) {
ctx->first_block = true;
ctx->sha_state = ESP_SHA256_STATE_IN_PROCESS;
} else if (ctx->sha_state == ESP_SHA256_STATE_IN_PROCESS) {
ctx->first_block = false;
esp_sha_write_digest_state(ctx->mode, ctx->state);
}
ret = esp_sha_dma(ctx->mode, input, len, ctx->buffer, local_len, ctx->first_block);
esp_sha_read_digest_state(ctx->mode, ctx->state);
esp_sha_release_hardware();
if (ret != 0) {
return ret;
}
}
if ( ilen > 0 ) {
memcpy( (void *) (ctx->buffer + left), input + len, ilen - len );
}
return 0;
}
#if !defined(MBEDTLS_DEPRECATED_REMOVED)
void mbedtls_sha256_update( mbedtls_sha256_context *ctx,
const unsigned char *input,
size_t ilen )
{
mbedtls_sha256_update_ret( ctx, input, ilen );
}
#endif
static const unsigned char sha256_padding[64] = {
0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
/*
* SHA-256 final digest
*/
int mbedtls_sha256_finish_ret( mbedtls_sha256_context *ctx, unsigned char output[32] )
{
int ret;
uint32_t last, padn;
uint32_t high, low;
unsigned char msglen[8];
high = ( ctx->total[0] >> 29 )
| ( ctx->total[1] << 3 );
low = ( ctx->total[0] << 3 );
PUT_UINT32_BE( high, msglen, 0 );
PUT_UINT32_BE( low, msglen, 4 );
last = ctx->total[0] & 0x3F;
padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
if ( ( ret = mbedtls_sha256_update_ret( ctx, sha256_padding, padn ) ) != 0 ) {
return ret;
}
if ( ( ret = mbedtls_sha256_update_ret( ctx, msglen, 8 ) ) != 0 ) {
return ret;
}
memcpy(output, ctx->state, 32);
return ret;
}
#if !defined(MBEDTLS_DEPRECATED_REMOVED)
void mbedtls_sha256_finish( mbedtls_sha256_context *ctx,
unsigned char output[32] )
{
mbedtls_sha256_finish_ret( ctx, output );
}
#endif
#endif /* MBEDTLS_SHA256_C && MBEDTLS_SHA256_ALT */

Wyświetl plik

@ -1,317 +0,0 @@
/*
* SHA-512 implementation with hardware ESP32 support added.
* Uses mbedTLS software implementation for failover when concurrent
* SHA operations are in use.
*
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
* Additions Copyright (C) 2016-2020, Espressif Systems (Shanghai) PTE LTD
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
/*
* The SHA-512 Secure Hash Standard was published by NIST in 2002.
*
* http://csrc.nist.gov/publications/fips/fips180-2/fips180-2.pdf
*/
#if !defined(MBEDTLS_CONFIG_FILE)
#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#if defined(MBEDTLS_SHA512_C) && defined(MBEDTLS_SHA512_ALT)
#include "mbedtls/sha512.h"
#if defined(_MSC_VER) || defined(__WATCOMC__)
#define UL64(x) x##ui64
#else
#define UL64(x) x##ULL
#endif
#include <string.h>
#if defined(MBEDTLS_SELF_TEST)
#if defined(MBEDTLS_PLATFORM_C)
#include "mbedtls/platform.h"
#else
#include <stdio.h>
#define mbedtls_printf printf
#endif /* MBEDTLS_PLATFORM_C */
#endif /* MBEDTLS_SELF_TEST */
#include "esp32s3/sha.h"
/* Implementation that should never be optimized out by the compiler */
static void mbedtls_zeroize( void *v, size_t n )
{
volatile unsigned char *p = v; while ( n-- ) *p++ = 0;
}
/*
* 64-bit integer manipulation macros (big endian)
*/
#ifndef PUT_UINT64_BE
#define PUT_UINT64_BE(n,b,i) \
{ \
(b)[(i) ] = (unsigned char) ( (n) >> 56 ); \
(b)[(i) + 1] = (unsigned char) ( (n) >> 48 ); \
(b)[(i) + 2] = (unsigned char) ( (n) >> 40 ); \
(b)[(i) + 3] = (unsigned char) ( (n) >> 32 ); \
(b)[(i) + 4] = (unsigned char) ( (n) >> 24 ); \
(b)[(i) + 5] = (unsigned char) ( (n) >> 16 ); \
(b)[(i) + 6] = (unsigned char) ( (n) >> 8 ); \
(b)[(i) + 7] = (unsigned char) ( (n) ); \
}
#endif /* PUT_UINT64_BE */
void esp_sha512_set_mode(mbedtls_sha512_context *ctx, esp_sha_type type)
{
switch (type) {
case SHA2_384:
case SHA2_512224:
case SHA2_512256:
case SHA2_512T:
ctx->mode = type;
break;
default:
ctx->mode = SHA2_512;
break;
}
}
/* For SHA512/t mode the intial hash value will depend on t */
void esp_sha512_set_t( mbedtls_sha512_context *ctx, uint16_t t_val)
{
ctx->t_val = t_val;
}
void mbedtls_sha512_init( mbedtls_sha512_context *ctx )
{
memset( ctx, 0, sizeof( mbedtls_sha512_context ) );
}
void mbedtls_sha512_free( mbedtls_sha512_context *ctx )
{
if ( ctx == NULL ) {
return;
}
mbedtls_zeroize( ctx, sizeof( mbedtls_sha512_context ) );
}
void mbedtls_sha512_clone( mbedtls_sha512_context *dst,
const mbedtls_sha512_context *src )
{
memcpy(dst, src, sizeof(mbedtls_sha512_context));
}
/*
* SHA-512 context setup
*/
int mbedtls_sha512_starts_ret( mbedtls_sha512_context *ctx, int is384 )
{
mbedtls_zeroize( ctx, sizeof( mbedtls_sha512_context ) );
if ( is384 ) {
ctx->mode = SHA2_384;
} else {
ctx->mode = SHA2_512;
}
return 0;
}
#if !defined(MBEDTLS_DEPRECATED_REMOVED)
void mbedtls_sha512_starts( mbedtls_sha512_context *ctx,
int is384 )
{
mbedtls_sha512_starts_ret( ctx, is384 );
}
#endif
static int esp_internal_sha512_dma_process(mbedtls_sha512_context *ctx,
const uint8_t *data, size_t len,
uint8_t *buf, size_t buf_len)
{
return esp_sha_dma(ctx->mode, data, len, buf, buf_len, ctx->first_block);
}
int mbedtls_internal_sha512_process( mbedtls_sha512_context *ctx, const unsigned char data[128] )
{
int ret;
esp_sha_acquire_hardware();
ret = esp_internal_sha512_dma_process(ctx, data, 128, 0, 0);
esp_sha_release_hardware();
return ret;
}
#if !defined(MBEDTLS_DEPRECATED_REMOVED)
void mbedtls_sha512_process( mbedtls_sha512_context *ctx,
const unsigned char data[128] )
{
mbedtls_internal_sha512_process( ctx, data );
}
#endif
/*
* SHA-512 process buffer
*/
int mbedtls_sha512_update_ret( mbedtls_sha512_context *ctx, const unsigned char *input,
size_t ilen )
{
int ret;
size_t fill;
unsigned int left, len, local_len = 0;
if ( ilen == 0 ) {
return 0;
}
left = (unsigned int) (ctx->total[0] & 0x7F);
fill = 128 - left;
ctx->total[0] += (uint64_t) ilen;
if ( ctx->total[0] < (uint64_t) ilen ) {
ctx->total[1]++;
}
if ( left && ilen >= fill ) {
memcpy( (void *) (ctx->buffer + left), input, fill );
input += fill;
ilen -= fill;
left = 0;
local_len = 128;
}
len = (ilen / 128) * 128;
if ( len || local_len) {
esp_sha_acquire_hardware();
if (ctx->sha_state == ESP_SHA512_STATE_INIT) {
if (ctx->mode == SHA2_512T) {
esp_sha_512_t_init_hash(ctx->t_val);
ctx->first_block = false;
} else {
ctx->first_block = true;
}
ctx->sha_state = ESP_SHA512_STATE_IN_PROCESS;
} else if (ctx->sha_state == ESP_SHA512_STATE_IN_PROCESS) {
ctx->first_block = false;
esp_sha_write_digest_state(ctx->mode, ctx->state);
}
ret = esp_internal_sha512_dma_process(ctx, input, len, ctx->buffer, local_len);
esp_sha_read_digest_state(ctx->mode, ctx->state);
esp_sha_release_hardware();
if (ret != 0) {
return ret;
}
}
if ( ilen > 0 ) {
memcpy( (void *) (ctx->buffer + left), input + len, ilen - len );
}
return 0;
}
#if !defined(MBEDTLS_DEPRECATED_REMOVED)
void mbedtls_sha512_update( mbedtls_sha512_context *ctx,
const unsigned char *input,
size_t ilen )
{
mbedtls_sha512_update_ret( ctx, input, ilen );
}
#endif
static const unsigned char sha512_padding[128] = {
0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
/*
* SHA-512 final digest
*/
int mbedtls_sha512_finish_ret( mbedtls_sha512_context *ctx, unsigned char output[64] )
{
int ret;
size_t last, padn;
uint64_t high, low;
unsigned char msglen[16];
high = ( ctx->total[0] >> 61 )
| ( ctx->total[1] << 3 );
low = ( ctx->total[0] << 3 );
PUT_UINT64_BE( high, msglen, 0 );
PUT_UINT64_BE( low, msglen, 8 );
last = (size_t)( ctx->total[0] & 0x7F );
padn = ( last < 112 ) ? ( 112 - last ) : ( 240 - last );
if ( ( ret = mbedtls_sha512_update_ret( ctx, sha512_padding, padn ) ) != 0 ) {
return ret;
}
if ( ( ret = mbedtls_sha512_update_ret( ctx, msglen, 16 ) ) != 0 ) {
return ret;
}
if (ctx->mode == SHA2_384) {
memcpy(output, ctx->state, 48);
} else {
memcpy(output, ctx->state, 64);
}
return ret;
}
#if !defined(MBEDTLS_DEPRECATED_REMOVED)
void mbedtls_sha512_finish( mbedtls_sha512_context *ctx,
unsigned char output[64] )
{
mbedtls_sha512_finish_ret( ctx, output );
}
#endif
#endif /* MBEDTLS_SHA512_C && MBEDTLS_SHA512_ALT */

Wyświetl plik

@ -1,384 +0,0 @@
/*
* ESP32 hardware accelerated SHA1/256/512 implementation
* based on mbedTLS FIPS-197 compliant version.
*
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
* Additions Copyright (C) 2016-2020, Espressif Systems (Shanghai) PTE Ltd
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
/*
* The SHA-1 standard was published by NIST in 1993.
*
* http://www.itl.nist.gov/fipspubs/fip180-1.htm
*/
typedef int _lock_t;
#include <string.h>
#include <stdio.h>
#include <sys/lock.h>
#include "esp_err.h"
#include "esp_log.h"
#include "esp32s3/rom/ets_sys.h"
#include "soc/dport_reg.h"
#include "soc/hwcrypto_reg.h"
#include "soc/soc_memory_layout.h"
#include "esp32s3/rom/cache.h"
#include "soc/cache_memory.h"
#include "freertos/FreeRTOS.h"
#include "freertos/semphr.h"
#include "esp32s3/sha.h"
#include "esp32s3/rom/lldesc.h"
#include "soc/periph_defs.h"
#include "driver/periph_ctrl.h"
#include "sys/param.h"
#include "soc/gdma_struct.h"
#include "soc/extmem_reg.h"
#define DMA_PERIPH_AES 6 /* DMA peripheral indexes */
#define DMA_PERIPH_SHA 7
#define DMA_CHANNEL 1 /* note: hard-coded */
/* Max amount of bytes in a single DMA operation is 4095,
for SHA this means that the biggest safe amount of bytes is
31 blocks of 128 bytes = 3968
*/
#define SHA_DMA_MAX_BYTES 3968
/* Lock for SHA engine */
static _lock_t s_sha_lock;
const static char *TAG = "esp-sha";
inline static size_t block_length(esp_sha_type type)
{
switch (type) {
case SHA1:
case SHA2_224:
case SHA2_256:
return 64;
case SHA2_384:
case SHA2_512:
case SHA2_512224:
case SHA2_512256:
case SHA2_512T:
return 128;
default:
return 0;
}
}
/* Return state size (in bytes) for a given SHA type */
inline static size_t state_length(esp_sha_type type)
{
switch (type) {
case SHA1:
return 160 / 8;
case SHA2_224:
case SHA2_256:
return 256 / 8;
case SHA2_384:
case SHA2_512:
case SHA2_512224:
case SHA2_512256:
case SHA2_512T:
return 512 / 8;
default:
return 0;
}
}
/* Enable SHA peripheral and then lock it */
void esp_sha_acquire_hardware()
{
_lock_acquire(&s_sha_lock);
/* Enable SHA and DMA hardware */
//periph_module_enable(PERIPH_SHA_DMA_MODULE);
REG_SET_BIT(SYSTEM_PERIP_CLK_EN1_REG, SYSTEM_CRYPTO_SHA_CLK_EN | SYSTEM_DMA_CLK_EN);
REG_CLR_BIT(SYSTEM_PERIP_RST_EN1_REG, SYSTEM_CRYPTO_SHA_RST | SYSTEM_CRYPTO_HMAC_RST |
SYSTEM_DMA_RST | SYSTEM_CRYPTO_DS_RST);
}
/* Disable SHA peripheral block and then release it */
void esp_sha_release_hardware()
{
/* Disable SHA and DMA hardware */
//periph_module_disable(PERIPH_SHA_MODULE);
REG_SET_BIT(SYSTEM_PERIP_RST_EN1_REG, SYSTEM_CRYPTO_SHA_RST | SYSTEM_DMA_RST |
SYSTEM_CRYPTO_DS_RST);
REG_CLR_BIT(SYSTEM_PERIP_CLK_EN1_REG, SYSTEM_CRYPTO_SHA_CLK_EN | SYSTEM_DMA_CLK_EN);
_lock_release(&s_sha_lock);
}
/* Busy wait until SHA is idle */
static void esp_sha_wait_idle(void)
{
while (DPORT_REG_READ(SHA_BUSY_REG) != 0) {
}
}
void esp_sha_write_digest_state(esp_sha_type sha_type, void *digest_state)
{
uint32_t *digest_state_words = (uint32_t *)digest_state;
uint32_t *reg_addr_buf = (uint32_t *)(SHA_H_BASE);
for (int i = 0; i < state_length(sha_type) / 4; i++) {
REG_WRITE(&reg_addr_buf[i], digest_state_words[i]);
}
}
/* Read the SHA digest from hardware */
void esp_sha_read_digest_state(esp_sha_type sha_type, void *digest_state)
{
uint32_t *digest_state_words = (uint32_t *)digest_state;
int word_len = state_length(sha_type) / 4;
esp_dport_access_read_buffer(digest_state_words, SHA_H_BASE, word_len);
/* Fault injection check: verify SHA engine actually ran,
state is not all zeroes.
*/
for (int i = 0; i < word_len; i++) {
if (digest_state_words[i] != 0) {
return;
}
}
abort(); // SHA peripheral returned all zero state, probably due to fault injection
}
static int esp_sha_dma_process(esp_sha_type sha_type, const void *input, uint32_t ilen,
const void *buf, uint32_t buf_len, bool is_first_block);
/* Performs SHA on multiple blocks at a time using DMA
splits up into smaller operations for inputs that exceed a single DMA list
*/
int esp_sha_dma(esp_sha_type sha_type, const void *input, uint32_t ilen,
const void *buf, uint32_t buf_len, bool is_first_block)
{
int ret = 0;
const void *dma_input;
unsigned char *non_icache_input = NULL;
unsigned char *non_icache_buf = NULL;
int dma_op_num = ( ilen / (SHA_DMA_MAX_BYTES + 1) ) + 1;
if (buf_len > 128) {
ESP_LOGE(TAG, "SHA DMA buf_len cannot exceed max size for a single block");
return -1;
}
/* DMA cannot access memory in the iCache range, copy data to temporary buffers before transfer */
if (!esp_ptr_dma_capable(input) && ilen) {
non_icache_input = malloc(sizeof(unsigned char) * MIN(ilen, SHA_DMA_MAX_BYTES));
if (non_icache_input == NULL) {
ESP_LOGE(TAG, "Failed to allocate memory");
ret = ESP_ERR_NO_MEM;
goto cleanup;
}
}
if (!esp_ptr_dma_capable(buf) && buf_len) {
non_icache_buf = malloc(sizeof(unsigned char) * buf_len);
if (non_icache_buf == NULL) {
ESP_LOGE(TAG, "Failed to allocate memory");
ret = ESP_ERR_NO_MEM;
goto cleanup;
}
memcpy(non_icache_buf, buf, buf_len);
buf = non_icache_buf;
}
/* The max amount of blocks in a single hardware operation is 2^6 - 1 = 63
Thus we only do a single DMA input list + dma buf list,
which is max 3968/64 + 64/64 = 63 blocks */
for (int i = 0; i < dma_op_num; i++) {
int dma_chunk_len = MIN(ilen, SHA_DMA_MAX_BYTES);
/* Input depends on if it's a temp alloc buffer or supplied by user */
if (non_icache_input != NULL) {
memcpy(non_icache_input, input, dma_chunk_len);
dma_input = non_icache_input;
} else {
dma_input = input;
}
ret = esp_sha_dma_process(sha_type, dma_input, dma_chunk_len, buf, buf_len, is_first_block);
if (ret != 0) {
return ret;
}
is_first_block = false;
ilen -= dma_chunk_len;
input += dma_chunk_len;
// Only append buf to the first operation
buf_len = 0;
}
cleanup:
free(non_icache_input);
free(non_icache_buf);
return ret;
}
static void esp_sha_dma_init(lldesc_t *input)
{
/* Reset DMA */
REG_CLR_BIT(SYSTEM_PERIP_CLK_EN1_REG, SYSTEM_DMA_CLK_EN);
REG_SET_BIT(SYSTEM_PERIP_CLK_EN1_REG, SYSTEM_DMA_CLK_EN);
REG_SET_BIT(SYSTEM_PERIP_RST_EN1_REG, SYSTEM_DMA_RST);
REG_CLR_BIT(SYSTEM_PERIP_RST_EN1_REG, SYSTEM_DMA_RST);
/* NOTE: all hardcoded to DMA channel 1 */
/* Note: burst mode has alignment requirements that we have not checked here */
GDMA.conf0[0].outdscr_burst_en = 0; /* was 1*/
GDMA.conf0[0].out_data_burst_en = 0; /* was 1*/
GDMA.conf0[0].out_auto_wrback = 0;
GDMA.peri_sel[0].peri_out_sel = DMA_PERIPH_SHA;
GDMA.sram_size[0].in_size = 3; /* 40 bytes, also minimum size for EDMA */
GDMA.sram_size[0].out_size = 3;
GDMA.conf1[0].in_ext_mem_bk_size = 0; // 16 bytes
GDMA.conf1[0].out_ext_mem_bk_size = 0; // 16 bytes
/* Set descriptors */
GDMA.out_link[0].addr = (uint32_t)input;
GDMA.conf0[0].in_rst = 1;
GDMA.conf0[0].in_rst = 0;
GDMA.conf0[0].out_rst = 1;
GDMA.conf0[0].out_rst = 0;
/* Start transfer */
GDMA.out_link[0].start = 1;
}
/* The initial hash value for SHA512/t is generated according to the
algorithm described in the TRM, chapter SHA-Accelerator
*/
int esp_sha_512_t_init_hash(uint16_t t)
{
uint32_t t_string = 0;
uint8_t t0, t1, t2, t_len;
if (t == 384) {
ESP_LOGE(TAG, "Invalid t for SHA512/t, t = %u,cannot be 384", t);
return -1;
}
if (t <= 9) {
t_string = (uint32_t)((1 << 23) | ((0x30 + t) << 24));
t_len = 0x48;
} else if (t <= 99) {
t0 = t % 10;
t1 = (t / 10) % 10;
t_string = (uint32_t)((1 << 15) | ((0x30 + t0) << 16) |
(((0x30 + t1) << 24)));
t_len = 0x50;
} else if (t <= 512) {
t0 = t % 10;
t1 = (t / 10) % 10;
t2 = t / 100;
t_string = (uint32_t)((1 << 7) | ((0x30 + t0) << 8) |
(((0x30 + t1) << 16) + ((0x30 + t2) << 24)));
t_len = 0x58;
} else {
ESP_LOGE(TAG, "Invalid t for SHA512/t, t = %u, must equal or less than 512", t);
return -1;
}
REG_WRITE(SHA_T_LENGTH_REG, t_len);
REG_WRITE(SHA_T_STRING_REG, t_string);
REG_WRITE(SHA_MODE_REG, SHA2_512T);
REG_WRITE(SHA_START_REG, 1);
esp_sha_wait_idle();
return 0;
}
/* Performs SHA on multiple blocks at a time */
static int esp_sha_dma_process(esp_sha_type sha_type, const void *input, uint32_t ilen,
const void *buf, uint32_t buf_len, bool is_first_block)
{
size_t blk_len = 0;
int ret = 0;
lldesc_t dma_descr_input = {};
lldesc_t dma_descr_buf = {};
lldesc_t *dma_descr_head;
blk_len = block_length(sha_type);
REG_WRITE(SHA_MODE_REG, sha_type);
REG_WRITE(SHA_BLOCK_NUM_REG, ((ilen + buf_len) / blk_len));
/* DMA descriptor for Memory to DMA-SHA transfer */
if (ilen) {
dma_descr_input.length = ilen;
dma_descr_input.size = ilen;
dma_descr_input.owner = 1;
dma_descr_input.eof = 1;
dma_descr_input.buf = (void *)input;
dma_descr_head = &dma_descr_input;
}
/* Check after input to overide head if there is any buf*/
if (buf_len) {
dma_descr_buf.length = buf_len;
dma_descr_buf.size = buf_len;
dma_descr_buf.owner = 1;
dma_descr_buf.eof = 1;
dma_descr_buf.buf = (void *)buf;
dma_descr_head = &dma_descr_buf;
}
/* Link DMA lists */
if (buf_len && ilen) {
dma_descr_buf.eof = 0;
dma_descr_buf.empty = (uint32_t)(&dma_descr_input);
}
esp_sha_dma_init(dma_descr_head);
/* Start hashing */
if (is_first_block) {
REG_WRITE(SHA_DMA_START_REG, 1);
} else {
REG_WRITE(SHA_DMA_CONTINUE_REG, 1);
}
esp_sha_wait_idle();
return ret;
}

Wyświetl plik

@ -1,4 +1,4 @@
// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
// Copyright 2019-2020 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@ -11,201 +11,10 @@
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef _ESP_SHA_H_
#define _ESP_SHA_H_
#include "esp32/rom/sha.h"
#include "esp_types.h"
#pragma once
/** @brief Low-level support functions for the hardware SHA engine
*
* @note If you're looking for a SHA API to use, try mbedtls component
* mbedtls/shaXX.h. That API supports hardware acceleration.
*
* The API in this header provides some building blocks for implementing a
* full SHA API such as the one in mbedtls, and also a basic SHA function esp_sha().
*
* Some technical details about the hardware SHA engine:
*
* - SHA accelerator engine calculates one digest at a time, per SHA
* algorithm type. It initialises and maintains the digest state
* internally. It is possible to read out an in-progress SHA digest
* state, but it is not possible to restore a SHA digest state
* into the engine.
*
* - The memory block SHA_TEXT_BASE is shared between all SHA digest
* engines, so all engines must be idle before this memory block is
* modified.
*
*/
#ifdef __cplusplus
extern "C" {
#endif
/* Defined in esp32/rom/sha.h */
typedef enum SHA_TYPE esp_sha_type;
/** @brief Calculate SHA1 or SHA2 sum of some data, using hardware SHA engine
*
* @note For more versatile SHA calculations, where data doesn't need
* to be passed all at once, try the mbedTLS mbedtls/shaX.h APIs. The
* hardware-accelerated mbedTLS implementation is also faster when
* hashing large amounts of data.
*
* @note It is not necessary to lock any SHA hardware before calling
* this function, thread safety is managed internally.
*
* @note If a TLS connection is open then this function may block
* indefinitely waiting for a SHA engine to become available. Use the
* mbedTLS SHA API to avoid this problem.
*
* @param sha_type SHA algorithm to use.
*
* @param input Input data buffer.
*
* @param ilen Length of input data in bytes.
*
* @param output Buffer for output SHA digest. Output is 20 bytes for
* sha_type SHA1, 32 bytes for sha_type SHA2_256, 48 bytes for
* sha_type SHA2_384, 64 bytes for sha_type SHA2_512.
*/
void esp_sha(esp_sha_type sha_type, const unsigned char *input, size_t ilen, unsigned char *output);
/* @brief Begin to execute a single SHA block operation
*
* @note This is a piece of a SHA algorithm, rather than an entire SHA
* algorithm.
*
* @note Call esp_sha_try_lock_engine() before calling this
* function. Do not call esp_sha_lock_memory_block() beforehand, this
* is done inside the function.
*
* @param sha_type SHA algorithm to use.
*
* @param data_block Pointer to block of data. Block size is
* determined by algorithm (SHA1/SHA2_256 = 64 bytes,
* SHA2_384/SHA2_512 = 128 bytes)
*
* @param is_first_block If this parameter is true, the SHA state will
* be initialised (with the initial state of the given SHA algorithm)
* before the block is calculated. If false, the existing state of the
* SHA engine will be used.
*
* @return As a performance optimisation, this function returns before
* the SHA block operation is complete. Both this function and
* esp_sha_read_state() will automatically wait for any previous
* operation to complete before they begin. If using the SHA registers
* directly in another way, call esp_sha_wait_idle() after calling this
* function but before accessing the SHA registers.
*/
void esp_sha_block(esp_sha_type sha_type, const void *data_block, bool is_first_block);
/** @brief Read out the current state of the SHA digest loaded in the engine.
*
* @note This is a piece of a SHA algorithm, rather than an entire SHA algorithm.
*
* @note Call esp_sha_try_lock_engine() before calling this
* function. Do not call esp_sha_lock_memory_block() beforehand, this
* is done inside the function.
*
* If the SHA suffix padding block has been executed already, the
* value that is read is the SHA digest (in big endian
* format). Otherwise, the value that is read is an interim SHA state.
*
* @note If sha_type is SHA2_384, only 48 bytes of state will be read.
* This is enough for the final SHA2_384 digest, but if you want the
* interim SHA-384 state (to continue digesting) then pass SHA2_512 instead.
*
* @param sha_type SHA algorithm in use.
*
* @param state Pointer to a memory buffer to hold the SHA state. Size
* is 20 bytes (SHA1), 32 bytes (SHA2_256), 48 bytes (SHA2_384) or 64 bytes (SHA2_512).
*
*/
void esp_sha_read_digest_state(esp_sha_type sha_type, void *digest_state);
/**
* @brief Obtain exclusive access to a particular SHA engine
*
* @param sha_type Type of SHA engine to use.
*
* Blocks until engine is available. Note: Can block indefinitely
* while a TLS connection is open, suggest using
* esp_sha_try_lock_engine() and failing over to software SHA.
*/
void esp_sha_lock_engine(esp_sha_type sha_type);
/**
* @brief Try and obtain exclusive access to a particular SHA engine
*
* @param sha_type Type of SHA engine to use.
*
* @return Returns true if the SHA engine is locked for exclusive
* use. Call esp_sha_unlock_sha_engine() when done. Returns false if
* the SHA engine is already in use, caller should use software SHA
* algorithm for this digest.
*/
bool esp_sha_try_lock_engine(esp_sha_type sha_type);
/**
* @brief Unlock an engine previously locked with esp_sha_lock_engine() or esp_sha_try_lock_engine()
*
* @param sha_type Type of engine to release.
*/
void esp_sha_unlock_engine(esp_sha_type sha_type);
/**
* @brief Acquire exclusive access to the SHA shared memory block at SHA_TEXT_BASE
*
* This memory block is shared across all the SHA algorithm types.
*
* Caller should have already locked a SHA engine before calling this function.
*
* Note that it is possible to obtain exclusive access to the memory block even
* while it is in use by the SHA engine. Caller should use esp_sha_wait_idle()
* to ensure the SHA engine is not reading from the memory block in hardware.
*
* @note This function enters a critical section. Do not block while holding this lock.
*
* @note You do not need to lock the memory block before calling esp_sha_block() or esp_sha_read_digest_state(), these functions handle memory block locking internally.
*
* Call esp_sha_unlock_memory_block() when done.
*/
void esp_sha_lock_memory_block(void);
/**
* @brief Release exclusive access to the SHA register memory block at SHA_TEXT_BASE
*
* Caller should have already locked a SHA engine before calling this function.
*
* This function releases the critical section entered by esp_sha_lock_memory_block().
*
* Call following esp_sha_lock_memory_block().
*/
void esp_sha_unlock_memory_block(void);
/** @brief Wait for the SHA engine to finish any current operation
*
* @note This function does not ensure exclusive access to any SHA
* engine. Caller should use esp_sha_try_lock_engine() and
* esp_sha_lock_memory_block() as required.
*
* @note Functions declared in this header file wait for SHA engine
* completion automatically, so you don't need to use this API for
* these. However if accessing SHA registers directly, you will need
* to call this before accessing SHA registers if using the
* esp_sha_block() function.
*
* @note This function busy-waits, so wastes CPU resources.
* Best to delay calling until you are about to need it.
*
*/
void esp_sha_wait_idle(void);
#ifdef __cplusplus
}
#endif
#endif
#include "sha/sha_parallel_engine.h"
#warning esp32/sha.h is deprecated, please use sha_parallel_engine.h instead

Wyświetl plik

@ -12,157 +12,10 @@
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef _ESP_SHA_H_
#define _ESP_SHA_H_
#pragma once
#include "esp32s2/rom/sha.h"
#include "sha/sha_dma.h"
/** @brief Low-level support functions for the hardware SHA engine using DMA
*
* @note If you're looking for a SHA API to use, try mbedtls component
* mbedtls/shaXX.h. That API supports hardware acceleration.
*
* The API in this header provides some building blocks for implementing a
* full SHA API such as the one in mbedtls, and also a basic SHA function esp_sha().
*
* Some technical details about the hardware SHA engine:
*
* - The crypto DMA is shared between the SHA and AES engine, it is not
* possible for them to run calcalutions in parallel.
*
*/
#ifdef __cplusplus
extern "C" {
#endif
/* Defined in rom/sha.h */
typedef SHA_TYPE esp_sha_type;
/** @brief Calculate SHA1 or SHA2 sum of some data, using hardware SHA engine
*
* @note For more versatile SHA calculations, where data doesn't need
* to be passed all at once, try the mbedTLS mbedtls/shaX.h APIs.
*
* @note It is not necessary to lock any SHA hardware before calling
* this function, thread safety is managed internally.
*
* @param sha_type SHA algorithm to use.
*
* @param input Input data buffer.
*
* @param ilen Length of input data in bytes.
*
* @param output Buffer for output SHA digest. Output is 20 bytes for
* sha_type SHA1, 32 bytes for sha_type SHA2_256, 48 bytes for
* sha_type SHA2_384, 64 bytes for sha_type SHA2_512.
*/
void esp_sha(esp_sha_type sha_type, const unsigned char *input, size_t ilen, unsigned char *output);
/** @brief Execute SHA block operation using DMA
*
* @note This is a piece of a SHA algorithm, rather than an entire SHA
* algorithm.
*
* @note Call esp_sha_aquire_hardware() before calling this
* function.
*
* @param sha_type SHA algorithm to use.
*
* @param input Pointer to the input data. Block size is
* determined by algorithm (SHA1/SHA2_256 = 64 bytes,
* SHA2_384/SHA2_512 = 128 bytes)
*
* @param ilen length of input data should be multiple of block length.
*
* @param buf Pointer to blocks of data that will be prepended
* to data_block before hashing. Useful when there is two sources of
* data that need to be efficiently calculated in a single SHA DMA
* operation.
*
* @param buf_len length of buf data should be multiple of block length.
* Should not be longer than the maximum amount of bytes in a single block
* (128 bytes)
*
* @param is_first_block If this parameter is true, the SHA state will
* be initialised (with the initial state of the given SHA algorithm)
* before the block is calculated. If false, the existing state of the
* SHA engine will be used.
*
* @param t The number of bits for the SHA512/t hash function, with
* output truncated to t bits. Used for calculating the inital hash.
* t is any positive integer between 1 and 512, except 384.
*
* @return 0 if successful
*/
int esp_sha_dma(esp_sha_type sha_type, const void *input, uint32_t ilen,
const void *buf, uint32_t buf_len, bool is_first_block);
/**
* @brief Read out the current state of the SHA digest
*
* @note This is a piece of a SHA algorithm, rather than an entire SHA algorithm.
*
* @note Call esp_sha_aquire_hardware() before calling this
* function.
*
* If the SHA suffix padding block has been executed already, the
* value that is read is the SHA digest.
* Otherwise, the value that is read is an interim SHA state.
*
* @param sha_type SHA algorithm in use.
* @param digest_state Pointer to a memory buffer to hold the SHA state. Size
* is 20 bytes (SHA1), 32 bytes (SHA2_256), or 64 bytes (SHA2_384, SHA2_512).
*/
void esp_sha_read_digest_state(esp_sha_type sha_type, void *digest_state);
/**
* @brief Set the current state of the SHA digest
*
* @note Call esp_sha_aquire_hardware() before calling this
* function.
*
* When resuming a
*
* @param sha_type SHA algorithm in use.
* @param digest_state
*/
void esp_sha_write_digest_state(esp_sha_type sha_type, void *digest_state);
#warning esp32s2/sha.h is deprecated, please use sha/sha_dma.h instead
/**
* @brief Enables the SHA and crypto DMA peripheral and takes the
* locks for both of them.
*/
void esp_sha_acquire_hardware(void);
/**
* @brief Disables the SHA and crypto DMA peripheral and releases the
* locks.
*/
void esp_sha_release_hardware(void);
/*
*/
/**
* @brief Sets the initial hash value for SHA512/t.
*
* @note Is generated according to the algorithm described in the TRM,
* chapter SHA-Accelerator
*
* @note The engine must be locked until the value is used for an operation
* or read out. Else you risk another operation overwriting it.
*
* @param t
*
* @return 0 if successful
*/
int esp_sha_512_t_init_hash(uint16_t t);
#ifdef __cplusplus
}
#endif
#endif

Wyświetl plik

@ -3,7 +3,7 @@
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
@ -12,10 +12,9 @@
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef _ESP_SHA_H_
#define _ESP_SHA_H_
#pragma once
#include "esp32s3/rom/sha.h"
#include "hal/sha_types.h"
/** @brief Low-level support functions for the hardware SHA engine using DMA
*
@ -36,8 +35,6 @@
extern "C" {
#endif
/* Defined in rom/sha.h */
typedef SHA_TYPE esp_sha_type;
/** @brief Calculate SHA1 or SHA2 sum of some data, using hardware SHA engine
*
@ -161,5 +158,4 @@ int esp_sha_512_t_init_hash(uint16_t t);
}
#endif
#endif

Wyświetl plik

@ -0,0 +1,207 @@
// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once
#include "hal/sha_types.h"
#include "esp_types.h"
/** @brief Low-level support functions for the hardware SHA engine
*
* @note If you're looking for a SHA API to use, try mbedtls component
* mbedtls/shaXX.h. That API supports hardware acceleration.
*
* The API in this header provides some building blocks for implementing a
* full SHA API such as the one in mbedtls, and also a basic SHA function esp_sha().
*
* Some technical details about the hardware SHA engine:
*
* - SHA accelerator engine calculates one digest at a time, per SHA
* algorithm type. It initialises and maintains the digest state
* internally. It is possible to read out an in-progress SHA digest
* state, but it is not possible to restore a SHA digest state
* into the engine.
*
* - The memory block SHA_TEXT_BASE is shared between all SHA digest
* engines, so all engines must be idle before this memory block is
* modified.
*
*/
#ifdef __cplusplus
extern "C" {
#endif
/** @brief Calculate SHA1 or SHA2 sum of some data, using hardware SHA engine
*
* @note For more versatile SHA calculations, where data doesn't need
* to be passed all at once, try the mbedTLS mbedtls/shaX.h APIs. The
* hardware-accelerated mbedTLS implementation is also faster when
* hashing large amounts of data.
*
* @note It is not necessary to lock any SHA hardware before calling
* this function, thread safety is managed internally.
*
* @note If a TLS connection is open then this function may block
* indefinitely waiting for a SHA engine to become available. Use the
* mbedTLS SHA API to avoid this problem.
*
* @param sha_type SHA algorithm to use.
*
* @param input Input data buffer.
*
* @param ilen Length of input data in bytes.
*
* @param output Buffer for output SHA digest. Output is 20 bytes for
* sha_type SHA1, 32 bytes for sha_type SHA2_256, 48 bytes for
* sha_type SHA2_384, 64 bytes for sha_type SHA2_512.
*/
void esp_sha(esp_sha_type sha_type, const unsigned char *input, size_t ilen, unsigned char *output);
/* @brief Begin to execute a single SHA block operation
*
* @note This is a piece of a SHA algorithm, rather than an entire SHA
* algorithm.
*
* @note Call esp_sha_try_lock_engine() before calling this
* function. Do not call esp_sha_lock_memory_block() beforehand, this
* is done inside the function.
*
* @param sha_type SHA algorithm to use.
*
* @param data_block Pointer to block of data. Block size is
* determined by algorithm (SHA1/SHA2_256 = 64 bytes,
* SHA2_384/SHA2_512 = 128 bytes)
*
* @param is_first_block If this parameter is true, the SHA state will
* be initialised (with the initial state of the given SHA algorithm)
* before the block is calculated. If false, the existing state of the
* SHA engine will be used.
*
* @return As a performance optimisation, this function returns before
* the SHA block operation is complete. Both this function and
* esp_sha_read_state() will automatically wait for any previous
* operation to complete before they begin. If using the SHA registers
* directly in another way, call esp_sha_wait_idle() after calling this
* function but before accessing the SHA registers.
*/
void esp_sha_block(esp_sha_type sha_type, const void *data_block, bool is_first_block);
/** @brief Read out the current state of the SHA digest loaded in the engine.
*
* @note This is a piece of a SHA algorithm, rather than an entire SHA algorithm.
*
* @note Call esp_sha_try_lock_engine() before calling this
* function. Do not call esp_sha_lock_memory_block() beforehand, this
* is done inside the function.
*
* If the SHA suffix padding block has been executed already, the
* value that is read is the SHA digest (in big endian
* format). Otherwise, the value that is read is an interim SHA state.
*
* @note If sha_type is SHA2_384, only 48 bytes of state will be read.
* This is enough for the final SHA2_384 digest, but if you want the
* interim SHA-384 state (to continue digesting) then pass SHA2_512 instead.
*
* @param sha_type SHA algorithm in use.
*
* @param state Pointer to a memory buffer to hold the SHA state. Size
* is 20 bytes (SHA1), 32 bytes (SHA2_256), 48 bytes (SHA2_384) or 64 bytes (SHA2_512).
*
*/
void esp_sha_read_digest_state(esp_sha_type sha_type, void *digest_state);
/**
* @brief Obtain exclusive access to a particular SHA engine
*
* @param sha_type Type of SHA engine to use.
*
* Blocks until engine is available. Note: Can block indefinitely
* while a TLS connection is open, suggest using
* esp_sha_try_lock_engine() and failing over to software SHA.
*/
void esp_sha_lock_engine(esp_sha_type sha_type);
/**
* @brief Try and obtain exclusive access to a particular SHA engine
*
* @param sha_type Type of SHA engine to use.
*
* @return Returns true if the SHA engine is locked for exclusive
* use. Call esp_sha_unlock_sha_engine() when done. Returns false if
* the SHA engine is already in use, caller should use software SHA
* algorithm for this digest.
*/
bool esp_sha_try_lock_engine(esp_sha_type sha_type);
/**
* @brief Unlock an engine previously locked with esp_sha_lock_engine() or esp_sha_try_lock_engine()
*
* @param sha_type Type of engine to release.
*/
void esp_sha_unlock_engine(esp_sha_type sha_type);
/**
* @brief Acquire exclusive access to the SHA shared memory block at SHA_TEXT_BASE
*
* This memory block is shared across all the SHA algorithm types.
*
* Caller should have already locked a SHA engine before calling this function.
*
* Note that it is possible to obtain exclusive access to the memory block even
* while it is in use by the SHA engine. Caller should use esp_sha_wait_idle()
* to ensure the SHA engine is not reading from the memory block in hardware.
*
* @note This function enters a critical section. Do not block while holding this lock.
*
* @note You do not need to lock the memory block before calling esp_sha_block() or esp_sha_read_digest_state(), these functions handle memory block locking internally.
*
* Call esp_sha_unlock_memory_block() when done.
*/
void esp_sha_lock_memory_block(void);
/**
* @brief Release exclusive access to the SHA register memory block at SHA_TEXT_BASE
*
* Caller should have already locked a SHA engine before calling this function.
*
* This function releases the critical section entered by esp_sha_lock_memory_block().
*
* Call following esp_sha_lock_memory_block().
*/
void esp_sha_unlock_memory_block(void);
/** @brief Wait for the SHA engine to finish any current operation
*
* @note This function does not ensure exclusive access to any SHA
* engine. Caller should use esp_sha_try_lock_engine() and
* esp_sha_lock_memory_block() as required.
*
* @note Functions declared in this header file wait for SHA engine
* completion automatically, so you don't need to use this API for
* these. However if accessing SHA registers directly, you will need
* to call this before accessing SHA registers if using the
* esp_sha_block() function.
*
* @note This function busy-waits, so wastes CPU resources.
* Best to delay calling until you are about to need it.
*
*/
void esp_sha_wait_idle(void);
#ifdef __cplusplus
}
#endif

Wyświetl plik

@ -23,57 +23,16 @@
#ifndef _SHA1_ALT_H_
#define _SHA1_ALT_H_
#if defined(MBEDTLS_SHA1_ALT)
#include "hal/sha_types.h"
#include "soc/sha_caps.h"
#ifdef __cplusplus
extern "C" {
#endif
#if defined(MBEDTLS_SHA1_ALT)
#if CONFIG_IDF_TARGET_ESP32S3
#include "esp32s3/sha.h"
typedef enum {
ESP_SHA1_STATE_INIT,
ESP_SHA1_STATE_IN_PROCESS
} esp_sha1_state;
/**
* \brief SHA-1 context structure
*/
typedef struct {
uint32_t total[2]; /*!< number of bytes processed */
uint32_t state[5]; /*!< intermediate digest state */
unsigned char buffer[64]; /*!< data block being processed */
int first_block; /*!< if first then true else false */
esp_sha_type mode;
esp_sha1_state sha_state;
} mbedtls_sha1_context;
#endif //CONFIG_IDF_TARGET_ESP32S3
#if CONFIG_IDF_TARGET_ESP32S2
#include "esp32s2/sha.h"
typedef enum {
ESP_SHA1_STATE_INIT,
ESP_SHA1_STATE_IN_PROCESS
} esp_sha1_state;
/**
* \brief SHA-1 context structure
*/
typedef struct {
uint32_t total[2]; /*!< number of bytes processed */
uint32_t state[5]; /*!< intermediate digest state */
unsigned char buffer[64]; /*!< data block being processed */
int first_block; /*!< if first then true else false */
esp_sha_type mode;
esp_sha1_state sha_state;
} mbedtls_sha1_context;
#endif //CONFIG_IDF_TARGET_ESP32S2
#if CONFIG_IDF_TARGET_ESP32
#if SOC_SHA_SUPPORT_PARALLEL_ENG
typedef enum {
ESP_MBEDTLS_SHA1_UNUSED, /* first block hasn't been processed yet */
@ -89,10 +48,28 @@ typedef struct {
uint32_t state[5]; /*!< intermediate digest state */
unsigned char buffer[64]; /*!< data block being processed */
esp_mbedtls_sha1_mode mode;
}
mbedtls_sha1_context;
} mbedtls_sha1_context;
#endif //CONFIG_IDF_TARGET_ESP32
#elif SOC_SHA_SUPPORT_DMA
typedef enum {
ESP_SHA1_STATE_INIT,
ESP_SHA1_STATE_IN_PROCESS
} esp_sha1_state;
/**
* \brief SHA-1 context structure
*/
typedef struct {
uint32_t total[2]; /*!< number of bytes processed */
uint32_t state[5]; /*!< intermediate digest state */
unsigned char buffer[64]; /*!< data block being processed */
int first_block; /*!< if first then true else false */
esp_sha_type mode;
esp_sha1_state sha_state;
} mbedtls_sha1_context;
#endif
#endif

Wyświetl plik

@ -23,62 +23,16 @@
#ifndef _SHA256_ALT_H_
#define _SHA256_ALT_H_
#if defined(MBEDTLS_SHA256_ALT)
#include "hal/sha_types.h"
#include "soc/sha_caps.h"
#ifdef __cplusplus
extern "C" {
#endif
#if defined(MBEDTLS_SHA256_ALT)
#if CONFIG_IDF_TARGET_ESP32S3
#include "esp32s3/sha.h"
typedef enum {
ESP_SHA256_STATE_INIT,
ESP_SHA256_STATE_IN_PROCESS
} esp_sha256_state;
/**
* \brief SHA-256 context structure
*/
typedef struct {
uint32_t total[2]; /*!< number of bytes processed */
uint32_t state[8]; /*!< intermediate digest state */
unsigned char buffer[64]; /*!< data block being processed */
int first_block; /*!< if first then true, else false */
esp_sha_type mode;
esp_sha256_state sha_state;
}
mbedtls_sha256_context;
#endif //CONFIG_IDF_TARGET_ESP32S3
#if CONFIG_IDF_TARGET_ESP32S2
#include "esp32s2/sha.h"
typedef enum {
ESP_SHA256_STATE_INIT,
ESP_SHA256_STATE_IN_PROCESS
} esp_sha256_state;
/**
* \brief SHA-256 context structure
*/
typedef struct {
uint32_t total[2]; /*!< number of bytes processed */
uint32_t state[8]; /*!< intermediate digest state */
unsigned char buffer[64]; /*!< data block being processed */
int first_block; /*!< if first then true, else false */
esp_sha_type mode;
esp_sha256_state sha_state;
}
mbedtls_sha256_context;
#endif //CONFIG_IDF_TARGET_ESP32S2
#if CONFIG_IDF_TARGET_ESP32
#if SOC_SHA_SUPPORT_PARALLEL_ENG
typedef enum {
ESP_MBEDTLS_SHA256_UNUSED, /* first block hasn't been processed yet */
ESP_MBEDTLS_SHA256_HARDWARE, /* using hardware SHA engine */
@ -94,10 +48,27 @@ typedef struct {
unsigned char buffer[64]; /*!< data block being processed */
int is224; /*!< 0 => SHA-256, else SHA-224 */
esp_mbedtls_sha256_mode mode;
}
mbedtls_sha256_context;
} mbedtls_sha256_context;
#endif //CONFIG_IDF_TARGET_ESP32
#elif SOC_SHA_SUPPORT_DMA
typedef enum {
ESP_SHA256_STATE_INIT,
ESP_SHA256_STATE_IN_PROCESS
} esp_sha256_state;
/**
* \brief SHA-256 context structure
*/
typedef struct {
uint32_t total[2]; /*!< number of bytes processed */
uint32_t state[8]; /*!< intermediate digest state */
unsigned char buffer[64]; /*!< data block being processed */
int first_block; /*!< if first then true, else false */
esp_sha_type mode;
esp_sha256_state sha_state;
} mbedtls_sha256_context;
#endif
#endif

Wyświetl plik

@ -23,86 +23,17 @@
#ifndef _SHA512_ALT_H_
#define _SHA512_ALT_H_
#if defined(MBEDTLS_SHA512_ALT)
#include "hal/sha_types.h"
#include "soc/sha_caps.h"
#ifdef __cplusplus
extern "C" {
#endif
#if defined(MBEDTLS_SHA512_ALT)
#if CONFIG_IDF_TARGET_ESP32S3
#include "esp32s3/sha.h"
typedef enum {
ESP_SHA512_STATE_INIT,
ESP_SHA512_STATE_IN_PROCESS
} esp_sha512_state;
/**
* \brief SHA-512 context structure
*/
typedef struct {
uint64_t total[2]; /*!< number of bytes processed */
uint64_t state[8]; /*!< intermediate digest state */
unsigned char buffer[128]; /*!< data block being processed */
int first_block;
esp_sha_type mode;
uint32_t t_val; /*!< t_val for 512/t mode */
esp_sha512_state sha_state;
} mbedtls_sha512_context;
/**
* @brief Sets the specfic algorithm for SHA512
*
* @param ctx The mbedtls sha512 context
*
* @param type The mode, used for setting SHA2_512224 and SHA2_512256:
*
*/
void esp_sha512_set_mode(mbedtls_sha512_context *ctx, esp_sha_type type);
/* For SHA512/t mode the intial hash value will depend on t */
void esp_sha512_set_t( mbedtls_sha512_context *ctx, uint16_t t_val);
#endif //CONFIG_IDF_TARGET_ESP32S3
#if CONFIG_IDF_TARGET_ESP32S2
#include "esp32s2/sha.h"
typedef enum {
ESP_SHA512_STATE_INIT,
ESP_SHA512_STATE_IN_PROCESS
} esp_sha512_state;
/**
* \brief SHA-512 context structure
*/
typedef struct {
uint64_t total[2]; /*!< number of bytes processed */
uint64_t state[8]; /*!< intermediate digest state */
unsigned char buffer[128]; /*!< data block being processed */
int first_block;
esp_sha_type mode;
uint32_t t_val; /*!< t_val for 512/t mode */
esp_sha512_state sha_state;
} mbedtls_sha512_context;
/**
* @brief Sets the specfic algorithm for SHA512
*
* @param ctx The mbedtls sha512 context
*
* @param type The mode, used for setting SHA2_512224 and SHA2_512256:
*
*/
void esp_sha512_set_mode(mbedtls_sha512_context *ctx, esp_sha_type type);
/* For SHA512/t mode the intial hash value will depend on t */
void esp_sha512_set_t( mbedtls_sha512_context *ctx, uint16_t t_val);
#endif //CONFIG_IDF_TARGET_ESP32S2
#if CONFIG_IDF_TARGET_ESP32
#if SOC_SHA_SUPPORT_PARALLEL_ENG
typedef enum {
ESP_MBEDTLS_SHA512_UNUSED, /* first block hasn't been processed yet */
@ -119,10 +50,43 @@ typedef struct {
unsigned char buffer[128]; /*!< data block being processed */
int is384; /*!< 0 => SHA-512, else SHA-384 */
esp_mbedtls_sha512_mode mode;
}
mbedtls_sha512_context;
} mbedtls_sha512_context;
#endif //CONFIG_IDF_TARGET_ESP32
#elif SOC_SHA_SUPPORT_DMA
typedef enum {
ESP_SHA512_STATE_INIT,
ESP_SHA512_STATE_IN_PROCESS
} esp_sha512_state;
/**
* \brief SHA-512 context structure
*/
typedef struct {
uint64_t total[2]; /*!< number of bytes processed */
uint64_t state[8]; /*!< intermediate digest state */
unsigned char buffer[128]; /*!< data block being processed */
int first_block;
esp_sha_type mode;
uint32_t t_val; /*!< t_val for 512/t mode */
esp_sha512_state sha_state;
} mbedtls_sha512_context;
/**
* @brief Sets the specfic algorithm for SHA512
*
* @param ctx The mbedtls sha512 context
*
* @param type The mode, used for setting SHA2_512224 and SHA2_512256:
*
*/
void esp_sha512_set_mode(mbedtls_sha512_context *ctx, esp_sha_type type);
/* For SHA512/t mode the intial hash value will depend on t */
void esp_sha512_set_t( mbedtls_sha512_context *ctx, uint16_t t_val);
#endif
#endif

Wyświetl plik

@ -1,7 +1,5 @@
/*
* SHA-1 implementation with hardware ESP32 support added.
* Uses mbedTLS software implementation for failover when concurrent
* SHA operations are in use.
* SHA-1 implementation with hardware ESP support added.
*
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
* Additions Copyright (C) 2016-2020, Espressif Systems (Shanghai) PTE LTD
@ -47,12 +45,15 @@
#endif /* MBEDTLS_PLATFORM_C */
#endif /* MBEDTLS_SELF_TEST */
#include "esp32s3/sha.h"
#include "sha/sha_dma.h"
/* Implementation that should never be optimized out by the compiler */
static void mbedtls_zeroize( void *v, size_t n )
{
volatile unsigned char *p = (unsigned char *)v; while ( n-- ) *p++ = 0;
volatile unsigned char *p = (unsigned char *)v;
while ( n-- ) {
*p++ = 0;
}
}
/*
@ -167,9 +168,9 @@ int mbedtls_sha1_update_ret( mbedtls_sha1_context *ctx, const unsigned char *inp
if ( len || local_len) {
esp_sha_acquire_hardware();
if (ctx->sha_state == ESP_SHA1_STATE_INIT) {
ctx->first_block = true;
ctx->sha_state = ESP_SHA1_STATE_IN_PROCESS;
} else if (ctx->sha_state == ESP_SHA1_STATE_IN_PROCESS) {
ctx->first_block = false;

Wyświetl plik

@ -1,7 +1,5 @@
/*
* SHA-256 implementation with hardware ESP32 support added.
* Uses mbedTLS software implementation for failover when concurrent
* SHA operations are in use.
* SHA-256 implementation with hardware ESP support added.
*
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
* Additions Copyright (C) 2016-2020, Espressif Systems (Shanghai) PTE LTD
@ -48,12 +46,15 @@
#endif /* MBEDTLS_PLATFORM_C */
#endif /* MBEDTLS_SELF_TEST */
#include "esp32s3/sha.h"
#include "sha/sha_dma.h"
/* Implementation that should never be optimized out by the compiler */
static void mbedtls_zeroize( void *v, size_t n )
{
volatile unsigned char *p = v; while ( n-- ) *p++ = 0;
volatile unsigned char *p = v;
while ( n-- ) {
*p++ = 0;
}
}
/*

Wyświetl plik

@ -1,7 +1,5 @@
/*
* SHA-512 implementation with hardware ESP32 support added.
* Uses mbedTLS software implementation for failover when concurrent
* SHA operations are in use.
* SHA-512 implementation with hardware ESP support added.
*
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
* Additions Copyright (C) 2016-2020, Espressif Systems (Shanghai) PTE LTD
@ -54,12 +52,15 @@
#endif /* MBEDTLS_PLATFORM_C */
#endif /* MBEDTLS_SELF_TEST */
#include "esp32s2/sha.h"
#include "sha/sha_dma.h"
/* Implementation that should never be optimized out by the compiler */
static void mbedtls_zeroize( void *v, size_t n )
{
volatile unsigned char *p = v; while ( n-- ) *p++ = 0;
volatile unsigned char *p = v;
while ( n-- ) {
*p++ = 0;
}
}
/*

Wyświetl plik

@ -1,5 +1,5 @@
/*
* ESP32 hardware accelerated SHA1/256/512 implementation
* ESP hardware accelerated SHA1/256/512 implementation
* based on mbedTLS FIPS-197 compliant version.
*
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
@ -31,11 +31,8 @@
#include "esp_log.h"
#include "esp_crypto_lock.h"
#include "esp32s2/rom/cache.h"
#include "esp32s2/rom/lldesc.h"
#include "soc/crypto_dma_reg.h"
#include "soc/lldesc.h"
#include "soc/dport_reg.h"
#include "soc/hwcrypto_reg.h"
#include "soc/cache_memory.h"
#include "soc/periph_defs.h"
@ -45,19 +42,39 @@
#include "driver/periph_ctrl.h"
#include "sys/param.h"
#include "esp32s2/sha.h"
#include "sha/sha_dma.h"
#include "hal/sha_hal.h"
#include "soc/sha_caps.h"
/* Max amount of bytes in a single DMA operation is 4095,
for SHA this means that the biggest safe amount of bytes is
31 blocks of 128 bytes = 3968
*/
#define SHA_DMA_MAX_BYTES 3968
#if CONFIG_IDF_TARGET_ESP32S2
#include "esp32s2/rom/cache.h"
#elif CONFIG_IDF_TARGET_ESP32S3
#include "esp32s3/rom/cache.h"
#endif
/* The longest length of a single block is for SHA512 = 128 byte */
#define SHA_MAX_BLK_LEN 128
#if SOC_SHA_GENERAL_DMA
#define SHA_LOCK() esp_crypto_sha_lock_acquire()
#define SHA_RELEASE() esp_crypto_sha_lock_release()
#elif SOC_SHA_CRYPTO_DMA
#define SHA_LOCK() esp_crypto_dma_lock_acquire()
#define SHA_RELEASE() esp_crypto_dma_lock_release()
#else
#define SHA_LOCK() ()
#endif
const static char *TAG = "esp-sha";
void esp_sha_write_digest_state(esp_sha_type sha_type, void *digest_state)
{
sha_hal_write_digest(sha_type, digest_state);
}
void esp_sha_read_digest_state(esp_sha_type sha_type, void *digest_state)
{
sha_hal_read_digest(sha_type, digest_state);
}
/* Return block size (in bytes) for a given SHA type */
inline static size_t block_length(esp_sha_type type)
{
@ -77,83 +94,36 @@ inline static size_t block_length(esp_sha_type type)
}
}
/* Return state size (in bytes) for a given SHA type */
inline static size_t state_length(esp_sha_type type)
{
switch (type) {
case SHA1:
return 160 / 8;
case SHA2_224:
case SHA2_256:
return 256 / 8;
case SHA2_384:
case SHA2_512:
case SHA2_512224:
case SHA2_512256:
case SHA2_512T:
return 512 / 8;
default:
return 0;
}
}
/* Enable SHA peripheral and then lock it */
void esp_sha_acquire_hardware()
{
esp_crypto_dma_lock_acquire();
SHA_LOCK(); /* Released when releasing hw with esp_sha_release_hardware() */
/* Enable SHA and DMA hardware */
#if SOC_SHA_CRYPTO_DMA
periph_module_enable(PERIPH_SHA_DMA_MODULE);
/* DMA for SHA */
REG_WRITE(CRYPTO_DMA_AES_SHA_SELECT_REG, 1);
#elif SOC_SHA_GENERAL_DMA
periph_module_enable(PERIPH_SHA_MODULE);
periph_module_enable(PERIPH_GDMA_MODULE);
#endif
}
/* Disable SHA peripheral block and then release it */
void esp_sha_release_hardware()
{
/* Disable SHA and DMA hardware */
#if SOC_SHA_CRYPTO_DMA
periph_module_disable(PERIPH_SHA_DMA_MODULE);
#elif SOC_SHA_GENERAL_DMA
periph_module_disable(PERIPH_SHA_MODULE);
periph_module_disable(PERIPH_GDMA_MODULE);
#endif
esp_crypto_dma_lock_release();
}
/* Busy wait until SHA is idle */
static void esp_sha_wait_idle(void)
{
while (DPORT_REG_READ(SHA_BUSY_REG) != 0) {
}
}
void esp_sha_write_digest_state(esp_sha_type sha_type, void *digest_state)
{
uint32_t *digest_state_words = (uint32_t *)digest_state;
uint32_t *reg_addr_buf = (uint32_t *)(SHA_H_BASE);
for (int i = 0; i < state_length(sha_type) / 4; i++) {
REG_WRITE(&reg_addr_buf[i], digest_state_words[i]);
}
}
/* Read the SHA digest from hardware */
void esp_sha_read_digest_state(esp_sha_type sha_type, void *digest_state)
{
uint32_t *digest_state_words = (uint32_t *)digest_state;
int word_len = state_length(sha_type) / 4;
esp_dport_access_read_buffer(digest_state_words, SHA_H_BASE, word_len);
/* Fault injection check: verify SHA engine actually ran,
state is not all zeroes.
*/
for (int i = 0; i < word_len; i++) {
if (digest_state_words[i] != 0) {
return;
}
}
abort(); // SHA peripheral returned all zero state, probably due to fault injection
SHA_RELEASE();
}
#if SOC_SHA_SUPPORT_SHA512_T
/* The initial hash value for SHA512/t is generated according to the
algorithm described in the TRM, chapter SHA-Accelerator
*/
@ -188,72 +158,41 @@ int esp_sha_512_t_init_hash(uint16_t t)
return -1;
}
REG_WRITE(SHA_T_LENGTH_REG, t_len);
REG_WRITE(SHA_T_STRING_REG, t_string);
REG_WRITE(SHA_MODE_REG, SHA2_512T);
REG_WRITE(SHA_START_REG, 1);
esp_sha_wait_idle();
sha_hal_sha512_init_hash(t_string, t_len);
return 0;
}
static void esp_sha_fill_text_block(esp_sha_type sha_type, const void *input)
{
uint32_t *reg_addr_buf = (uint32_t *)(SHA_TEXT_BASE);
uint32_t *data_words = NULL;
#endif //SOC_SHA_SUPPORT_SHA512_T
/* Fill the data block */
data_words = (uint32_t *)(input);
for (int i = 0; i < block_length(sha_type) / 4; i++) {
reg_addr_buf[i] = (data_words[i]);
}
asm volatile ("memw");
}
/* Hash a single SHA block */
static void esp_sha_block(esp_sha_type sha_type, const void *input, bool is_first_block)
{
esp_sha_fill_text_block(sha_type, input);
esp_sha_wait_idle();
/* Start hashing */
if (is_first_block) {
REG_WRITE(SHA_START_REG, 1);
} else {
REG_WRITE(SHA_CONTINUE_REG, 1);
}
}
/* Hash the input block by block, using non-DMA mode */
static void esp_sha_block_mode(esp_sha_type sha_type, const uint8_t *input, uint32_t ilen,
const uint8_t *buf, uint32_t buf_len, bool is_first_block)
const uint8_t *buf, uint32_t buf_len, bool is_first_block)
{
size_t blk_len = 0;
size_t blk_word_len = 0;
int num_block = 0;
blk_len = block_length(sha_type);
REG_WRITE(SHA_MODE_REG, sha_type);
blk_word_len = blk_len / 4;
num_block = ilen / blk_len;
if (buf_len != 0) {
esp_sha_block(sha_type, buf, is_first_block);
sha_hal_hash_block(sha_type, buf, blk_word_len, is_first_block);
is_first_block = false;
}
for (int i = 0; i < num_block; i++) {
esp_sha_block(sha_type, input + blk_len*i, is_first_block);
sha_hal_hash_block(sha_type, input + blk_len * i, blk_word_len, is_first_block);
is_first_block = false;
}
esp_sha_wait_idle();
}
static int esp_sha_dma_process(esp_sha_type sha_type, const void *input, uint32_t ilen,
const void *buf, uint32_t buf_len, bool is_first_block);
const void *buf, uint32_t buf_len, bool is_first_block);
/* Performs SHA on multiple blocks at a time using DMA
splits up into smaller operations for inputs that exceed a single DMA list
@ -263,20 +202,20 @@ int esp_sha_dma(esp_sha_type sha_type, const void *input, uint32_t ilen,
{
int ret = 0;
unsigned char *dma_cap_buf = NULL;
int dma_op_num = ( ilen / (SHA_DMA_MAX_BYTES + 1) ) + 1;
int dma_op_num = ( ilen / (SOC_SHA_DMA_MAX_BUFFER_SIZE + 1) ) + 1;
if (buf_len > block_length(sha_type)) {
ESP_LOGE(TAG, "SHA DMA buf_len cannot exceed max size for a single block");
return -1;
}
/* DMA cannot access memory in the iCache range, hash block by block instead of using DMA */
/* DMA cannot access memory in flash, hash block by block instead of using DMA */
if (!esp_ptr_dma_ext_capable(input) && !esp_ptr_dma_capable(input) && (ilen != 0)) {
esp_sha_block_mode(sha_type, input, ilen, buf, buf_len, is_first_block);
return 0;
}
#if (CONFIG_ESP32S2_SPIRAM_SUPPORT)
#if (CONFIG_SPIRAM_USE_CAPS_ALLOC || CONFIG_SPIRAM_USE_MALLOC)
if (esp_ptr_external_ram(input)) {
Cache_WriteBack_Addr((uint32_t)input, ilen);
}
@ -303,7 +242,7 @@ int esp_sha_dma(esp_sha_type sha_type, const void *input, uint32_t ilen,
which is max 3968/64 + 64/64 = 63 blocks */
for (int i = 0; i < dma_op_num; i++) {
int dma_chunk_len = MIN(ilen, SHA_DMA_MAX_BYTES);
int dma_chunk_len = MIN(ilen, SOC_SHA_DMA_MAX_BUFFER_SIZE);
ret = esp_sha_dma_process(sha_type, input, dma_chunk_len, buf, buf_len, is_first_block);
@ -324,34 +263,16 @@ cleanup:
return ret;
}
static void esp_sha_dma_init(lldesc_t *input)
{
/* Reset DMA */
SET_PERI_REG_MASK(CRYPTO_DMA_CONF0_REG, CONF0_REG_AHBM_RST | CONF0_REG_OUT_RST | CONF0_REG_AHBM_FIFO_RST);
CLEAR_PERI_REG_MASK(CRYPTO_DMA_CONF0_REG, CONF0_REG_AHBM_RST | CONF0_REG_OUT_RST | CONF0_REG_AHBM_FIFO_RST);
/* Set descriptors */
CLEAR_PERI_REG_MASK(CRYPTO_DMA_OUT_LINK_REG, OUT_LINK_REG_OUTLINK_ADDR);
SET_PERI_REG_MASK(CRYPTO_DMA_OUT_LINK_REG, ((uint32_t)(input))&OUT_LINK_REG_OUTLINK_ADDR);
/* Start transfer */
SET_PERI_REG_MASK(CRYPTO_DMA_OUT_LINK_REG, OUT_LINK_REG_OUTLINK_START);
}
/* Performs SHA on multiple blocks at a time */
static esp_err_t esp_sha_dma_process(esp_sha_type sha_type, const void *input, uint32_t ilen,
const void *buf, uint32_t buf_len, bool is_first_block)
const void *buf, uint32_t buf_len, bool is_first_block)
{
size_t blk_len = 0;
int ret = 0;
lldesc_t dma_descr_input = {};
lldesc_t dma_descr_buf = {};
lldesc_t *dma_descr_head;
blk_len = block_length(sha_type);
REG_WRITE(SHA_MODE_REG, sha_type);
REG_WRITE(SHA_BLOCK_NUM_REG, ((ilen + buf_len) / blk_len));
size_t num_blks = (ilen + buf_len) / block_length(sha_type);
/* DMA descriptor for Memory to DMA-SHA transfer */
if (ilen) {
@ -359,7 +280,7 @@ static esp_err_t esp_sha_dma_process(esp_sha_type sha_type, const void *input, u
dma_descr_input.size = ilen;
dma_descr_input.owner = 1;
dma_descr_input.eof = 1;
dma_descr_input.buf = input;
dma_descr_input.buf = (uint8_t *)input;
dma_descr_head = &dma_descr_input;
}
/* Check after input to overide head if there is any buf*/
@ -368,7 +289,7 @@ static esp_err_t esp_sha_dma_process(esp_sha_type sha_type, const void *input, u
dma_descr_buf.size = buf_len;
dma_descr_buf.owner = 1;
dma_descr_buf.eof = 1;
dma_descr_buf.buf = buf;
dma_descr_buf.buf = (uint8_t *)buf;
dma_descr_head = &dma_descr_buf;
}
@ -378,16 +299,8 @@ static esp_err_t esp_sha_dma_process(esp_sha_type sha_type, const void *input, u
dma_descr_buf.empty = (uint32_t)(&dma_descr_input);
}
esp_sha_dma_init(dma_descr_head);
sha_hal_hash_dma(sha_type, dma_descr_head, num_blks, is_first_block);
/* Start hashing */
if (is_first_block) {
REG_WRITE(SHA_DMA_START_REG, 1);
} else {
REG_WRITE(SHA_DMA_CONTINUE_REG, 1);
}
esp_sha_wait_idle();
return ret;
}

Wyświetl plik

@ -15,26 +15,29 @@
#include <string.h>
#include <stdio.h>
#include <assert.h>
#if CONFIG_IDF_TARGET_ESP32
#include "esp32/sha.h"
#elif CONFIG_IDF_TARGET_ESP32S2
#include "esp32s2/sha.h"
#elif CONFIG_IDF_TARGET_ESP32S3
#include "esp32s3/sha.h"
#endif
#include "hal/sha_types.h"
#include "soc/sha_caps.h"
#include "esp_log.h"
#include <mbedtls/sha1.h>
#include <mbedtls/sha256.h>
#include <mbedtls/sha512.h>
#if SOC_SHA_SUPPORT_PARALLEL_ENG
#include "sha/sha_parallel_engine.h"
#elif SOC_SHA_SUPPORT_DMA
#include "sha/sha_dma.h"
#endif
static const char *TAG = "esp_sha";
void esp_sha(esp_sha_type sha_type, const unsigned char *input, size_t ilen, unsigned char *output)
{
int ret;
assert(input != NULL && output != NULL);
#if SOC_SHA_SUPPORT_SHA1
if (sha_type == SHA1) {
mbedtls_sha1_context *ctx1 = (mbedtls_sha1_context *)malloc(sizeof(mbedtls_sha1_context));
assert(ctx1 != NULL);
mbedtls_sha1_starts_ret(ctx1);
@ -44,9 +47,12 @@ void esp_sha(esp_sha_type sha_type, const unsigned char *input, size_t ilen, uns
assert(ret == 0);
mbedtls_sha1_free(ctx1);
free(ctx1);
return;
}
#endif //SOC_SHA_SUPPORT_SHA1
} else if (sha_type == SHA2_256) {
#if SOC_SHA_SUPPORT_SHA256
if (sha_type == SHA2_256) {
mbedtls_sha256_context *ctx256 = (mbedtls_sha256_context *)malloc(sizeof(mbedtls_sha256_context));
assert(ctx256 != NULL);
mbedtls_sha256_starts_ret(ctx256, 0);
@ -56,9 +62,12 @@ void esp_sha(esp_sha_type sha_type, const unsigned char *input, size_t ilen, uns
assert(ret == 0);
mbedtls_sha256_free(ctx256);
free(ctx256);
return;
}
#endif //SOC_SHA_SUPPORT_SHA256
} else if (sha_type == SHA2_384) {
#if SOC_SHA_SUPPORT_SHA384
if (sha_type == SHA2_384) {
mbedtls_sha512_context *ctx384 = (mbedtls_sha512_context *)malloc(sizeof(mbedtls_sha512_context));
assert(ctx384 != NULL);
mbedtls_sha512_starts_ret(ctx384, 1);
@ -68,9 +77,12 @@ void esp_sha(esp_sha_type sha_type, const unsigned char *input, size_t ilen, uns
assert(ret == 0);
mbedtls_sha512_free(ctx384);
free(ctx384);
return;
}
#endif //SOC_SHA_SUPPORT_SHA384
} else if (sha_type == SHA2_512) {
#if SOC_SHA_SUPPORT_SHA512
if (sha_type == SHA2_512) {
mbedtls_sha512_context *ctx512 = (mbedtls_sha512_context *)malloc(sizeof(mbedtls_sha512_context));
assert(ctx512 != NULL);
mbedtls_sha512_starts_ret(ctx512, 0);
@ -80,7 +92,10 @@ void esp_sha(esp_sha_type sha_type, const unsigned char *input, size_t ilen, uns
assert(ret == 0);
mbedtls_sha512_free(ctx512);
free(ctx512);
return;
}
#endif //SOC_SHA_SUPPORT_SHA512
ESP_LOGE(TAG, "SHA type %d not supported", sha_type);
abort();
}

Wyświetl plik

@ -47,11 +47,15 @@
#endif /* MBEDTLS_PLATFORM_C */
#endif /* MBEDTLS_SELF_TEST */
#include "esp32/sha.h"
#include "sha/sha_parallel_engine.h"
/* Implementation that should never be optimized out by the compiler */
static void mbedtls_zeroize( void *v, size_t n ) {
volatile unsigned char *p = (unsigned char*)v; while( n-- ) *p++ = 0;
static void mbedtls_zeroize( void *v, size_t n )
{
volatile unsigned char *p = (unsigned char *)v;
while ( n-- ) {
*p++ = 0;
}
}
/*
@ -84,8 +88,9 @@ void mbedtls_sha1_init( mbedtls_sha1_context *ctx )
void mbedtls_sha1_free( mbedtls_sha1_context *ctx )
{
if( ctx == NULL )
if ( ctx == NULL ) {
return;
}
if (ctx->mode == ESP_MBEDTLS_SHA1_HARDWARE) {
esp_sha_unlock_engine(SHA1);
@ -335,8 +340,9 @@ int mbedtls_sha1_update_ret( mbedtls_sha1_context *ctx, const unsigned char *inp
size_t fill;
uint32_t left;
if( ilen == 0 )
if ( ilen == 0 ) {
return 0;
}
left = ctx->total[0] & 0x3F;
fill = 64 - left;
@ -344,11 +350,11 @@ int mbedtls_sha1_update_ret( mbedtls_sha1_context *ctx, const unsigned char *inp
ctx->total[0] += (uint32_t) ilen;
ctx->total[0] &= 0xFFFFFFFF;
if( ctx->total[0] < (uint32_t) ilen )
if ( ctx->total[0] < (uint32_t) ilen ) {
ctx->total[1]++;
}
if( left && ilen >= fill )
{
if ( left && ilen >= fill ) {
memcpy( (void *) (ctx->buffer + left), input, fill );
if ( ( ret = mbedtls_internal_sha1_process( ctx, ctx->buffer ) ) != 0 ) {
@ -360,8 +366,7 @@ int mbedtls_sha1_update_ret( mbedtls_sha1_context *ctx, const unsigned char *inp
left = 0;
}
while( ilen >= 64 )
{
while ( ilen >= 64 ) {
if ( ( ret = mbedtls_internal_sha1_process( ctx, input ) ) != 0 ) {
return ret;
}
@ -370,8 +375,9 @@ int mbedtls_sha1_update_ret( mbedtls_sha1_context *ctx, const unsigned char *inp
ilen -= 64;
}
if( ilen > 0 )
if ( ilen > 0 ) {
memcpy( (void *) (ctx->buffer + left), input, ilen );
}
return 0;
}
@ -385,9 +391,8 @@ void mbedtls_sha1_update( mbedtls_sha1_context *ctx,
}
#endif
static const unsigned char sha1_padding[64] =
{
0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
static const unsigned char sha1_padding[64] = {
0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
@ -404,7 +409,7 @@ int mbedtls_sha1_finish_ret( mbedtls_sha1_context *ctx, unsigned char output[20]
unsigned char msglen[8];
high = ( ctx->total[0] >> 29 )
| ( ctx->total[1] << 3 );
| ( ctx->total[1] << 3 );
low = ( ctx->total[0] << 3 );
PUT_UINT32_BE( high, msglen, 0 );

Wyświetl plik

@ -48,11 +48,15 @@
#endif /* MBEDTLS_PLATFORM_C */
#endif /* MBEDTLS_SELF_TEST */
#include "esp32/sha.h"
#include "sha/sha_parallel_engine.h"
/* Implementation that should never be optimized out by the compiler */
static void mbedtls_zeroize( void *v, size_t n ) {
volatile unsigned char *p = v; while( n-- ) *p++ = 0;
static void mbedtls_zeroize( void *v, size_t n )
{
volatile unsigned char *p = v;
while ( n-- ) {
*p++ = 0;
}
}
/*
@ -85,8 +89,9 @@ void mbedtls_sha256_init( mbedtls_sha256_context *ctx )
void mbedtls_sha256_free( mbedtls_sha256_context *ctx )
{
if( ctx == NULL )
if ( ctx == NULL ) {
return;
}
if (ctx->mode == ESP_MBEDTLS_SHA256_HARDWARE) {
esp_sha_unlock_engine(SHA2_256);
@ -116,8 +121,7 @@ int mbedtls_sha256_starts_ret( mbedtls_sha256_context *ctx, int is224 )
ctx->total[0] = 0;
ctx->total[1] = 0;
if( is224 == 0 )
{
if ( is224 == 0 ) {
/* SHA-256 */
ctx->state[0] = 0x6A09E667;
ctx->state[1] = 0xBB67AE85;
@ -127,9 +131,7 @@ int mbedtls_sha256_starts_ret( mbedtls_sha256_context *ctx, int is224 )
ctx->state[5] = 0x9B05688C;
ctx->state[6] = 0x1F83D9AB;
ctx->state[7] = 0x5BE0CD19;
}
else
{
} else {
/* SHA-224 */
ctx->state[0] = 0xC1059ED8;
ctx->state[1] = 0x367CD507;
@ -157,8 +159,7 @@ void mbedtls_sha256_starts( mbedtls_sha256_context *ctx,
}
#endif
static const uint32_t K[] =
{
static const uint32_t K[] = {
0x428A2F98, 0x71374491, 0xB5C0FBCF, 0xE9B5DBA5,
0x3956C25B, 0x59F111F1, 0x923F82A4, 0xAB1C5ED5,
0xD807AA98, 0x12835B01, 0x243185BE, 0x550C7DC3,
@ -241,16 +242,17 @@ static void mbedtls_sha256_software_process( mbedtls_sha256_context *ctx, const
uint32_t A[8];
unsigned int i;
for( i = 0; i < 8; i++ )
for ( i = 0; i < 8; i++ ) {
A[i] = ctx->state[i];
}
#if defined(MBEDTLS_SHA256_SMALLER)
for( i = 0; i < 64; i++ )
{
if( i < 16 )
for ( i = 0; i < 64; i++ ) {
if ( i < 16 ) {
GET_UINT32_BE( W[i], data, 4 * i );
else
} else {
R( i );
}
P( A[0], A[1], A[2], A[3], A[4], A[5], A[6], A[7], W[i], K[i] );
@ -258,50 +260,51 @@ static void mbedtls_sha256_software_process( mbedtls_sha256_context *ctx, const
A[3] = A[2]; A[2] = A[1]; A[1] = A[0]; A[0] = temp1;
}
#else /* MBEDTLS_SHA256_SMALLER */
for( i = 0; i < 16; i++ )
for ( i = 0; i < 16; i++ ) {
GET_UINT32_BE( W[i], data, 4 * i );
for( i = 0; i < 16; i += 8 )
{
P( A[0], A[1], A[2], A[3], A[4], A[5], A[6], A[7], W[i+0], K[i+0] );
P( A[7], A[0], A[1], A[2], A[3], A[4], A[5], A[6], W[i+1], K[i+1] );
P( A[6], A[7], A[0], A[1], A[2], A[3], A[4], A[5], W[i+2], K[i+2] );
P( A[5], A[6], A[7], A[0], A[1], A[2], A[3], A[4], W[i+3], K[i+3] );
P( A[4], A[5], A[6], A[7], A[0], A[1], A[2], A[3], W[i+4], K[i+4] );
P( A[3], A[4], A[5], A[6], A[7], A[0], A[1], A[2], W[i+5], K[i+5] );
P( A[2], A[3], A[4], A[5], A[6], A[7], A[0], A[1], W[i+6], K[i+6] );
P( A[1], A[2], A[3], A[4], A[5], A[6], A[7], A[0], W[i+7], K[i+7] );
}
for( i = 16; i < 64; i += 8 )
{
P( A[0], A[1], A[2], A[3], A[4], A[5], A[6], A[7], R(i+0), K[i+0] );
P( A[7], A[0], A[1], A[2], A[3], A[4], A[5], A[6], R(i+1), K[i+1] );
P( A[6], A[7], A[0], A[1], A[2], A[3], A[4], A[5], R(i+2), K[i+2] );
P( A[5], A[6], A[7], A[0], A[1], A[2], A[3], A[4], R(i+3), K[i+3] );
P( A[4], A[5], A[6], A[7], A[0], A[1], A[2], A[3], R(i+4), K[i+4] );
P( A[3], A[4], A[5], A[6], A[7], A[0], A[1], A[2], R(i+5), K[i+5] );
P( A[2], A[3], A[4], A[5], A[6], A[7], A[0], A[1], R(i+6), K[i+6] );
P( A[1], A[2], A[3], A[4], A[5], A[6], A[7], A[0], R(i+7), K[i+7] );
for ( i = 0; i < 16; i += 8 ) {
P( A[0], A[1], A[2], A[3], A[4], A[5], A[6], A[7], W[i + 0], K[i + 0] );
P( A[7], A[0], A[1], A[2], A[3], A[4], A[5], A[6], W[i + 1], K[i + 1] );
P( A[6], A[7], A[0], A[1], A[2], A[3], A[4], A[5], W[i + 2], K[i + 2] );
P( A[5], A[6], A[7], A[0], A[1], A[2], A[3], A[4], W[i + 3], K[i + 3] );
P( A[4], A[5], A[6], A[7], A[0], A[1], A[2], A[3], W[i + 4], K[i + 4] );
P( A[3], A[4], A[5], A[6], A[7], A[0], A[1], A[2], W[i + 5], K[i + 5] );
P( A[2], A[3], A[4], A[5], A[6], A[7], A[0], A[1], W[i + 6], K[i + 6] );
P( A[1], A[2], A[3], A[4], A[5], A[6], A[7], A[0], W[i + 7], K[i + 7] );
}
for ( i = 16; i < 64; i += 8 ) {
P( A[0], A[1], A[2], A[3], A[4], A[5], A[6], A[7], R(i + 0), K[i + 0] );
P( A[7], A[0], A[1], A[2], A[3], A[4], A[5], A[6], R(i + 1), K[i + 1] );
P( A[6], A[7], A[0], A[1], A[2], A[3], A[4], A[5], R(i + 2), K[i + 2] );
P( A[5], A[6], A[7], A[0], A[1], A[2], A[3], A[4], R(i + 3), K[i + 3] );
P( A[4], A[5], A[6], A[7], A[0], A[1], A[2], A[3], R(i + 4), K[i + 4] );
P( A[3], A[4], A[5], A[6], A[7], A[0], A[1], A[2], R(i + 5), K[i + 5] );
P( A[2], A[3], A[4], A[5], A[6], A[7], A[0], A[1], R(i + 6), K[i + 6] );
P( A[1], A[2], A[3], A[4], A[5], A[6], A[7], A[0], R(i + 7), K[i + 7] );
}
#endif /* MBEDTLS_SHA256_SMALLER */
for( i = 0; i < 8; i++ )
for ( i = 0; i < 8; i++ ) {
ctx->state[i] += A[i];
}
}
/*
* SHA-256 process buffer
*/
int mbedtls_sha256_update_ret( mbedtls_sha256_context *ctx, const unsigned char *input,
size_t ilen )
size_t ilen )
{
int ret;
size_t fill;
uint32_t left;
if( ilen == 0 )
if ( ilen == 0 ) {
return 0;
}
left = ctx->total[0] & 0x3F;
fill = 64 - left;
@ -309,11 +312,11 @@ int mbedtls_sha256_update_ret( mbedtls_sha256_context *ctx, const unsigned char
ctx->total[0] += (uint32_t) ilen;
ctx->total[0] &= 0xFFFFFFFF;
if( ctx->total[0] < (uint32_t) ilen )
if ( ctx->total[0] < (uint32_t) ilen ) {
ctx->total[1]++;
}
if( left && ilen >= fill )
{
if ( left && ilen >= fill ) {
memcpy( (void *) (ctx->buffer + left), input, fill );
if ( ( ret = mbedtls_internal_sha256_process( ctx, ctx->buffer ) ) != 0 ) {
@ -325,8 +328,7 @@ int mbedtls_sha256_update_ret( mbedtls_sha256_context *ctx, const unsigned char
left = 0;
}
while( ilen >= 64 )
{
while ( ilen >= 64 ) {
if ( ( ret = mbedtls_internal_sha256_process( ctx, input ) ) != 0 ) {
return ret;
}
@ -335,8 +337,9 @@ int mbedtls_sha256_update_ret( mbedtls_sha256_context *ctx, const unsigned char
ilen -= 64;
}
if( ilen > 0 )
if ( ilen > 0 ) {
memcpy( (void *) (ctx->buffer + left), input, ilen );
}
return 0;
}
@ -350,9 +353,8 @@ void mbedtls_sha256_update( mbedtls_sha256_context *ctx,
}
#endif
static const unsigned char sha256_padding[64] =
{
0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
static const unsigned char sha256_padding[64] = {
0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
@ -369,7 +371,7 @@ int mbedtls_sha256_finish_ret( mbedtls_sha256_context *ctx, unsigned char output
unsigned char msglen[8];
high = ( ctx->total[0] >> 29 )
| ( ctx->total[1] << 3 );
| ( ctx->total[1] << 3 );
low = ( ctx->total[0] << 3 );
PUT_UINT32_BE( high, msglen, 0 );
@ -399,8 +401,9 @@ int mbedtls_sha256_finish_ret( mbedtls_sha256_context *ctx, unsigned char output
PUT_UINT32_BE( ctx->state[5], output, 20 );
PUT_UINT32_BE( ctx->state[6], output, 24 );
if( ctx->is224 == 0 )
if ( ctx->is224 == 0 ) {
PUT_UINT32_BE( ctx->state[7], output, 28 );
}
out:
if (ctx->mode == ESP_MBEDTLS_SHA256_HARDWARE) {

Wyświetl plik

@ -38,9 +38,9 @@
#include "mbedtls/sha512.h"
#if defined(_MSC_VER) || defined(__WATCOMC__)
#define UL64(x) x##ui64
#define UL64(x) x##ui64
#else
#define UL64(x) x##ULL
#define UL64(x) x##ULL
#endif
#include <string.h>
@ -54,7 +54,7 @@
#endif /* MBEDTLS_PLATFORM_C */
#endif /* MBEDTLS_SELF_TEST */
#include "esp32/sha.h"
#include "sha/sha_parallel_engine.h"
inline static esp_sha_type sha_type(const mbedtls_sha512_context *ctx)
{
@ -62,8 +62,12 @@ inline static esp_sha_type sha_type(const mbedtls_sha512_context *ctx)
}
/* Implementation that should never be optimized out by the compiler */
static void mbedtls_zeroize( void *v, size_t n ) {
volatile unsigned char *p = v; while( n-- ) *p++ = 0;
static void mbedtls_zeroize( void *v, size_t n )
{
volatile unsigned char *p = v;
while ( n-- ) {
*p++ = 0;
}
}
/*
@ -104,8 +108,9 @@ void mbedtls_sha512_init( mbedtls_sha512_context *ctx )
void mbedtls_sha512_free( mbedtls_sha512_context *ctx )
{
if( ctx == NULL )
if ( ctx == NULL ) {
return;
}
if (ctx->mode == ESP_MBEDTLS_SHA512_HARDWARE) {
esp_sha_unlock_engine(sha_type(ctx));
@ -140,8 +145,7 @@ int mbedtls_sha512_starts_ret( mbedtls_sha512_context *ctx, int is384 )
ctx->total[0] = 0;
ctx->total[1] = 0;
if( is384 == 0 )
{
if ( is384 == 0 ) {
/* SHA-512 */
ctx->state[0] = UL64(0x6A09E667F3BCC908);
ctx->state[1] = UL64(0xBB67AE8584CAA73B);
@ -151,9 +155,7 @@ int mbedtls_sha512_starts_ret( mbedtls_sha512_context *ctx, int is384 )
ctx->state[5] = UL64(0x9B05688C2B3E6C1F);
ctx->state[6] = UL64(0x1F83D9ABFB41BD6B);
ctx->state[7] = UL64(0x5BE0CD19137E2179);
}
else
{
} else {
/* SHA-384 */
ctx->state[0] = UL64(0xCBBB9D5DC1059ED8);
ctx->state[1] = UL64(0x629A292A367CD507);
@ -185,8 +187,7 @@ void mbedtls_sha512_starts( mbedtls_sha512_context *ctx,
/*
* Round constants
*/
static const uint64_t K[80] =
{
static const uint64_t K[80] = {
UL64(0x428A2F98D728AE22), UL64(0x7137449123EF65CD),
UL64(0xB5C0FBCFEC4D3B2F), UL64(0xE9B5DBA58189DBBC),
UL64(0x3956C25BF348B538), UL64(0x59F111F1B605D019),
@ -288,13 +289,11 @@ static void mbedtls_sha512_software_process( mbedtls_sha512_context *ctx, const
d += temp1; h = temp1 + temp2; \
}
for( i = 0; i < 16; i++ )
{
for ( i = 0; i < 16; i++ ) {
GET_UINT64_BE( W[i], data, i << 3 );
}
for( ; i < 80; i++ )
{
for ( ; i < 80; i++ ) {
W[i] = S1(W[i - 2]) + W[i - 7] +
S0(W[i - 15]) + W[i - 16];
}
@ -309,8 +308,7 @@ static void mbedtls_sha512_software_process( mbedtls_sha512_context *ctx, const
H = ctx->state[7];
i = 0;
do
{
do {
P( A, B, C, D, E, F, G, H, W[i], K[i] ); i++;
P( H, A, B, C, D, E, F, G, W[i], K[i] ); i++;
P( G, H, A, B, C, D, E, F, W[i], K[i] ); i++;
@ -319,8 +317,7 @@ static void mbedtls_sha512_software_process( mbedtls_sha512_context *ctx, const
P( D, E, F, G, H, A, B, C, W[i], K[i] ); i++;
P( C, D, E, F, G, H, A, B, W[i], K[i] ); i++;
P( B, C, D, E, F, G, H, A, W[i], K[i] ); i++;
}
while( i < 80 );
} while ( i < 80 );
ctx->state[0] += A;
ctx->state[1] += B;
@ -336,25 +333,26 @@ static void mbedtls_sha512_software_process( mbedtls_sha512_context *ctx, const
* SHA-512 process buffer
*/
int mbedtls_sha512_update_ret( mbedtls_sha512_context *ctx, const unsigned char *input,
size_t ilen )
size_t ilen )
{
int ret;
size_t fill;
unsigned int left;
if( ilen == 0 )
if ( ilen == 0 ) {
return 0;
}
left = (unsigned int) (ctx->total[0] & 0x7F);
fill = 128 - left;
ctx->total[0] += (uint64_t) ilen;
if( ctx->total[0] < (uint64_t) ilen )
if ( ctx->total[0] < (uint64_t) ilen ) {
ctx->total[1]++;
}
if( left && ilen >= fill )
{
if ( left && ilen >= fill ) {
memcpy( (void *) (ctx->buffer + left), input, fill );
if ( ( ret = mbedtls_internal_sha512_process( ctx, ctx->buffer ) ) != 0 ) {
return ret;
@ -365,8 +363,7 @@ int mbedtls_sha512_update_ret( mbedtls_sha512_context *ctx, const unsigned char
left = 0;
}
while( ilen >= 128 )
{
while ( ilen >= 128 ) {
if ( ( ret = mbedtls_internal_sha512_process( ctx, input ) ) != 0 ) {
return ret;
}
@ -375,8 +372,9 @@ int mbedtls_sha512_update_ret( mbedtls_sha512_context *ctx, const unsigned char
ilen -= 128;
}
if( ilen > 0 )
if ( ilen > 0 ) {
memcpy( (void *) (ctx->buffer + left), input, ilen );
}
return 0;
}
@ -391,9 +389,8 @@ void mbedtls_sha512_update( mbedtls_sha512_context *ctx,
#endif
static const unsigned char sha512_padding[128] =
{
0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
static const unsigned char sha512_padding[128] = {
0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
@ -414,7 +411,7 @@ int mbedtls_sha512_finish_ret( mbedtls_sha512_context *ctx, unsigned char output
unsigned char msglen[16];
high = ( ctx->total[0] >> 61 )
| ( ctx->total[1] << 3 );
| ( ctx->total[1] << 3 );
low = ( ctx->total[0] << 3 );
PUT_UINT64_BE( high, msglen, 0 );
@ -443,8 +440,7 @@ int mbedtls_sha512_finish_ret( mbedtls_sha512_context *ctx, unsigned char output
PUT_UINT64_BE( ctx->state[4], output, 32 );
PUT_UINT64_BE( ctx->state[5], output, 40 );
if( ctx->is384 == 0 )
{
if ( ctx->is384 == 0 ) {
PUT_UINT64_BE( ctx->state[6], output, 48 );
PUT_UINT64_BE( ctx->state[7], output, 56 );
}

Wyświetl plik

@ -33,27 +33,14 @@
#include "freertos/FreeRTOS.h"
#include "freertos/semphr.h"
#include "esp32/sha.h"
#include "hal/sha_hal.h"
#include "hal/sha_types.h"
#include "sha/sha_parallel_engine.h"
#include "soc/hwcrypto_periph.h"
#include "driver/periph_ctrl.h"
inline static uint32_t SHA_LOAD_REG(esp_sha_type sha_type) {
return SHA_1_LOAD_REG + sha_type * 0x10;
}
inline static uint32_t SHA_BUSY_REG(esp_sha_type sha_type) {
return SHA_1_BUSY_REG + sha_type * 0x10;
}
inline static uint32_t SHA_START_REG(esp_sha_type sha_type) {
return SHA_1_START_REG + sha_type * 0x10;
}
inline static uint32_t SHA_CONTINUE_REG(esp_sha_type sha_type) {
return SHA_1_CONTINUE_REG + sha_type * 0x10;
}
/* Single spinlock for SHA engine memory block
/*
Single spinlock for SHA engine memory block
*/
static portMUX_TYPE memory_block_lock = portMUX_INITIALIZER_UNLOCKED;
@ -76,9 +63,25 @@ static uint8_t engines_in_use;
*/
static portMUX_TYPE engines_in_use_lock = portMUX_INITIALIZER_UNLOCKED;
/* Return block size (in words) for a given SHA type */
inline static size_t block_length(esp_sha_type type)
{
switch (type) {
case SHA1:
case SHA2_256:
return 64 / 4;
case SHA2_384:
case SHA2_512:
return 128 / 4;
default:
return 0;
}
}
/* Index into the engine_states array */
inline static size_t sha_engine_index(esp_sha_type type) {
switch(type) {
inline static size_t sha_engine_index(esp_sha_type type)
{
switch (type) {
case SHA1:
return 0;
case SHA2_256:
@ -88,36 +91,6 @@ inline static size_t sha_engine_index(esp_sha_type type) {
}
}
/* Return digest length (in bytes) for a given SHA type */
inline static size_t sha_length(esp_sha_type type) {
switch(type) {
case SHA1:
return 20;
case SHA2_256:
return 32;
case SHA2_384:
return 48;
case SHA2_512:
return 64;
default:
return 0;
}
}
/* Return block size (in bytes) for a given SHA type */
inline static size_t block_length(esp_sha_type type) {
switch(type) {
case SHA1:
case SHA2_256:
return 64;
case SHA2_384:
case SHA2_512:
return 128;
default:
return 0;
}
}
void esp_sha_lock_memory_block(void)
{
portENTER_CRITICAL(&memory_block_lock);
@ -211,23 +184,8 @@ void esp_sha_unlock_engine(esp_sha_type sha_type)
xSemaphoreGive(engine_state);
}
void esp_sha_wait_idle(void)
{
while(1) {
if(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) {
break;
}
}
}
void esp_sha_read_digest_state(esp_sha_type sha_type, void *digest_state)
{
uint32_t *digest_state_words = NULL;
uint32_t *reg_addr_buf = NULL;
uint32_t word_len = sha_length(sha_type)/4;
#ifndef NDEBUG
{
SemaphoreHandle_t engine_state = sha_get_engine_state(sha_type);
@ -237,44 +195,17 @@ void esp_sha_read_digest_state(esp_sha_type sha_type, void *digest_state)
#endif
// preemptively do this before entering the critical section, then re-check once in it
esp_sha_wait_idle();
sha_hal_wait_idle();
esp_sha_lock_memory_block();
esp_sha_wait_idle();
sha_hal_read_digest(sha_type, digest_state);
DPORT_REG_WRITE(SHA_LOAD_REG(sha_type), 1);
while(DPORT_REG_READ(SHA_BUSY_REG(sha_type)) == 1) { }
digest_state_words = (uint32_t *)digest_state;
reg_addr_buf = (uint32_t *)(SHA_TEXT_BASE);
if(sha_type == SHA2_384 || sha_type == SHA2_512) {
/* for these ciphers using 64-bit states, swap each pair of words */
DPORT_INTERRUPT_DISABLE(); // Disable interrupt only on current CPU.
for(int i = 0; i < word_len; i += 2) {
digest_state_words[i+1] = DPORT_SEQUENCE_REG_READ((uint32_t)&reg_addr_buf[i]);
digest_state_words[i] = DPORT_SEQUENCE_REG_READ((uint32_t)&reg_addr_buf[i+1]);
}
DPORT_INTERRUPT_RESTORE(); // restore the previous interrupt level
} else {
esp_dport_access_read_buffer(digest_state_words, (uint32_t)&reg_addr_buf[0], word_len);
}
esp_sha_unlock_memory_block();
/* Fault injection check: verify SHA engine actually ran,
state is not all zeroes.
*/
for (int i = 0; i < word_len; i++) {
if (digest_state_words[i] != 0) {
return;
}
}
abort(); // SHA peripheral returned all zero state, probably due to fault injection
}
void esp_sha_block(esp_sha_type sha_type, const void *data_block, bool is_first_block)
void esp_sha_block(esp_sha_type sha_type, const void *data_block, bool first_block)
{
uint32_t *reg_addr_buf = NULL;
uint32_t *data_words = NULL;
#ifndef NDEBUG
{
SemaphoreHandle_t engine_state = sha_get_engine_state(sha_type);
@ -284,30 +215,10 @@ void esp_sha_block(esp_sha_type sha_type, const void *data_block, bool is_first_
#endif
// preemptively do this before entering the critical section, then re-check once in it
esp_sha_wait_idle();
sha_hal_wait_idle();
esp_sha_lock_memory_block();
esp_sha_wait_idle();
/* Fill the data block */
reg_addr_buf = (uint32_t *)(SHA_TEXT_BASE);
data_words = (uint32_t *)data_block;
for (int i = 0; i < block_length(sha_type) / 4; i++) {
reg_addr_buf[i] = __builtin_bswap32(data_words[i]);
}
asm volatile ("memw");
if(is_first_block) {
DPORT_REG_WRITE(SHA_START_REG(sha_type), 1);
} else {
DPORT_REG_WRITE(SHA_CONTINUE_REG(sha_type), 1);
}
sha_hal_hash_block(sha_type, data_block, block_length(sha_type), first_block);
esp_sha_unlock_memory_block();
/* Note: deliberately not waiting for this operation to complete,
as a performance tweak - delay waiting until the next time we need the SHA
unit, instead.
*/
}

Wyświetl plik

@ -0,0 +1,91 @@
// Copyright 2015-2019 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/*******************************************************************************
* NOTICE
* The hal is not public api, don't use in application code.
* See readme.md in soc/include/hal/readme.md
******************************************************************************/
#pragma once
#include <stddef.h>
#include <stdbool.h>
#include "soc/sha_caps.h"
#include "soc/lldesc.h"
#include "hal/sha_types.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Hashes a single message block
*
* @param sha_type SHA algorithm to hash with
* @param data_block Input message to be hashed
* @param block_word_len Length of the input message
* @param first_block Is this the first block in a message or a continuation?
*/
void sha_hal_hash_block(esp_sha_type sha_type, const void *data_block, size_t block_word_len, bool first_block);
/**
* @brief Polls and waits until the SHA engine is idle
*
*/
void sha_hal_wait_idle(void);
/**
* @brief Reads the current message digest from the SHA engine
*
* @param sha_type SHA algorithm used
* @param digest_state Output buffer to which to read message digest to
*/
void sha_hal_read_digest(esp_sha_type sha_type, void *digest_state);
#if SOC_SHA_SUPPORT_RESUME
/**
* @brief Writes the message digest to the SHA engine
*
* @param sha_type The SHA algorithm type
* @param digest_state Message digest to be written to SHA engine
*/
void sha_hal_write_digest(esp_sha_type sha_type, void *digest_state);
#endif
#if SOC_SHA_SUPPORT_DMA
/**
* @brief Hashes a number of message blocks using DMA
*
* @param sha_type SHA algorithm to hash with
* @param input Input message to be hashed
* @param num_blocks Number of blocks to hash
* @param first_block Is this the first block in a message or a continuation?
*/
void sha_hal_hash_dma(esp_sha_type sha_type, lldesc_t *input, size_t num_blocks, bool first_block);
#endif
#if SOC_SHA_SUPPORT_SHA512_T
/**
* @brief Calculates and sets the initial digiest for SHA512_t
*
* @param t_string
* @param t_len
*/
void sha_hal_sha512_init_hash(uint32_t t_string, uint8_t t_len);
#endif
#ifdef __cplusplus
}
#endif

Wyświetl plik

@ -0,0 +1,34 @@
// Copyright 2020 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
#define SOC_SHA_SUPPORT_DMA (0)
/* ESP32 style SHA engine, where multiple states can be stored in parallel */
#define SOC_SHA_SUPPORT_PARALLEL_ENG (1)
/* Supported HW algorithms */
#define SOC_SHA_SUPPORT_SHA1 (1)
#define SOC_SHA_SUPPORT_SHA256 (1)
#define SOC_SHA_SUPPORT_SHA384 (1)
#define SOC_SHA_SUPPORT_SHA512 (1)
#ifdef __cplusplus
}
#endif

Wyświetl plik

@ -0,0 +1,54 @@
// Copyright 2020 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
/* Max amount of bytes in a single DMA operation is 4095,
for SHA this means that the biggest safe amount of bytes is
31 blocks of 128 bytes = 3968
*/
#define SOC_SHA_DMA_MAX_BUFFER_SIZE (3968)
#define SOC_SHA_SUPPORT_DMA (1)
/* ESP32 style SHA engine, where multiple states can be stored in parallel */
#define SOC_SHA_SUPPORT_PARALLEL_ENG (0)
/* The SHA engine is able to resume hashing from a user */
#define SOC_SHA_SUPPORT_RESUME (1)
/* Has "crypto DMA", which is shared with AES */
#define SOC_SHA_CRYPTO_DMA (1)
/* Has a centralized DMA, which is shared with all peripherals */
#define SOC_SHA_GENERAL_DMA (0)
/* Supported HW algorithms */
#define SOC_SHA_SUPPORT_SHA1 (1)
#define SOC_SHA_SUPPORT_SHA224 (1)
#define SOC_SHA_SUPPORT_SHA256 (1)
#define SOC_SHA_SUPPORT_SHA384 (1)
#define SOC_SHA_SUPPORT_SHA256 (1)
#define SOC_SHA_SUPPORT_SHA512 (1)
#define SOC_SHA_SUPPORT_SHA512_224 (1)
#define SOC_SHA_SUPPORT_SHA512_256 (1)
#define SOC_SHA_SUPPORT_SHA512_T (1)
#ifdef __cplusplus
}
#endif

Wyświetl plik

@ -0,0 +1,54 @@
// Copyright 2020 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
/* Max amount of bytes in a single DMA operation is 4095,
for SHA this means that the biggest safe amount of bytes is
31 blocks of 128 bytes = 3968
*/
#define SOC_SHA_DMA_MAX_BUFFER_SIZE (3968)
#define SOC_SHA_SUPPORT_DMA (1)
/* ESP32 style SHA engine, where multiple states can be stored in parallel */
#define SOC_SHA_SUPPORT_PARALLEL_ENG (0)
/* The SHA engine is able to resume hashing from a user */
#define SOC_SHA_SUPPORT_RESUME (1)
/* Has "crypto DMA", which is shared with AES */
#define SOC_SHA_CRYPTO_DMA (0)
/* Has a centralized DMA, which is shared with all peripherals */
#define SOC_SHA_GENERAL_DMA (1)
/* Supported HW algorithms */
#define SOC_SHA_SUPPORT_SHA1 (1)
#define SOC_SHA_SUPPORT_SHA224 (1)
#define SOC_SHA_SUPPORT_SHA256 (1)
#define SOC_SHA_SUPPORT_SHA384 (1)
#define SOC_SHA_SUPPORT_SHA256 (1)
#define SOC_SHA_SUPPORT_SHA512 (1)
#define SOC_SHA_SUPPORT_SHA512_224 (1)
#define SOC_SHA_SUPPORT_SHA512_256 (1)
#define SOC_SHA_SUPPORT_SHA512_T (1)
#ifdef __cplusplus
}
#endif

Wyświetl plik

@ -14,4 +14,5 @@
// Remove them when GDMA driver API is ready
#define SOC_GDMA_M2M_DMA_CHANNEL (0)
#define SOC_GDMA_SPI2_DMA_CHANNEL (1)
#define SOC_GDMA_SPI3_DMA_CHANNEL (2)
#define SOC_GDMA_SPI3_DMA_CHANNEL (2)
#define SOC_GDMA_SHA_DMA_CHANNEL (3)