mirror of
https://github.com/espressif/esp-idf.git
synced 2026-06-11 11:42:39 +02:00
Digital Signature support for S3
Closes IDF-1791
This commit is contained in:
@@ -1,52 +1,52 @@
|
||||
idf_build_get_property(target IDF_TARGET)
|
||||
|
||||
set(srcs "wdt_hal_iram.c"
|
||||
"mpu_hal.c"
|
||||
"cpu_hal.c")
|
||||
set(srcs "wdt_hal_iram.c"
|
||||
"mpu_hal.c"
|
||||
"cpu_hal.c")
|
||||
|
||||
set(includes "${target}/include" "include" "platform_port/include")
|
||||
|
||||
if(NOT BOOTLOADER_BUILD)
|
||||
list(APPEND srcs
|
||||
"rmt_hal.c"
|
||||
"rtc_io_hal.c"
|
||||
"spi_hal.c"
|
||||
"spi_hal_iram.c"
|
||||
"spi_slave_hal.c"
|
||||
"spi_slave_hal_iram.c"
|
||||
"i2s_hal.c"
|
||||
"sigmadelta_hal.c"
|
||||
"timer_hal.c"
|
||||
"ledc_hal.c"
|
||||
"ledc_hal_iram.c"
|
||||
"i2c_hal.c"
|
||||
"i2c_hal_iram.c"
|
||||
"gpio_hal.c"
|
||||
"uart_hal.c"
|
||||
"uart_hal_iram.c"
|
||||
"spi_flash_hal.c"
|
||||
"spi_flash_hal_iram.c"
|
||||
"spi_flash_encrypt_hal_iram.c"
|
||||
"soc_hal.c"
|
||||
"interrupt_controller_hal.c"
|
||||
"sha_hal.c"
|
||||
"aes_hal.c"
|
||||
"twai_hal.c"
|
||||
"twai_hal_iram.c"
|
||||
"adc_hal.c")
|
||||
"rmt_hal.c"
|
||||
"rtc_io_hal.c"
|
||||
"spi_hal.c"
|
||||
"spi_hal_iram.c"
|
||||
"spi_slave_hal.c"
|
||||
"spi_slave_hal_iram.c"
|
||||
"i2s_hal.c"
|
||||
"sigmadelta_hal.c"
|
||||
"timer_hal.c"
|
||||
"ledc_hal.c"
|
||||
"ledc_hal_iram.c"
|
||||
"i2c_hal.c"
|
||||
"i2c_hal_iram.c"
|
||||
"gpio_hal.c"
|
||||
"uart_hal.c"
|
||||
"uart_hal_iram.c"
|
||||
"spi_flash_hal.c"
|
||||
"spi_flash_hal_iram.c"
|
||||
"spi_flash_encrypt_hal_iram.c"
|
||||
"soc_hal.c"
|
||||
"interrupt_controller_hal.c"
|
||||
"sha_hal.c"
|
||||
"aes_hal.c"
|
||||
"twai_hal.c"
|
||||
"twai_hal_iram.c"
|
||||
"adc_hal.c")
|
||||
|
||||
if(${target} STREQUAL "esp32")
|
||||
list(APPEND srcs
|
||||
"dac_hal.c"
|
||||
"mcpwm_hal.c"
|
||||
"pcnt_hal.c"
|
||||
"sdio_slave_hal.c"
|
||||
"touch_sensor_hal.c"
|
||||
"esp32/adc_hal.c"
|
||||
"esp32/brownout_hal.c"
|
||||
"esp32/interrupt_descriptor_table.c"
|
||||
"esp32/touch_sensor_hal.c"
|
||||
"esp32/gpio_hal_workaround.c")
|
||||
"dac_hal.c"
|
||||
"mcpwm_hal.c"
|
||||
"pcnt_hal.c"
|
||||
"sdio_slave_hal.c"
|
||||
"touch_sensor_hal.c"
|
||||
"esp32/adc_hal.c"
|
||||
"esp32/brownout_hal.c"
|
||||
"esp32/interrupt_descriptor_table.c"
|
||||
"esp32/touch_sensor_hal.c"
|
||||
"esp32/gpio_hal_workaround.c")
|
||||
if(NOT BOOTLOADER_BUILD AND CONFIG_ETH_USE_ESP32_EMAC)
|
||||
list(APPEND srcs "emac_hal.c")
|
||||
endif()
|
||||
@@ -73,6 +73,7 @@ if(NOT BOOTLOADER_BUILD)
|
||||
|
||||
if(${target} STREQUAL "esp32s3")
|
||||
list(APPEND srcs
|
||||
"ds_hal.c"
|
||||
"gdma_hal.c"
|
||||
"lcd_hal.c"
|
||||
"mcpwm_hal.c"
|
||||
@@ -106,15 +107,15 @@ if(NOT BOOTLOADER_BUILD)
|
||||
|
||||
if(${target} STREQUAL "esp32h2")
|
||||
list(APPEND srcs
|
||||
"ds_hal.c"
|
||||
"gdma_hal.c"
|
||||
"spi_flash_hal_gpspi.c"
|
||||
"spi_slave_hd_hal.c"
|
||||
"systimer_hal.c"
|
||||
"esp32h2/adc_hal.c"
|
||||
"esp32h2/brownout_hal.c"
|
||||
"esp32h2/hmac_hal.c"
|
||||
"esp32h2/rtc_cntl_hal.c")
|
||||
"ds_hal.c"
|
||||
"gdma_hal.c"
|
||||
"spi_flash_hal_gpspi.c"
|
||||
"spi_slave_hd_hal.c"
|
||||
"systimer_hal.c"
|
||||
"esp32h2/adc_hal.c"
|
||||
"esp32h2/brownout_hal.c"
|
||||
"esp32h2/hmac_hal.c"
|
||||
"esp32h2/rtc_cntl_hal.c")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
|
||||
@@ -157,6 +157,8 @@ static inline uint32_t periph_ll_get_rst_en_mask(periph_module_t periph, bool en
|
||||
return SYSTEM_DMA_RST;
|
||||
case PERIPH_HMAC_MODULE:
|
||||
return SYSTEM_CRYPTO_HMAC_RST;
|
||||
case PERIPH_DS_MODULE:
|
||||
return SYSTEM_CRYPTO_DS_RST;
|
||||
case PERIPH_AES_MODULE:
|
||||
if (enable == true) {
|
||||
// Clear reset on digital signature, otherwise AES unit is held in reset also.
|
||||
@@ -203,6 +205,7 @@ static uint32_t periph_ll_get_clk_en_reg(periph_module_t periph)
|
||||
case PERIPH_LCD_CAM_MODULE:
|
||||
case PERIPH_GDMA_MODULE:
|
||||
case PERIPH_HMAC_MODULE:
|
||||
case PERIPH_DS_MODULE:
|
||||
case PERIPH_AES_MODULE:
|
||||
case PERIPH_SHA_MODULE:
|
||||
case PERIPH_RSA_MODULE:
|
||||
@@ -229,6 +232,7 @@ static uint32_t periph_ll_get_rst_en_reg(periph_module_t periph)
|
||||
case PERIPH_LCD_CAM_MODULE:
|
||||
case PERIPH_GDMA_MODULE:
|
||||
case PERIPH_HMAC_MODULE:
|
||||
case PERIPH_DS_MODULE:
|
||||
case PERIPH_AES_MODULE:
|
||||
case PERIPH_SHA_MODULE:
|
||||
case PERIPH_RSA_MODULE:
|
||||
|
||||
@@ -0,0 +1,162 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2020-2021 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "soc/hwcrypto_reg.h"
|
||||
#include "soc/soc_caps.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
static inline void ds_ll_start(void)
|
||||
{
|
||||
REG_WRITE(DS_SET_START_REG, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Wait until DS peripheral has finished any outstanding operation.
|
||||
*/
|
||||
static inline bool ds_ll_busy(void)
|
||||
{
|
||||
return (REG_READ(DS_QUERY_BUSY_REG) > 0) ? true : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Busy wait until the hardware is ready.
|
||||
*/
|
||||
static inline void ds_ll_wait_busy(void)
|
||||
{
|
||||
while (ds_ll_busy());
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief In case of a key error, check what caused it.
|
||||
*/
|
||||
static inline ds_key_check_t ds_ll_key_error_source(void)
|
||||
{
|
||||
uint32_t key_error = REG_READ(DS_QUERY_KEY_WRONG_REG);
|
||||
if (key_error == 0) {
|
||||
return DS_NO_KEY_INPUT;
|
||||
} else {
|
||||
return DS_OTHER_WRONG;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Write the initialization vector to the corresponding register field.
|
||||
*/
|
||||
static inline void ds_ll_configure_iv(const uint32_t *iv)
|
||||
{
|
||||
for (size_t i = 0; i < (SOC_DS_KEY_PARAM_MD_IV_LENGTH / sizeof(uint32_t)); i++) {
|
||||
REG_WRITE(DS_IV_BASE + (i * 4), iv[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Write the message which should be signed.
|
||||
*
|
||||
* @param msg Pointer to the message.
|
||||
* @param size Length of msg in bytes. It is the RSA signature length in bytes.
|
||||
*/
|
||||
static inline void ds_ll_write_message(const uint8_t *msg, size_t size)
|
||||
{
|
||||
memcpy((uint8_t *) DS_X_BASE, msg, size);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Write the encrypted private key parameters.
|
||||
*/
|
||||
static inline void ds_ll_write_private_key_params(const uint8_t *encrypted_key_params)
|
||||
{
|
||||
/* Note: as the internal peripheral still has RSA 4096 structure,
|
||||
but C is encrypted based on the actual max RSA length (ETS_DS_MAX_BITS), need to fragment it
|
||||
when copying to hardware...
|
||||
|
||||
(note if ETS_DS_MAX_BITS == 4096, this should be the same as copying data->c to hardware in one fragment)
|
||||
*/
|
||||
typedef struct {
|
||||
uint32_t addr;
|
||||
size_t len;
|
||||
} frag_t;
|
||||
const frag_t frags[] = {
|
||||
{DS_C_Y_BASE, SOC_DS_SIGNATURE_MAX_BIT_LEN / 8},
|
||||
{DS_C_M_BASE, SOC_DS_SIGNATURE_MAX_BIT_LEN / 8},
|
||||
{DS_C_RB_BASE, SOC_DS_SIGNATURE_MAX_BIT_LEN / 8},
|
||||
{DS_C_BOX_BASE, DS_IV_BASE - DS_C_BOX_BASE},
|
||||
};
|
||||
const size_t NUM_FRAGS = sizeof(frags) / sizeof(frag_t);
|
||||
const uint8_t *from = encrypted_key_params;
|
||||
|
||||
for (int i = 0; i < NUM_FRAGS; i++) {
|
||||
memcpy((uint8_t *)frags[i].addr, from, frags[i].len);
|
||||
from += frags[i].len;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Begin signing procedure.
|
||||
*/
|
||||
static inline void ds_ll_start_sign(void)
|
||||
{
|
||||
REG_WRITE(DS_SET_ME_REG, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief check the calculated signature.
|
||||
*
|
||||
* @return
|
||||
* - DS_SIGNATURE_OK if no issue is detected with the signature.
|
||||
* - DS_SIGNATURE_PADDING_FAIL if the padding of the private key parameters is wrong.
|
||||
* - DS_SIGNATURE_MD_FAIL if the message digest check failed. This means that the message digest calculated using
|
||||
* the private key parameters fails, i.e., the integrity of the private key parameters is not protected.
|
||||
* - DS_SIGNATURE_PADDING_AND_MD_FAIL if both padding and message digest check fail.
|
||||
*/
|
||||
static inline ds_signature_check_t ds_ll_check_signature(void)
|
||||
{
|
||||
uint32_t result = REG_READ(DS_QUERY_CHECK_REG);
|
||||
switch (result) {
|
||||
case 0:
|
||||
return DS_SIGNATURE_OK;
|
||||
case 1:
|
||||
return DS_SIGNATURE_MD_FAIL;
|
||||
case 2:
|
||||
return DS_SIGNATURE_PADDING_FAIL;
|
||||
default:
|
||||
return DS_SIGNATURE_PADDING_AND_MD_FAIL;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Read the signature from the hardware.
|
||||
*
|
||||
* @param result The signature result.
|
||||
* @param size Length of signature result in bytes. It is the RSA signature length in bytes.
|
||||
*/
|
||||
static inline void ds_ll_read_result(uint8_t *result, size_t size)
|
||||
{
|
||||
memcpy(result, (uint8_t *) DS_Z_BASE, size);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Exit the signature operation.
|
||||
*
|
||||
* @note This does not deactivate the module. Corresponding clock/reset bits have to be triggered for deactivation.
|
||||
*/
|
||||
static inline void ds_ll_finish(void)
|
||||
{
|
||||
REG_WRITE(DS_SET_FINISH_REG, 1);
|
||||
ds_ll_wait_busy();
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
@@ -21,7 +21,7 @@
|
||||
#pragma once
|
||||
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
#error "ESP32 doesn't have a DS peripheral"
|
||||
#error "ESP32 doesn't have a DS peripheral"
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
Reference in New Issue
Block a user