mirror of
https://github.com/espressif/esp-idf.git
synced 2025-08-05 05:34:32 +02:00
Merge branch 'refactor/merge_esp_hmac_headers_into_one' into 'master'
esp_hw_support: Merge HMAC layer into one Closes IDF-3803 See merge request espressif/esp-idf!18742
This commit is contained in:
@@ -18,6 +18,9 @@
|
||||
#if __has_include("esp_dpp.h")
|
||||
#include "esp_dpp.h"
|
||||
#endif
|
||||
#if __has_include("esp_ds_err.h")
|
||||
#include "esp_ds_err.h"
|
||||
#endif
|
||||
#if __has_include("esp_efuse.h")
|
||||
#include "esp_efuse.h"
|
||||
#endif
|
||||
@@ -69,9 +72,6 @@
|
||||
#if __has_include("nvs.h")
|
||||
#include "nvs.h"
|
||||
#endif
|
||||
#if __has_include("soc/esp32s2/esp_ds.h")
|
||||
#include "soc/esp32s2/esp_ds.h"
|
||||
#endif
|
||||
#if __has_include("spi_flash_mmap.h")
|
||||
#include "spi_flash_mmap.h"
|
||||
#endif
|
||||
@@ -767,7 +767,7 @@ static const esp_err_msg_t esp_err_msg_table[] = {
|
||||
ERR_TBL_IT(ESP_ERR_HW_CRYPTO_BASE), /* 49152 0xc000 Starting number of HW cryptography
|
||||
module error codes */
|
||||
# endif
|
||||
// components/esp_hw_support/include/soc/esp32s2/esp_ds.h
|
||||
// components/esp_hw_support/include/esp_ds_err.h
|
||||
# ifdef ESP_ERR_HW_CRYPTO_DS_HMAC_FAIL
|
||||
ERR_TBL_IT(ESP_ERR_HW_CRYPTO_DS_HMAC_FAIL), /* 49153 0xc001 HMAC peripheral problem */
|
||||
# endif
|
||||
|
@@ -45,6 +45,10 @@ if(NOT BOOTLOADER_BUILD)
|
||||
list(APPEND srcs "port/${target}/systimer.c")
|
||||
endif()
|
||||
|
||||
if(CONFIG_SOC_HMAC_SUPPORTED)
|
||||
list(APPEND srcs "esp_hmac.c")
|
||||
endif()
|
||||
|
||||
# ESP32C6-TODO
|
||||
if(CONFIG_IDF_TARGET_ESP32C6)
|
||||
list(REMOVE_ITEM srcs
|
||||
|
@@ -1,41 +1,51 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include "esp_private/periph_ctrl.h"
|
||||
#include "esp32s3/rom/efuse.h"
|
||||
#include "esp32s3/rom/hmac.h"
|
||||
#include "esp32s3/rom/ets_sys.h"
|
||||
#include "rom/efuse.h"
|
||||
#include "rom/hmac.h"
|
||||
#include "rom/ets_sys.h"
|
||||
#include "esp_efuse.h"
|
||||
#include "esp_efuse_table.h"
|
||||
#include "esp_hmac.h"
|
||||
#include "esp_log.h"
|
||||
#include "esp_crypto_lock.h"
|
||||
#include "soc/hwcrypto_reg.h"
|
||||
#include "soc/system_reg.h"
|
||||
|
||||
#if !CONFIG_IDF_TARGET_ESP32S2
|
||||
#include "hal/hmac_hal.h"
|
||||
#include "esp_private/periph_ctrl.h"
|
||||
#endif
|
||||
|
||||
#define SHA256_BLOCK_SZ 64
|
||||
#define SHA256_PAD_SZ 8
|
||||
|
||||
#if defined(CONFIG_IDF_TARGET_ESP32S3) || defined(CONFIG_IDF_TARGET_ESP32S2)
|
||||
#define JTAG_STATUS_BIT ESP_EFUSE_HARD_DIS_JTAG
|
||||
#else
|
||||
/* For ESP32C3, ESP32C6, ESP32H2 */
|
||||
#define JTAG_STATUS_BIT ESP_EFUSE_DIS_PAD_JTAG
|
||||
#endif
|
||||
static const char *TAG = "esp_hmac";
|
||||
|
||||
#if !CONFIG_IDF_TARGET_ESP32S2
|
||||
/**
|
||||
* @brief Apply the HMAC padding without the embedded length.
|
||||
*
|
||||
* @note This function does not check the data length, it is the responsibility of the other functions in this
|
||||
* module to make sure that \c data_len is at most SHA256_BLOCK_SZ - 1 so the padding fits in.
|
||||
* Otherwise, this function has undefined behavior.
|
||||
* Note however, that for the actual HMAC implementation on ESP32S3, the length also needs to be applied at the end
|
||||
* Note however, that for the actual HMAC implementation, the length also needs to be applied at the end
|
||||
* of the block. This function alone deosn't do that.
|
||||
*/
|
||||
static void write_and_padd(uint8_t *block, const uint8_t *data, uint16_t data_len)
|
||||
{
|
||||
memcpy(block, data, data_len);
|
||||
// Apply a one bit, followed by zero bits (refer to the ESP32S3 TRM).
|
||||
// Apply a one bit, followed by zero bits (refer to the TRM of respective target).
|
||||
block[data_len] = 0x80;
|
||||
bzero(block + data_len + 1, SHA256_BLOCK_SZ - data_len - 1);
|
||||
}
|
||||
@@ -143,7 +153,7 @@ esp_err_t esp_hmac_jtag_enable(hmac_key_id_t key_id, const uint8_t *token)
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
|
||||
/* Check if JTAG is permanently disabled by HW Disable eFuse */
|
||||
if (esp_efuse_read_field_bit(ESP_EFUSE_HARD_DIS_JTAG)) {
|
||||
if (esp_efuse_read_field_bit(JTAG_STATUS_BIT)) {
|
||||
ESP_LOGE(TAG, "JTAG disabled permanently.");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
@@ -170,12 +180,94 @@ esp_err_t esp_hmac_jtag_enable(hmac_key_id_t key_id, const uint8_t *token)
|
||||
esp_err_t esp_hmac_jtag_disable()
|
||||
{
|
||||
esp_crypto_hmac_lock_acquire();
|
||||
|
||||
REG_SET_BIT(HMAC_SET_INVALIDATE_JTAG_REG, HMAC_INVALIDATE_JTAG);
|
||||
|
||||
REG_WRITE(HMAC_SET_INVALIDATE_JTAG_REG, 1);
|
||||
esp_crypto_hmac_lock_release();
|
||||
|
||||
ESP_LOGD(TAG, "Invalidate JTAG result register. JTAG disabled.");
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
#else /* !CONFIG_IDF_TARGET_ESP32S2 */
|
||||
|
||||
static ets_efuse_block_t convert_key_type(hmac_key_id_t key_id) {
|
||||
return ETS_EFUSE_BLOCK_KEY0 + (ets_efuse_block_t) key_id;
|
||||
}
|
||||
|
||||
esp_err_t esp_hmac_calculate(hmac_key_id_t key_id,
|
||||
const void *message,
|
||||
size_t message_len,
|
||||
uint8_t *hmac)
|
||||
{
|
||||
int hmac_ret;
|
||||
if (!message || !hmac) return ESP_ERR_INVALID_ARG;
|
||||
if (key_id >= HMAC_KEY_MAX) return ESP_ERR_INVALID_ARG;
|
||||
|
||||
esp_crypto_dma_lock_acquire();
|
||||
|
||||
ets_hmac_enable();
|
||||
hmac_ret = ets_hmac_calculate_message(convert_key_type(key_id), message, message_len, hmac);
|
||||
ets_hmac_disable();
|
||||
|
||||
esp_crypto_dma_lock_release();
|
||||
|
||||
if (hmac_ret != 0) {
|
||||
return ESP_FAIL;
|
||||
} else {
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
esp_err_t esp_hmac_jtag_enable(hmac_key_id_t key_id, const uint8_t *token)
|
||||
{
|
||||
int ets_status;
|
||||
esp_err_t err = ESP_OK;
|
||||
|
||||
if ((!token) || (key_id >= HMAC_KEY_MAX))
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
|
||||
/* Check if JTAG is permanently disabled by HW Disable eFuse */
|
||||
if (esp_efuse_read_field_bit(ESP_EFUSE_HARD_DIS_JTAG)) {
|
||||
ESP_LOGE(TAG, "JTAG disabled permanently.");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
esp_crypto_dma_lock_acquire();
|
||||
|
||||
ets_hmac_enable();
|
||||
|
||||
/* Token updating into HMAC module. */
|
||||
for (int i = 0; i < 32; i += 4) {
|
||||
uint32_t key_word;
|
||||
memcpy(&key_word, &token[i], 4);
|
||||
REG_WRITE(DPORT_JTAG_CTRL_0_REG + i, __builtin_bswap32(key_word));
|
||||
}
|
||||
|
||||
ets_status = ets_hmac_calculate_downstream(convert_key_type(key_id), ETS_EFUSE_KEY_PURPOSE_HMAC_DOWN_JTAG);
|
||||
if (ets_status != ETS_OK) {
|
||||
err = ESP_FAIL;
|
||||
ESP_LOGE(TAG, "HMAC downstream JTAG enable mode setting failed. (%d)", err);
|
||||
}
|
||||
|
||||
ESP_LOGD(TAG, "HMAC computation in downstream mode is completed.");
|
||||
|
||||
ets_hmac_disable();
|
||||
|
||||
esp_crypto_dma_lock_release();
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
esp_err_t esp_hmac_jtag_disable()
|
||||
{
|
||||
esp_crypto_dma_lock_acquire();
|
||||
|
||||
REG_WRITE(HMAC_SET_INVALIDATE_JTAG_REG, 1);
|
||||
|
||||
esp_crypto_dma_lock_release();
|
||||
|
||||
ESP_LOGD(TAG, "Invalidate JTAG result register. JTAG disabled.");
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
#endif /* CONFIG_IDF_TARGET_ESP32S2*/
|
24
components/esp_hw_support/include/esp_ds_err.h
Normal file
24
components/esp_hw_support/include/esp_ds_err.h
Normal file
@@ -0,0 +1,24 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2020-2021 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define ESP_ERR_HW_CRYPTO_DS_HMAC_FAIL (ESP_ERR_HW_CRYPTO_BASE + 0x1) /*!< HMAC peripheral problem */
|
||||
#define ESP_ERR_HW_CRYPTO_DS_INVALID_KEY (ESP_ERR_HW_CRYPTO_BASE + 0x2) /*!< given HMAC key isn't correct,
|
||||
HMAC peripheral problem */
|
||||
#define ESP_ERR_HW_CRYPTO_DS_INVALID_DIGEST (ESP_ERR_HW_CRYPTO_BASE + 0x4) /*!< message digest check failed,
|
||||
result is invalid */
|
||||
#define ESP_ERR_HW_CRYPTO_DS_INVALID_PADDING (ESP_ERR_HW_CRYPTO_BASE + 0x5) /*!< padding check failed, but result
|
||||
is produced anyway and can be read*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
@@ -4,11 +4,15 @@
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#ifndef _ESP_HMAC_H_
|
||||
#define _ESP_HMAC_H_
|
||||
#pragma once
|
||||
|
||||
#include <stdbool.h>
|
||||
#include "esp_err.h"
|
||||
#include "soc/soc_caps.h"
|
||||
|
||||
#if !SOC_HMAC_SUPPORTED && !CI_HEADER_CHECK
|
||||
#error "HMAC peripheral is not supported for the selected target"
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@@ -32,7 +36,7 @@ typedef enum {
|
||||
* Calculate the HMAC of a given message.
|
||||
*
|
||||
* Calculate the HMAC \c hmac of a given message \c message with length \c message_len.
|
||||
* SHA256 is used for the calculation (fixed on ESP32S2).
|
||||
* SHA256 is used for the calculation.
|
||||
*
|
||||
* @note Uses the HMAC peripheral in "upstream" mode.
|
||||
*
|
||||
@@ -40,7 +44,7 @@ typedef enum {
|
||||
* The corresponding purpose field of the key block in the efuse must be set to the HMAC upstream purpose value.
|
||||
* @param message the message for which to calculate the HMAC
|
||||
* @param message_len message length
|
||||
* return ESP_ERR_INVALID_STATE if unsuccessful
|
||||
* return ESP_ERR_INVALID_STATE if unsuccessful
|
||||
* @param [out] hmac the hmac result; the buffer behind the provided pointer must be a writeable buffer of 32 bytes
|
||||
*
|
||||
* @return
|
||||
@@ -49,9 +53,9 @@ typedef enum {
|
||||
* * ESP_FAIL, if the hmac calculation failed
|
||||
*/
|
||||
esp_err_t esp_hmac_calculate(hmac_key_id_t key_id,
|
||||
const void *message,
|
||||
size_t message_len,
|
||||
uint8_t *hmac);
|
||||
const void *message,
|
||||
size_t message_len,
|
||||
uint8_t *hmac);
|
||||
|
||||
/**
|
||||
* @brief Use HMAC peripheral in Downstream mode to re-enable the JTAG, if it is not permanently disabled by HW.
|
||||
@@ -88,5 +92,3 @@ esp_err_t esp_hmac_jtag_disable(void);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // _ESP_HMAC_H_
|
@@ -8,19 +8,12 @@
|
||||
|
||||
#include "esp_hmac.h"
|
||||
#include "esp_err.h"
|
||||
#include "esp_ds_err.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define ESP32C3_ERR_HW_CRYPTO_DS_HMAC_FAIL ESP_ERR_HW_CRYPTO_BASE + 0x1 /*!< HMAC peripheral problem */
|
||||
#define ESP32C3_ERR_HW_CRYPTO_DS_INVALID_KEY ESP_ERR_HW_CRYPTO_BASE + 0x2 /*!< given HMAC key isn't correct,
|
||||
HMAC peripheral problem */
|
||||
#define ESP32C3_ERR_HW_CRYPTO_DS_INVALID_DIGEST ESP_ERR_HW_CRYPTO_BASE + 0x4 /*!< message digest check failed,
|
||||
result is invalid */
|
||||
#define ESP32C3_ERR_HW_CRYPTO_DS_INVALID_PADDING ESP_ERR_HW_CRYPTO_BASE + 0x5 /*!< padding check failed, but result
|
||||
is produced anyway and can be read*/
|
||||
|
||||
#define ESP_DS_IV_BIT_LEN 128
|
||||
#define ESP_DS_IV_LEN (ESP_DS_IV_BIT_LEN / 8)
|
||||
#define ESP_DS_SIGNATURE_MAX_BIT_LEN 3072
|
||||
|
@@ -8,19 +8,12 @@
|
||||
|
||||
#include "esp_hmac.h"
|
||||
#include "esp_err.h"
|
||||
#include "esp_ds_err.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define ESP32C6_ERR_HW_CRYPTO_DS_HMAC_FAIL ESP_ERR_HW_CRYPTO_BASE + 0x1 /*!< HMAC peripheral problem */
|
||||
#define ESP32C6_ERR_HW_CRYPTO_DS_INVALID_KEY ESP_ERR_HW_CRYPTO_BASE + 0x2 /*!< given HMAC key isn't correct,
|
||||
HMAC peripheral problem */
|
||||
#define ESP32C6_ERR_HW_CRYPTO_DS_INVALID_DIGEST ESP_ERR_HW_CRYPTO_BASE + 0x4 /*!< message digest check failed,
|
||||
result is invalid */
|
||||
#define ESP32C6_ERR_HW_CRYPTO_DS_INVALID_PADDING ESP_ERR_HW_CRYPTO_BASE + 0x5 /*!< padding check failed, but result
|
||||
is produced anyway and can be read*/
|
||||
|
||||
#define ESP_DS_IV_BIT_LEN 128
|
||||
#define ESP_DS_IV_LEN (ESP_DS_IV_BIT_LEN / 8)
|
||||
#define ESP_DS_SIGNATURE_MAX_BIT_LEN 3072
|
||||
|
@@ -1,92 +0,0 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#ifndef _ESP_HMAC_H_
|
||||
#define _ESP_HMAC_H_
|
||||
|
||||
#include <stdbool.h>
|
||||
#include "esp_err.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* The possible efuse keys for the HMAC peripheral
|
||||
*/
|
||||
typedef enum {
|
||||
HMAC_KEY0 = 0,
|
||||
HMAC_KEY1,
|
||||
HMAC_KEY2,
|
||||
HMAC_KEY3,
|
||||
HMAC_KEY4,
|
||||
HMAC_KEY5,
|
||||
HMAC_KEY_MAX
|
||||
} hmac_key_id_t;
|
||||
|
||||
/**
|
||||
* @brief
|
||||
* Calculate the HMAC of a given message.
|
||||
*
|
||||
* Calculate the HMAC \c hmac of a given message \c message with length \c message_len.
|
||||
* SHA256 is used for the calculation (fixed on ESP32S2).
|
||||
*
|
||||
* @note Uses the HMAC peripheral in "upstream" mode.
|
||||
*
|
||||
* @param key_id Determines which of the 6 key blocks in the efuses should be used for the HMAC calcuation.
|
||||
* The corresponding purpose field of the key block in the efuse must be set to the HMAC upstream purpose value.
|
||||
* @param message the message for which to calculate the HMAC
|
||||
* @param message_len message length
|
||||
* return ESP_ERR_INVALID_STATE if unsuccessful
|
||||
* @param [out] hmac the hmac result; the buffer behind the provided pointer must be a writeable buffer of 32 bytes
|
||||
*
|
||||
* @return
|
||||
* * ESP_OK, if the calculation was successful,
|
||||
* * ESP_ERR_INVALID_ARG if message or hmac is a nullptr or if key_id out of range
|
||||
* * ESP_FAIL, if the hmac calculation failed
|
||||
*/
|
||||
esp_err_t esp_hmac_calculate(hmac_key_id_t key_id,
|
||||
const void *message,
|
||||
size_t message_len,
|
||||
uint8_t *hmac);
|
||||
|
||||
/**
|
||||
* @brief Use HMAC peripheral in Downstream mode to re-enable the JTAG, if it is not permanently disabled by HW.
|
||||
* In downstream mode, HMAC calculations performed by peripheral are used internally and not provided back to user.
|
||||
*
|
||||
* @param key_id Determines which of the 6 key blocks in the efuses should be used for the HMAC calculation.
|
||||
* The corresponding purpose field of the key block in the efuse must be set to HMAC downstream purpose.
|
||||
*
|
||||
* @param token Pre calculated HMAC value of the 32-byte 0x00 using SHA-256 and the known private HMAC key. The key is already
|
||||
* programmed to a eFuse key block. The key block number is provided as the first parameter to this function.
|
||||
*
|
||||
* @return
|
||||
* * ESP_OK, if the key_purpose of the key_id matches to HMAC downstread mode,
|
||||
* The API returns success even if calculated HMAC does not match with the provided token.
|
||||
* However, The JTAG will be re-enabled only if the calculated HMAC value matches with provided token,
|
||||
* otherwise JTAG will remain disabled.
|
||||
* * ESP_FAIL, if the key_purpose of the key_id is not set to HMAC downstream purpose
|
||||
* or JTAG is permanently disabled by EFUSE_HARD_DIS_JTAG eFuse parameter.
|
||||
* * ESP_ERR_INVALID_ARG, invalid input arguments
|
||||
*
|
||||
* @note Return value of the API does not indicate the JTAG status.
|
||||
*/
|
||||
esp_err_t esp_hmac_jtag_enable(hmac_key_id_t key_id, const uint8_t *token);
|
||||
|
||||
/**
|
||||
* @brief Disable the JTAG which might be enabled using the HMAC downstream mode. This function just clears the result generated
|
||||
* by calling esp_hmac_jtag_enable() API.
|
||||
*
|
||||
* @return
|
||||
* * ESP_OK return ESP_OK after writing the HMAC_SET_INVALIDATE_JTAG_REG with value 1.
|
||||
*/
|
||||
esp_err_t esp_hmac_jtag_disable(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // _ESP_HMAC_H_
|
@@ -8,18 +8,12 @@
|
||||
|
||||
#include "esp_hmac.h"
|
||||
#include "esp_err.h"
|
||||
#include "esp_ds_err.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define ESP32H2_ERR_HW_CRYPTO_DS_HMAC_FAIL ESP_ERR_HW_CRYPTO_BASE + 0x1 /*!< HMAC peripheral problem */
|
||||
#define ESP32H2_ERR_HW_CRYPTO_DS_INVALID_KEY ESP_ERR_HW_CRYPTO_BASE + 0x2 /*!< given HMAC key isn't correct,
|
||||
HMAC peripheral problem */
|
||||
#define ESP32H2_ERR_HW_CRYPTO_DS_INVALID_DIGEST ESP_ERR_HW_CRYPTO_BASE + 0x4 /*!< message digest check failed,
|
||||
result is invalid */
|
||||
#define ESP32H2_ERR_HW_CRYPTO_DS_INVALID_PADDING ESP_ERR_HW_CRYPTO_BASE + 0x5 /*!< padding check failed, but result
|
||||
is produced anyway and can be read*/
|
||||
|
||||
#define ESP_DS_IV_BIT_LEN 128
|
||||
#define ESP_DS_IV_LEN (ESP_DS_IV_BIT_LEN / 8)
|
||||
|
@@ -1,92 +0,0 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#ifndef _ESP_HMAC_H_
|
||||
#define _ESP_HMAC_H_
|
||||
|
||||
#include <stdbool.h>
|
||||
#include "esp_err.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* The possible efuse keys for the HMAC peripheral
|
||||
*/
|
||||
typedef enum {
|
||||
HMAC_KEY0 = 0,
|
||||
HMAC_KEY1,
|
||||
HMAC_KEY2,
|
||||
HMAC_KEY3,
|
||||
HMAC_KEY4,
|
||||
HMAC_KEY5,
|
||||
HMAC_KEY_MAX
|
||||
} hmac_key_id_t;
|
||||
|
||||
/**
|
||||
* @brief
|
||||
* Calculate the HMAC of a given message.
|
||||
*
|
||||
* Calculate the HMAC \c hmac of a given message \c message with length \c message_len.
|
||||
* SHA256 is used for the calculation (fixed on ESP32S2).
|
||||
*
|
||||
* @note Uses the HMAC peripheral in "upstream" mode.
|
||||
*
|
||||
* @param key_id Determines which of the 6 key blocks in the efuses should be used for the HMAC calcuation.
|
||||
* The corresponding purpose field of the key block in the efuse must be set to the HMAC upstream purpose value.
|
||||
* @param message the message for which to calculate the HMAC
|
||||
* @param message_len message length
|
||||
* return ESP_ERR_INVALID_STATE if unsuccessful
|
||||
* @param [out] hmac the hmac result; the buffer behind the provided pointer must be a writeable buffer of 32 bytes
|
||||
*
|
||||
* @return
|
||||
* * ESP_OK, if the calculation was successful,
|
||||
* * ESP_ERR_INVALID_ARG if message or hmac is a nullptr or if key_id out of range
|
||||
* * ESP_FAIL, if the hmac calculation failed
|
||||
*/
|
||||
esp_err_t esp_hmac_calculate(hmac_key_id_t key_id,
|
||||
const void *message,
|
||||
size_t message_len,
|
||||
uint8_t *hmac);
|
||||
|
||||
/**
|
||||
* @brief Use HMAC peripheral in Downstream mode to re-enable the JTAG, if it is not permanently disabled by HW.
|
||||
* In downstream mode, HMAC calculations performed by peripheral are used internally and not provided back to user.
|
||||
*
|
||||
* @param key_id Determines which of the 6 key blocks in the efuses should be used for the HMAC calculation.
|
||||
* The corresponding purpose field of the key block in the efuse must be set to HMAC downstream purpose.
|
||||
*
|
||||
* @param token Pre calculated HMAC value of the 32-byte 0x00 using SHA-256 and the known private HMAC key. The key is already
|
||||
* programmed to a eFuse key block. The key block number is provided as the first parameter to this function.
|
||||
*
|
||||
* @return
|
||||
* * ESP_OK, if the key_purpose of the key_id matches to HMAC downstread mode,
|
||||
* The API returns success even if calculated HMAC does not match with the provided token.
|
||||
* However, The JTAG will be re-enabled only if the calculated HMAC value matches with provided token,
|
||||
* otherwise JTAG will remain disabled.
|
||||
* * ESP_FAIL, if the key_purpose of the key_id is not set to HMAC downstream purpose
|
||||
* or JTAG is permanently disabled by EFUSE_HARD_DIS_JTAG eFuse parameter.
|
||||
* * ESP_ERR_INVALID_ARG, invalid input arguments
|
||||
*
|
||||
* @note Return value of the API does not indicate the JTAG status.
|
||||
*/
|
||||
esp_err_t esp_hmac_jtag_enable(hmac_key_id_t key_id, const uint8_t *token);
|
||||
|
||||
/**
|
||||
* @brief Disable the JTAG which might be enabled using the HMAC downstream mode. This function just clears the result generated
|
||||
* by calling esp_hmac_jtag_enable() API.
|
||||
*
|
||||
* @return
|
||||
* * ESP_OK return ESP_OK after writing the HMAC_SET_INVALIDATE_JTAG_REG with value 1.
|
||||
*/
|
||||
esp_err_t esp_hmac_jtag_disable(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // _ESP_HMAC_H_
|
@@ -8,19 +8,12 @@
|
||||
|
||||
#include "esp_hmac.h"
|
||||
#include "esp_err.h"
|
||||
#include "esp_ds_err.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define ESP_ERR_HW_CRYPTO_DS_HMAC_FAIL ESP_ERR_HW_CRYPTO_BASE + 0x1 /*!< HMAC peripheral problem */
|
||||
#define ESP_ERR_HW_CRYPTO_DS_INVALID_KEY ESP_ERR_HW_CRYPTO_BASE + 0x2 /*!< given HMAC key isn't correct,
|
||||
HMAC peripheral problem */
|
||||
#define ESP_ERR_HW_CRYPTO_DS_INVALID_DIGEST ESP_ERR_HW_CRYPTO_BASE + 0x4 /*!< message digest check failed,
|
||||
result is invalid */
|
||||
#define ESP_ERR_HW_CRYPTO_DS_INVALID_PADDING ESP_ERR_HW_CRYPTO_BASE + 0x5 /*!< padding check failed, but result
|
||||
is produced anyway and can be read*/
|
||||
|
||||
#define ESP_DS_IV_LEN 16
|
||||
|
||||
/* Length of parameter 'C' stored in flash */
|
||||
|
@@ -1,95 +0,0 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#ifndef _ESP_HMAC_H_
|
||||
#define _ESP_HMAC_H_
|
||||
|
||||
#include "esp_err.h"
|
||||
#include "stdbool.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* The possible efuse keys for the HMAC peripheral
|
||||
*/
|
||||
typedef enum {
|
||||
HMAC_KEY0 = 0,
|
||||
HMAC_KEY1,
|
||||
HMAC_KEY2,
|
||||
HMAC_KEY3,
|
||||
HMAC_KEY4,
|
||||
HMAC_KEY5,
|
||||
HMAC_KEY_MAX
|
||||
} hmac_key_id_t;
|
||||
|
||||
/**
|
||||
* @brief
|
||||
* Calculate the HMAC of a given message.
|
||||
*
|
||||
* Calculate the HMAC \c hmac of a given message \c message with length \c message_len.
|
||||
* SHA256 is used for the calculation (fixed on ESP32S2).
|
||||
*
|
||||
* @note Uses the HMAC peripheral in "upstream" mode.
|
||||
*
|
||||
* @param key_id Determines which of the 6 key blocks in the efuses should be used for the HMAC calcuation.
|
||||
* The corresponding purpose field of the key block in the efuse must be set to the HMAC upstream purpose value.
|
||||
* @param message the message for which to calculate the HMAC
|
||||
* @param message_len message length
|
||||
* return ESP_ERR_INVALID_STATE if unsuccessful
|
||||
* @param [out] hmac the hmac result; the buffer behind the provided pointer must be a writeable buffer of 32 bytes
|
||||
*
|
||||
* @return
|
||||
* * ESP_OK, if the calculation was successful,
|
||||
* * ESP_ERR_INVALID_ARG if message or hmac is a nullptr or if key_id out of range
|
||||
* * ESP_FAIL, if the hmac calculation failed
|
||||
*/
|
||||
esp_err_t esp_hmac_calculate(hmac_key_id_t key_id,
|
||||
const void *message,
|
||||
size_t message_len,
|
||||
uint8_t *hmac);
|
||||
|
||||
/**
|
||||
* @brief
|
||||
* Use HMAC peripheral in Downstream mode to re-enable the JTAG, if it is not permanently disable by HW.
|
||||
* In downstream mode HMAC calculations perfomred by peripheral used internally and not provided back to user.
|
||||
*
|
||||
* @param key_id Determines which of the 6 key blocks in the efuses should be used for the HMAC calculation.
|
||||
* The corresponding purpose field of the key block in the efuse must be set to HMAC downstream purpose.
|
||||
*
|
||||
* @param token Pre calculated HMAC value of the 32-byte 0x00 using SHA-256 and the known private HMAC key. The key is already
|
||||
* programmed to a eFuse key block. The key block number is provided as the first parameter to this function.
|
||||
*
|
||||
* @return
|
||||
* * ESP_OK, if the key_purpose of the key_id matches to HMAC downstread mode,
|
||||
* The API returns success even if calculated HMAC does not match with the provided token.
|
||||
* However, The JTAG will be re-enabled only if the calculated HMAC value matches with provided token,
|
||||
* otherwise JTAG will remain disabled.
|
||||
* * ESP_FAIL, if the key_purpose of the key_id is not set to HMAC downstream purpose
|
||||
* or JTAG is permanently disabled by EFUSE_HARD_DIS_JTAG eFuse parameter.
|
||||
* * ESP_ERR_INVALID_ARG, invalid input arguments
|
||||
*
|
||||
* @note Return value of the API does not indicate the JTAG status.
|
||||
*/
|
||||
esp_err_t esp_hmac_jtag_enable(hmac_key_id_t key_id,
|
||||
const uint8_t *token);
|
||||
|
||||
/**
|
||||
* @brief
|
||||
* Disable the JTAG which might be enable using the HMAC downstream mode. This function just clear the result generated by
|
||||
* JTAG key by calling esp_hmac_jtag_enable() API.
|
||||
*
|
||||
* @return
|
||||
* * ESP_OK return ESP_OK after writing the HMAC_SET_INVALIDATE_JTAG_REG with value 1.
|
||||
*/
|
||||
esp_err_t esp_hmac_jtag_disable(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // _ESP_HMAC_H_
|
@@ -10,19 +10,12 @@
|
||||
#include "esp_hmac.h"
|
||||
#include "esp_err.h"
|
||||
#include "soc/soc_caps.h"
|
||||
#include "esp_ds_err.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define ESP32S3_ERR_HW_CRYPTO_DS_HMAC_FAIL ESP_ERR_HW_CRYPTO_BASE + 0x1 /*!< HMAC peripheral problem */
|
||||
#define ESP32S3_ERR_HW_CRYPTO_DS_INVALID_KEY ESP_ERR_HW_CRYPTO_BASE + 0x2 /*!< given HMAC key isn't correct,
|
||||
HMAC peripheral problem */
|
||||
#define ESP32S3_ERR_HW_CRYPTO_DS_INVALID_DIGEST ESP_ERR_HW_CRYPTO_BASE + 0x4 /*!< message digest check failed,
|
||||
result is invalid */
|
||||
#define ESP32S3_ERR_HW_CRYPTO_DS_INVALID_PADDING ESP_ERR_HW_CRYPTO_BASE + 0x5 /*!< padding check failed, but result
|
||||
is produced anyway and can be read*/
|
||||
|
||||
#define ESP_DS_IV_LEN 16
|
||||
|
||||
/* Length of parameter 'C' stored in flash */
|
||||
|
@@ -1,87 +0,0 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "esp_err.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* The possible efuse keys for the HMAC peripheral
|
||||
*/
|
||||
typedef enum {
|
||||
HMAC_KEY0 = 0,
|
||||
HMAC_KEY1,
|
||||
HMAC_KEY2,
|
||||
HMAC_KEY3,
|
||||
HMAC_KEY4,
|
||||
HMAC_KEY5,
|
||||
HMAC_KEY_MAX
|
||||
} hmac_key_id_t;
|
||||
|
||||
/**
|
||||
* @brief
|
||||
* Calculate the HMAC of a given message.
|
||||
*
|
||||
* Calculate the HMAC \c hmac of a given message \c message with length \c message_len.
|
||||
* SHA256 is used for the calculation (fixed on ESP32S3).
|
||||
*
|
||||
* @note Uses the HMAC peripheral in "upstream" mode.
|
||||
*
|
||||
* @param key_id Determines which of the 6 key blocks in the efuses should be used for the HMAC calcuation.
|
||||
* The corresponding purpose field of the key block in the efuse must be set to the HMAC upstream purpose value.
|
||||
* @param message the message for which to calculate the HMAC
|
||||
* @param message_len message length
|
||||
* @param [out] hmac the hmac result; the buffer behind the provided pointer must be a writeable buffer of 32 bytes
|
||||
*
|
||||
* @return
|
||||
* * ESP_OK, if the calculation was successful,
|
||||
* * ESP_ERR_INVALID_ARG if message or hmac is a nullptr or if key_id out of range
|
||||
* * ESP_FAIL, if the hmac calculation failed
|
||||
*/
|
||||
esp_err_t esp_hmac_calculate(hmac_key_id_t key_id,
|
||||
const void *message,
|
||||
size_t message_len,
|
||||
uint8_t *hmac);
|
||||
|
||||
/**
|
||||
* @brief Use HMAC peripheral in Downstream mode to re-enable the JTAG, if it is not permanently disabled by HW.
|
||||
* In downstream mode, HMAC calculations performed by peripheral are used internally and not provided back to user.
|
||||
*
|
||||
* @param key_id Determines which of the 6 key blocks in the efuses should be used for the HMAC calculation.
|
||||
* The corresponding purpose field of the key block in the efuse must be set to HMAC downstream purpose.
|
||||
*
|
||||
* @param token Pre calculated HMAC value of the 32-byte 0x00 using SHA-256 and the known private HMAC key. The key is already
|
||||
* programmed to a eFuse key block. The key block number is provided as the first parameter to this function.
|
||||
*
|
||||
* @return
|
||||
* * ESP_OK, if the key_purpose of the key_id matches to HMAC downstread mode,
|
||||
* The API returns success even if calculated HMAC does not match with the provided token.
|
||||
* However, The JTAG will be re-enabled only if the calculated HMAC value matches with provided token,
|
||||
* otherwise JTAG will remain disabled.
|
||||
* * ESP_FAIL, if the key_purpose of the key_id is not set to HMAC downstream purpose
|
||||
* or JTAG is permanently disabled by EFUSE_HARD_DIS_JTAG eFuse parameter.
|
||||
* * ESP_ERR_INVALID_ARG, invalid input arguments
|
||||
*
|
||||
* @note Return value of the API does not indicate the JTAG status.
|
||||
*/
|
||||
esp_err_t esp_hmac_jtag_enable(hmac_key_id_t key_id, const uint8_t *token);
|
||||
|
||||
/**
|
||||
* @brief Disable the JTAG which might be enabled using the HMAC downstream mode. This function just clears the result generated
|
||||
* by calling esp_hmac_jtag_enable() API.
|
||||
*
|
||||
* @return
|
||||
* * ESP_OK return ESP_OK after writing the HMAC_SET_INVALIDATE_JTAG_REG with value 1.
|
||||
*/
|
||||
esp_err_t esp_hmac_jtag_disable(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
@@ -8,8 +8,7 @@ set(srcs "rtc_clk_init.c"
|
||||
)
|
||||
|
||||
if(NOT BOOTLOADER_BUILD)
|
||||
list(APPEND srcs "esp_hmac.c"
|
||||
"esp_crypto_lock.c"
|
||||
list(APPEND srcs "esp_crypto_lock.c"
|
||||
"esp_ds.c")
|
||||
|
||||
# init constructor for wifi
|
||||
|
@@ -115,7 +115,7 @@ esp_err_t esp_ds_start_sign(const void *message,
|
||||
uint32_t conf_error = hmac_hal_configure(HMAC_OUTPUT_DS, key_id);
|
||||
if (conf_error) {
|
||||
ds_disable_release();
|
||||
return ESP32C3_ERR_HW_CRYPTO_DS_HMAC_FAIL;
|
||||
return ESP_ERR_HW_CRYPTO_DS_HMAC_FAIL;
|
||||
}
|
||||
|
||||
ds_hal_start();
|
||||
@@ -125,7 +125,7 @@ esp_err_t esp_ds_start_sign(const void *message,
|
||||
while (ds_ll_busy() != 0) {
|
||||
if ((esp_timer_get_time() - start_time) > SOC_DS_KEY_CHECK_MAX_WAIT_US) {
|
||||
ds_disable_release();
|
||||
return ESP32C3_ERR_HW_CRYPTO_DS_INVALID_KEY;
|
||||
return ESP_ERR_HW_CRYPTO_DS_INVALID_KEY;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -170,11 +170,11 @@ esp_err_t esp_ds_finish_sign(void *signature, esp_ds_context_t *esp_ds_ctx)
|
||||
esp_err_t return_value = ESP_OK;
|
||||
|
||||
if (sig_check_result == DS_SIGNATURE_MD_FAIL || sig_check_result == DS_SIGNATURE_PADDING_AND_MD_FAIL) {
|
||||
return_value = ESP32C3_ERR_HW_CRYPTO_DS_INVALID_DIGEST;
|
||||
return_value = ESP_ERR_HW_CRYPTO_DS_INVALID_DIGEST;
|
||||
}
|
||||
|
||||
if (sig_check_result == DS_SIGNATURE_PADDING_FAIL) {
|
||||
return_value = ESP32C3_ERR_HW_CRYPTO_DS_INVALID_PADDING;
|
||||
return_value = ESP_ERR_HW_CRYPTO_DS_INVALID_PADDING;
|
||||
}
|
||||
|
||||
free(esp_ds_ctx);
|
||||
|
@@ -1,180 +0,0 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include "esp_private/periph_ctrl.h"
|
||||
#include "esp32c3/rom/hmac.h"
|
||||
#include "esp32c3/rom/ets_sys.h"
|
||||
#include "esp_efuse.h"
|
||||
#include "esp_efuse_table.h"
|
||||
#include "esp_hmac.h"
|
||||
#include "esp_log.h"
|
||||
#include "esp_crypto_lock.h"
|
||||
#include "soc/hwcrypto_reg.h"
|
||||
|
||||
#include "hal/hmac_hal.h"
|
||||
|
||||
#define SHA256_BLOCK_SZ 64
|
||||
#define SHA256_PAD_SZ 8
|
||||
|
||||
static const char *TAG = "esp_hmac";
|
||||
|
||||
/**
|
||||
* @brief Apply the HMAC padding without the embedded length.
|
||||
*
|
||||
* @note This function does not check the data length, it is the responsibility of the other functions in this
|
||||
* module to make sure that \c data_len is at most SHA256_BLOCK_SZ - 1 so the padding fits in.
|
||||
* Otherwise, this function has undefined behavior.
|
||||
* Note however, that for the actual HMAC implementation on ESP32C3, the length also needs to be applied at the end
|
||||
* of the block. This function alone deosn't do that.
|
||||
*/
|
||||
static void write_and_padd(uint8_t *block, const uint8_t *data, uint16_t data_len)
|
||||
{
|
||||
memcpy(block, data, data_len);
|
||||
// Apply a one bit, followed by zero bits (refer to the ESP32C3 TRM).
|
||||
block[data_len] = 0x80;
|
||||
bzero(block + data_len + 1, SHA256_BLOCK_SZ - data_len - 1);
|
||||
}
|
||||
|
||||
esp_err_t esp_hmac_calculate(hmac_key_id_t key_id,
|
||||
const void *message,
|
||||
size_t message_len,
|
||||
uint8_t *hmac)
|
||||
{
|
||||
const uint8_t *message_bytes = (const uint8_t *)message;
|
||||
|
||||
if (!message || !hmac) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
if (key_id >= HMAC_KEY_MAX) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
esp_crypto_hmac_lock_acquire();
|
||||
|
||||
// We also enable SHA and DS here. SHA is used by HMAC, DS will otherwise hold SHA in reset state.
|
||||
periph_module_enable(PERIPH_HMAC_MODULE);
|
||||
periph_module_enable(PERIPH_SHA_MODULE);
|
||||
periph_module_enable(PERIPH_DS_MODULE);
|
||||
|
||||
hmac_hal_start();
|
||||
|
||||
uint32_t conf_error = hmac_hal_configure(HMAC_OUTPUT_USER, key_id);
|
||||
if (conf_error) {
|
||||
esp_crypto_hmac_lock_release();
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
if (message_len + 1 + SHA256_PAD_SZ <= SHA256_BLOCK_SZ) {
|
||||
// If message including padding is only one block...
|
||||
// Last message block, so apply SHA-256 padding rules in software
|
||||
uint8_t block[SHA256_BLOCK_SZ];
|
||||
uint64_t bit_len = __builtin_bswap64(message_len * 8 + 512);
|
||||
|
||||
write_and_padd(block, message_bytes, message_len);
|
||||
// Final block: append the bit length in this block and signal padding to peripheral
|
||||
memcpy(block + SHA256_BLOCK_SZ - sizeof(bit_len),
|
||||
&bit_len, sizeof(bit_len));
|
||||
hmac_hal_write_one_block_512(block);
|
||||
} else {
|
||||
// If message including padding is needs more than one block
|
||||
|
||||
// write all blocks without padding except the last one
|
||||
size_t remaining_blocks = message_len / SHA256_BLOCK_SZ;
|
||||
for (int i = 1; i < remaining_blocks; i++) {
|
||||
hmac_hal_write_block_512(message_bytes);
|
||||
message_bytes += SHA256_BLOCK_SZ;
|
||||
hmac_hal_next_block_normal();
|
||||
}
|
||||
|
||||
// If message fits into one block but without padding, we must not write another block.
|
||||
if (remaining_blocks) {
|
||||
hmac_hal_write_block_512(message_bytes);
|
||||
message_bytes += SHA256_BLOCK_SZ;
|
||||
}
|
||||
|
||||
size_t remaining = message_len % SHA256_BLOCK_SZ;
|
||||
// Last message block, so apply SHA-256 padding rules in software
|
||||
uint8_t block[SHA256_BLOCK_SZ];
|
||||
uint64_t bit_len = __builtin_bswap64(message_len * 8 + 512);
|
||||
|
||||
// If the remaining message and appended padding doesn't fit into a single block, we have to write an
|
||||
// extra block with the rest of the message and potential padding first.
|
||||
if (remaining >= SHA256_BLOCK_SZ - SHA256_PAD_SZ) {
|
||||
write_and_padd(block, message_bytes, remaining);
|
||||
hmac_hal_next_block_normal();
|
||||
hmac_hal_write_block_512(block);
|
||||
bzero(block, SHA256_BLOCK_SZ);
|
||||
} else {
|
||||
write_and_padd(block, message_bytes, remaining);
|
||||
}
|
||||
memcpy(block + SHA256_BLOCK_SZ - sizeof(bit_len),
|
||||
&bit_len, sizeof(bit_len));
|
||||
hmac_hal_next_block_padding();
|
||||
hmac_hal_write_block_512(block);
|
||||
}
|
||||
|
||||
// Read back result (bit swapped)
|
||||
hmac_hal_read_result_256(hmac);
|
||||
|
||||
periph_module_disable(PERIPH_DS_MODULE);
|
||||
periph_module_disable(PERIPH_SHA_MODULE);
|
||||
periph_module_disable(PERIPH_HMAC_MODULE);
|
||||
|
||||
esp_crypto_hmac_lock_release();
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
static ets_efuse_block_t convert_key_type(hmac_key_id_t key_id) {
|
||||
return ETS_EFUSE_BLOCK_KEY0 + (ets_efuse_block_t) key_id;
|
||||
}
|
||||
|
||||
esp_err_t esp_hmac_jtag_enable(hmac_key_id_t key_id, const uint8_t *token)
|
||||
{
|
||||
int ets_status;
|
||||
esp_err_t err = ESP_OK;
|
||||
|
||||
if ((!token) || (key_id >= HMAC_KEY_MAX))
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
|
||||
/* Check if JTAG is permanently disabled by HW Disable eFuse */
|
||||
if (esp_efuse_read_field_bit(ESP_EFUSE_DIS_PAD_JTAG)) {
|
||||
ESP_LOGE(TAG, "JTAG disabled permanently.");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
esp_crypto_hmac_lock_acquire();
|
||||
|
||||
ets_status = ets_jtag_enable_temporarily(token, convert_key_type(key_id));
|
||||
|
||||
if (ets_status != ETS_OK) {
|
||||
// ets_jtag_enable_temporarily returns either ETS_OK or ETS_FAIL
|
||||
err = ESP_FAIL;
|
||||
ESP_LOGE(TAG, "JTAG re-enabling failed (%d)", err);
|
||||
}
|
||||
|
||||
ESP_LOGD(TAG, "HMAC computation in downstream mode is completed.");
|
||||
|
||||
ets_hmac_disable();
|
||||
|
||||
esp_crypto_hmac_lock_release();
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
esp_err_t esp_hmac_jtag_disable()
|
||||
{
|
||||
esp_crypto_hmac_lock_acquire();
|
||||
|
||||
REG_SET_BIT(HMAC_SET_INVALIDATE_JTAG_REG, HMAC_INVALIDATE_JTAG);
|
||||
|
||||
esp_crypto_hmac_lock_release();
|
||||
|
||||
ESP_LOGD(TAG, "Invalidate JTAG result register. JTAG disabled.");
|
||||
|
||||
return ESP_OK;
|
||||
}
|
@@ -115,7 +115,7 @@ esp_err_t esp_ds_start_sign(const void *message,
|
||||
uint32_t conf_error = hmac_hal_configure(HMAC_OUTPUT_DS, key_id);
|
||||
if (conf_error) {
|
||||
ds_disable_release();
|
||||
return ESP32C6_ERR_HW_CRYPTO_DS_HMAC_FAIL;
|
||||
return ESP_ERR_HW_CRYPTO_DS_HMAC_FAIL;
|
||||
}
|
||||
|
||||
ds_hal_start();
|
||||
@@ -125,7 +125,7 @@ esp_err_t esp_ds_start_sign(const void *message,
|
||||
while (ds_ll_busy() != 0) {
|
||||
if ((esp_timer_get_time() - start_time) > SOC_DS_KEY_CHECK_MAX_WAIT_US) {
|
||||
ds_disable_release();
|
||||
return ESP32C6_ERR_HW_CRYPTO_DS_INVALID_KEY;
|
||||
return ESP_ERR_HW_CRYPTO_DS_INVALID_KEY;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -170,11 +170,11 @@ esp_err_t esp_ds_finish_sign(void *signature, esp_ds_context_t *esp_ds_ctx)
|
||||
esp_err_t return_value = ESP_OK;
|
||||
|
||||
if (sig_check_result == DS_SIGNATURE_MD_FAIL || sig_check_result == DS_SIGNATURE_PADDING_AND_MD_FAIL) {
|
||||
return_value = ESP32C6_ERR_HW_CRYPTO_DS_INVALID_DIGEST;
|
||||
return_value = ESP_ERR_HW_CRYPTO_DS_INVALID_DIGEST;
|
||||
}
|
||||
|
||||
if (sig_check_result == DS_SIGNATURE_PADDING_FAIL) {
|
||||
return_value = ESP32C6_ERR_HW_CRYPTO_DS_INVALID_PADDING;
|
||||
return_value = ESP_ERR_HW_CRYPTO_DS_INVALID_PADDING;
|
||||
}
|
||||
|
||||
free(esp_ds_ctx);
|
||||
|
@@ -1,182 +0,0 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
// TODO: IDF-5355 Copy frome C3
|
||||
|
||||
#include <string.h>
|
||||
#include "esp_private/periph_ctrl.h"
|
||||
#include "esp32c6/rom/hmac.h"
|
||||
#include "esp32c6/rom/ets_sys.h"
|
||||
#include "esp_efuse.h"
|
||||
#include "esp_efuse_table.h"
|
||||
#include "esp_hmac.h"
|
||||
#include "esp_log.h"
|
||||
#include "esp_crypto_lock.h"
|
||||
#include "soc/hwcrypto_reg.h"
|
||||
|
||||
#include "hal/hmac_hal.h"
|
||||
|
||||
#define SHA256_BLOCK_SZ 64
|
||||
#define SHA256_PAD_SZ 8
|
||||
|
||||
static const char *TAG = "esp_hmac";
|
||||
|
||||
/**
|
||||
* @brief Apply the HMAC padding without the embedded length.
|
||||
*
|
||||
* @note This function does not check the data length, it is the responsibility of the other functions in this
|
||||
* module to make sure that \c data_len is at most SHA256_BLOCK_SZ - 1 so the padding fits in.
|
||||
* Otherwise, this function has undefined behavior.
|
||||
* Note however, that for the actual HMAC implementation on ESP32C6, the length also needs to be applied at the end
|
||||
* of the block. This function alone deosn't do that.
|
||||
*/
|
||||
static void write_and_padd(uint8_t *block, const uint8_t *data, uint16_t data_len)
|
||||
{
|
||||
memcpy(block, data, data_len);
|
||||
// Apply a one bit, followed by zero bits (refer to the ESP32C6 TRM).
|
||||
block[data_len] = 0x80;
|
||||
bzero(block + data_len + 1, SHA256_BLOCK_SZ - data_len - 1);
|
||||
}
|
||||
|
||||
esp_err_t esp_hmac_calculate(hmac_key_id_t key_id,
|
||||
const void *message,
|
||||
size_t message_len,
|
||||
uint8_t *hmac)
|
||||
{
|
||||
const uint8_t *message_bytes = (const uint8_t *)message;
|
||||
|
||||
if (!message || !hmac) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
if (key_id >= HMAC_KEY_MAX) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
esp_crypto_hmac_lock_acquire();
|
||||
|
||||
// We also enable SHA and DS here. SHA is used by HMAC, DS will otherwise hold SHA in reset state.
|
||||
periph_module_enable(PERIPH_HMAC_MODULE);
|
||||
periph_module_enable(PERIPH_SHA_MODULE);
|
||||
periph_module_enable(PERIPH_DS_MODULE);
|
||||
|
||||
hmac_hal_start();
|
||||
|
||||
uint32_t conf_error = hmac_hal_configure(HMAC_OUTPUT_USER, key_id);
|
||||
if (conf_error) {
|
||||
esp_crypto_hmac_lock_release();
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
if (message_len + 1 + SHA256_PAD_SZ <= SHA256_BLOCK_SZ) {
|
||||
// If message including padding is only one block...
|
||||
// Last message block, so apply SHA-256 padding rules in software
|
||||
uint8_t block[SHA256_BLOCK_SZ];
|
||||
uint64_t bit_len = __builtin_bswap64(message_len * 8 + 512);
|
||||
|
||||
write_and_padd(block, message_bytes, message_len);
|
||||
// Final block: append the bit length in this block and signal padding to peripheral
|
||||
memcpy(block + SHA256_BLOCK_SZ - sizeof(bit_len),
|
||||
&bit_len, sizeof(bit_len));
|
||||
hmac_hal_write_one_block_512(block);
|
||||
} else {
|
||||
// If message including padding is needs more than one block
|
||||
|
||||
// write all blocks without padding except the last one
|
||||
size_t remaining_blocks = message_len / SHA256_BLOCK_SZ;
|
||||
for (int i = 1; i < remaining_blocks; i++) {
|
||||
hmac_hal_write_block_512(message_bytes);
|
||||
message_bytes += SHA256_BLOCK_SZ;
|
||||
hmac_hal_next_block_normal();
|
||||
}
|
||||
|
||||
// If message fits into one block but without padding, we must not write another block.
|
||||
if (remaining_blocks) {
|
||||
hmac_hal_write_block_512(message_bytes);
|
||||
message_bytes += SHA256_BLOCK_SZ;
|
||||
}
|
||||
|
||||
size_t remaining = message_len % SHA256_BLOCK_SZ;
|
||||
// Last message block, so apply SHA-256 padding rules in software
|
||||
uint8_t block[SHA256_BLOCK_SZ];
|
||||
uint64_t bit_len = __builtin_bswap64(message_len * 8 + 512);
|
||||
|
||||
// If the remaining message and appended padding doesn't fit into a single block, we have to write an
|
||||
// extra block with the rest of the message and potential padding first.
|
||||
if (remaining >= SHA256_BLOCK_SZ - SHA256_PAD_SZ) {
|
||||
write_and_padd(block, message_bytes, remaining);
|
||||
hmac_hal_next_block_normal();
|
||||
hmac_hal_write_block_512(block);
|
||||
bzero(block, SHA256_BLOCK_SZ);
|
||||
} else {
|
||||
write_and_padd(block, message_bytes, remaining);
|
||||
}
|
||||
memcpy(block + SHA256_BLOCK_SZ - sizeof(bit_len),
|
||||
&bit_len, sizeof(bit_len));
|
||||
hmac_hal_next_block_padding();
|
||||
hmac_hal_write_block_512(block);
|
||||
}
|
||||
|
||||
// Read back result (bit swapped)
|
||||
hmac_hal_read_result_256(hmac);
|
||||
|
||||
periph_module_disable(PERIPH_DS_MODULE);
|
||||
periph_module_disable(PERIPH_SHA_MODULE);
|
||||
periph_module_disable(PERIPH_HMAC_MODULE);
|
||||
|
||||
esp_crypto_hmac_lock_release();
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
static ets_efuse_block_t convert_key_type(hmac_key_id_t key_id) {
|
||||
return ETS_EFUSE_BLOCK_KEY0 + (ets_efuse_block_t) key_id;
|
||||
}
|
||||
|
||||
esp_err_t esp_hmac_jtag_enable(hmac_key_id_t key_id, const uint8_t *token)
|
||||
{
|
||||
int ets_status;
|
||||
esp_err_t err = ESP_OK;
|
||||
|
||||
if ((!token) || (key_id >= HMAC_KEY_MAX))
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
|
||||
/* Check if JTAG is permanently disabled by HW Disable eFuse */
|
||||
if (esp_efuse_read_field_bit(ESP_EFUSE_DIS_PAD_JTAG)) {
|
||||
ESP_LOGE(TAG, "JTAG disabled permanently.");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
esp_crypto_hmac_lock_acquire();
|
||||
|
||||
ets_status = ets_jtag_enable_temporarily(token, convert_key_type(key_id));
|
||||
|
||||
if (ets_status != ETS_OK) {
|
||||
// ets_jtag_enable_temporarily returns either ETS_OK or ETS_FAIL
|
||||
err = ESP_FAIL;
|
||||
ESP_LOGE(TAG, "JTAG re-enabling failed (%d)", err);
|
||||
}
|
||||
|
||||
ESP_LOGD(TAG, "HMAC computation in downstream mode is completed.");
|
||||
|
||||
ets_hmac_disable();
|
||||
|
||||
esp_crypto_hmac_lock_release();
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
esp_err_t esp_hmac_jtag_disable()
|
||||
{
|
||||
esp_crypto_hmac_lock_acquire();
|
||||
|
||||
REG_SET_BIT(HMAC_SET_INVALIDATE_JTAG_REG, HMAC_SET_INVALIDATE_JTAG);
|
||||
|
||||
esp_crypto_hmac_lock_release();
|
||||
|
||||
ESP_LOGD(TAG, "Invalidate JTAG result register. JTAG disabled.");
|
||||
|
||||
return ESP_OK;
|
||||
}
|
@@ -8,8 +8,7 @@ set(srcs "rtc_clk_init.c"
|
||||
)
|
||||
|
||||
if(NOT BOOTLOADER_BUILD)
|
||||
list(APPEND srcs "esp_hmac.c"
|
||||
"esp_crypto_lock.c"
|
||||
list(APPEND srcs "esp_crypto_lock.c"
|
||||
"esp_ds.c")
|
||||
|
||||
if(CONFIG_ESP_SYSTEM_MEMPROT_FEATURE)
|
||||
|
@@ -115,7 +115,7 @@ esp_err_t esp_ds_start_sign(const void *message,
|
||||
uint32_t conf_error = hmac_hal_configure(HMAC_OUTPUT_DS, key_id);
|
||||
if (conf_error) {
|
||||
ds_disable_release();
|
||||
return ESP32H2_ERR_HW_CRYPTO_DS_HMAC_FAIL;
|
||||
return ESP_ERR_HW_CRYPTO_DS_HMAC_FAIL;
|
||||
}
|
||||
|
||||
ds_hal_start();
|
||||
@@ -125,7 +125,7 @@ esp_err_t esp_ds_start_sign(const void *message,
|
||||
while (ds_ll_busy() != 0) {
|
||||
if ((esp_timer_get_time() - start_time) > SOC_DS_KEY_CHECK_MAX_WAIT_US) {
|
||||
ds_disable_release();
|
||||
return ESP32H2_ERR_HW_CRYPTO_DS_INVALID_KEY;
|
||||
return ESP_ERR_HW_CRYPTO_DS_INVALID_KEY;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -170,11 +170,11 @@ esp_err_t esp_ds_finish_sign(void *signature, esp_ds_context_t *esp_ds_ctx)
|
||||
esp_err_t return_value = ESP_OK;
|
||||
|
||||
if (sig_check_result == DS_SIGNATURE_MD_FAIL || sig_check_result == DS_SIGNATURE_PADDING_AND_MD_FAIL) {
|
||||
return_value = ESP32H2_ERR_HW_CRYPTO_DS_INVALID_DIGEST;
|
||||
return_value = ESP_ERR_HW_CRYPTO_DS_INVALID_DIGEST;
|
||||
}
|
||||
|
||||
if (sig_check_result == DS_SIGNATURE_PADDING_FAIL) {
|
||||
return_value = ESP32H2_ERR_HW_CRYPTO_DS_INVALID_PADDING;
|
||||
return_value = ESP_ERR_HW_CRYPTO_DS_INVALID_PADDING;
|
||||
}
|
||||
|
||||
free(esp_ds_ctx);
|
||||
|
@@ -1,180 +0,0 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include "esp_private/periph_ctrl.h"
|
||||
#include "esp32c3/rom/hmac.h"
|
||||
#include "esp32c3/rom/ets_sys.h"
|
||||
#include "esp_efuse.h"
|
||||
#include "esp_efuse_table.h"
|
||||
#include "esp_hmac.h"
|
||||
#include "esp_log.h"
|
||||
#include "esp_crypto_lock.h"
|
||||
#include "soc/hwcrypto_reg.h"
|
||||
|
||||
#include "hal/hmac_hal.h"
|
||||
|
||||
#define SHA256_BLOCK_SZ 64
|
||||
#define SHA256_PAD_SZ 8
|
||||
|
||||
static const char *TAG = "esp_hmac";
|
||||
|
||||
/**
|
||||
* @brief Apply the HMAC padding without the embedded length.
|
||||
*
|
||||
* @note This function does not check the data length, it is the responsibility of the other functions in this
|
||||
* module to make sure that \c data_len is at most SHA256_BLOCK_SZ - 1 so the padding fits in.
|
||||
* Otherwise, this function has undefined behavior.
|
||||
* Note however, that for the actual HMAC implementation on ESP32H2, the length also needs to be applied at the end
|
||||
* of the block. This function alone deosn't do that.
|
||||
*/
|
||||
static void write_and_padd(uint8_t *block, const uint8_t *data, uint16_t data_len)
|
||||
{
|
||||
memcpy(block, data, data_len);
|
||||
// Apply a one bit, followed by zero bits (refer to the ESP32H2 TRM).
|
||||
block[data_len] = 0x80;
|
||||
bzero(block + data_len + 1, SHA256_BLOCK_SZ - data_len - 1);
|
||||
}
|
||||
|
||||
esp_err_t esp_hmac_calculate(hmac_key_id_t key_id,
|
||||
const void *message,
|
||||
size_t message_len,
|
||||
uint8_t *hmac)
|
||||
{
|
||||
const uint8_t *message_bytes = (const uint8_t *)message;
|
||||
|
||||
if (!message || !hmac) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
if (key_id >= HMAC_KEY_MAX) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
esp_crypto_hmac_lock_acquire();
|
||||
|
||||
// We also enable SHA and DS here. SHA is used by HMAC, DS will otherwise hold SHA in reset state.
|
||||
periph_module_enable(PERIPH_HMAC_MODULE);
|
||||
periph_module_enable(PERIPH_SHA_MODULE);
|
||||
periph_module_enable(PERIPH_DS_MODULE);
|
||||
|
||||
hmac_hal_start();
|
||||
|
||||
uint32_t conf_error = hmac_hal_configure(HMAC_OUTPUT_USER, key_id);
|
||||
if (conf_error) {
|
||||
esp_crypto_hmac_lock_release();
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
if (message_len + 1 + SHA256_PAD_SZ <= SHA256_BLOCK_SZ) {
|
||||
// If message including padding is only one block...
|
||||
// Last message block, so apply SHA-256 padding rules in software
|
||||
uint8_t block[SHA256_BLOCK_SZ];
|
||||
uint64_t bit_len = __builtin_bswap64(message_len * 8 + 512);
|
||||
|
||||
write_and_padd(block, message_bytes, message_len);
|
||||
// Final block: append the bit length in this block and signal padding to peripheral
|
||||
memcpy(block + SHA256_BLOCK_SZ - sizeof(bit_len),
|
||||
&bit_len, sizeof(bit_len));
|
||||
hmac_hal_write_one_block_512(block);
|
||||
} else {
|
||||
// If message including padding is needs more than one block
|
||||
|
||||
// write all blocks without padding except the last one
|
||||
size_t remaining_blocks = message_len / SHA256_BLOCK_SZ;
|
||||
for (int i = 1; i < remaining_blocks; i++) {
|
||||
hmac_hal_write_block_512(message_bytes);
|
||||
message_bytes += SHA256_BLOCK_SZ;
|
||||
hmac_hal_next_block_normal();
|
||||
}
|
||||
|
||||
// If message fits into one block but without padding, we must not write another block.
|
||||
if (remaining_blocks) {
|
||||
hmac_hal_write_block_512(message_bytes);
|
||||
message_bytes += SHA256_BLOCK_SZ;
|
||||
}
|
||||
|
||||
size_t remaining = message_len % SHA256_BLOCK_SZ;
|
||||
// Last message block, so apply SHA-256 padding rules in software
|
||||
uint8_t block[SHA256_BLOCK_SZ];
|
||||
uint64_t bit_len = __builtin_bswap64(message_len * 8 + 512);
|
||||
|
||||
// If the remaining message and appended padding doesn't fit into a single block, we have to write an
|
||||
// extra block with the rest of the message and potential padding first.
|
||||
if (remaining >= SHA256_BLOCK_SZ - SHA256_PAD_SZ) {
|
||||
write_and_padd(block, message_bytes, remaining);
|
||||
hmac_hal_next_block_normal();
|
||||
hmac_hal_write_block_512(block);
|
||||
bzero(block, SHA256_BLOCK_SZ);
|
||||
} else {
|
||||
write_and_padd(block, message_bytes, remaining);
|
||||
}
|
||||
memcpy(block + SHA256_BLOCK_SZ - sizeof(bit_len),
|
||||
&bit_len, sizeof(bit_len));
|
||||
hmac_hal_next_block_padding();
|
||||
hmac_hal_write_block_512(block);
|
||||
}
|
||||
|
||||
// Read back result (bit swapped)
|
||||
hmac_hal_read_result_256(hmac);
|
||||
|
||||
periph_module_disable(PERIPH_DS_MODULE);
|
||||
periph_module_disable(PERIPH_SHA_MODULE);
|
||||
periph_module_disable(PERIPH_HMAC_MODULE);
|
||||
|
||||
esp_crypto_hmac_lock_release();
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
static ets_efuse_block_t convert_key_type(hmac_key_id_t key_id) {
|
||||
return ETS_EFUSE_BLOCK_KEY0 + (ets_efuse_block_t) key_id;
|
||||
}
|
||||
|
||||
esp_err_t esp_hmac_jtag_enable(hmac_key_id_t key_id, const uint8_t *token)
|
||||
{
|
||||
int ets_status;
|
||||
esp_err_t err = ESP_OK;
|
||||
|
||||
if ((!token) || (key_id >= HMAC_KEY_MAX))
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
|
||||
/* Check if JTAG is permanently disabled by HW Disable eFuse */
|
||||
if (esp_efuse_read_field_bit(ESP_EFUSE_DIS_PAD_JTAG)) {
|
||||
ESP_LOGE(TAG, "JTAG disabled permanently.");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
esp_crypto_hmac_lock_acquire();
|
||||
|
||||
ets_status = ets_jtag_enable_temporarily(token, convert_key_type(key_id));
|
||||
|
||||
if (ets_status != ETS_OK) {
|
||||
// ets_jtag_enable_temporarily returns either ETS_OK or ETS_FAIL
|
||||
err = ESP_FAIL;
|
||||
ESP_LOGE(TAG, "JTAG re-enabling failed (%d)", err);
|
||||
}
|
||||
|
||||
ESP_LOGD(TAG, "HMAC computation in downstream mode is completed.");
|
||||
|
||||
ets_hmac_disable();
|
||||
|
||||
esp_crypto_hmac_lock_release();
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
esp_err_t esp_hmac_jtag_disable()
|
||||
{
|
||||
esp_crypto_hmac_lock_acquire();
|
||||
|
||||
REG_SET_BIT(HMAC_SET_INVALIDATE_JTAG_REG, HMAC_INVALIDATE_JTAG);
|
||||
|
||||
esp_crypto_hmac_lock_release();
|
||||
|
||||
ESP_LOGD(TAG, "Invalidate JTAG result register. JTAG disabled.");
|
||||
|
||||
return ESP_OK;
|
||||
}
|
@@ -13,7 +13,6 @@ set(srcs
|
||||
|
||||
if(NOT BOOTLOADER_BUILD)
|
||||
list(APPEND srcs "memprot.c"
|
||||
"esp_hmac.c"
|
||||
"esp_crypto_lock.c"
|
||||
"esp_ds.c")
|
||||
|
||||
|
@@ -1,100 +0,0 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include "esp32s2/rom/ets_sys.h"
|
||||
#include "esp32s2/rom/hmac.h"
|
||||
#include "esp_hmac.h"
|
||||
#include "esp_crypto_lock.h"
|
||||
#include "esp_efuse.h"
|
||||
#include "esp_efuse_table.h"
|
||||
#include "soc/hwcrypto_reg.h"
|
||||
#include "soc/system_reg.h"
|
||||
#include "esp_log.h"
|
||||
|
||||
static const char *TAG = "esp_hmac";
|
||||
|
||||
static ets_efuse_block_t convert_key_type(hmac_key_id_t key_id) {
|
||||
return ETS_EFUSE_BLOCK_KEY0 + (ets_efuse_block_t) key_id;
|
||||
}
|
||||
|
||||
esp_err_t esp_hmac_calculate(hmac_key_id_t key_id,
|
||||
const void *message,
|
||||
size_t message_len,
|
||||
uint8_t *hmac)
|
||||
{
|
||||
int hmac_ret;
|
||||
if (!message || !hmac) return ESP_ERR_INVALID_ARG;
|
||||
if (key_id >= HMAC_KEY_MAX) return ESP_ERR_INVALID_ARG;
|
||||
|
||||
esp_crypto_dma_lock_acquire();
|
||||
|
||||
ets_hmac_enable();
|
||||
hmac_ret = ets_hmac_calculate_message(convert_key_type(key_id), message, message_len, hmac);
|
||||
ets_hmac_disable();
|
||||
|
||||
esp_crypto_dma_lock_release();
|
||||
|
||||
if (hmac_ret != 0) {
|
||||
return ESP_FAIL;
|
||||
} else {
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
esp_err_t esp_hmac_jtag_enable(hmac_key_id_t key_id, const uint8_t *token)
|
||||
{
|
||||
int ets_status;
|
||||
esp_err_t err = ESP_OK;
|
||||
|
||||
if ((!token) || (key_id >= HMAC_KEY_MAX))
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
|
||||
/* Check if JTAG is permanently disabled by HW Disable eFuse */
|
||||
if (esp_efuse_read_field_bit(ESP_EFUSE_HARD_DIS_JTAG)) {
|
||||
ESP_LOGE(TAG, "JTAG disabled permanently.");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
esp_crypto_dma_lock_acquire();
|
||||
|
||||
ets_hmac_enable();
|
||||
|
||||
/* Token updating into HMAC module. */
|
||||
for (int i = 0; i < 32; i += 4) {
|
||||
uint32_t key_word;
|
||||
memcpy(&key_word, &token[i], 4);
|
||||
REG_WRITE(DPORT_JTAG_CTRL_0_REG + i, __builtin_bswap32(key_word));
|
||||
}
|
||||
|
||||
ets_status = ets_hmac_calculate_downstream(convert_key_type(key_id), ETS_EFUSE_KEY_PURPOSE_HMAC_DOWN_JTAG);
|
||||
if (ets_status != ETS_OK) {
|
||||
err = ESP_FAIL;
|
||||
ESP_LOGE(TAG, "HMAC downstream JTAG enable mode setting failed. (%d)", err);
|
||||
}
|
||||
|
||||
ESP_LOGD(TAG, "HMAC computation in downstream mode is completed.");
|
||||
|
||||
ets_hmac_disable();
|
||||
|
||||
esp_crypto_dma_lock_release();
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
esp_err_t esp_hmac_jtag_disable()
|
||||
{
|
||||
esp_crypto_dma_lock_acquire();
|
||||
|
||||
REG_WRITE(HMAC_SET_INVALIDATE_JTAG_REG, 1);
|
||||
|
||||
esp_crypto_dma_lock_release();
|
||||
|
||||
ESP_LOGD(TAG, "Invalidate JTAG result register. JTAG disabled.");
|
||||
|
||||
return ESP_OK;
|
||||
}
|
@@ -12,8 +12,7 @@ set(srcs
|
||||
)
|
||||
|
||||
if(NOT BOOTLOADER_BUILD)
|
||||
list(APPEND srcs "esp_hmac.c"
|
||||
"esp_ds.c"
|
||||
list(APPEND srcs "esp_ds.c"
|
||||
"esp_crypto_lock.c")
|
||||
|
||||
if(CONFIG_ESP_SYSTEM_MEMPROT_FEATURE)
|
||||
|
@@ -119,7 +119,7 @@ esp_err_t esp_ds_start_sign(const void *message,
|
||||
uint32_t conf_error = hmac_hal_configure(HMAC_OUTPUT_DS, key_id);
|
||||
if (conf_error) {
|
||||
ds_disable_release();
|
||||
return ESP32S3_ERR_HW_CRYPTO_DS_HMAC_FAIL;
|
||||
return ESP_ERR_HW_CRYPTO_DS_HMAC_FAIL;
|
||||
}
|
||||
|
||||
ds_hal_start();
|
||||
@@ -129,7 +129,7 @@ esp_err_t esp_ds_start_sign(const void *message,
|
||||
while (ds_ll_busy() != 0) {
|
||||
if ((esp_timer_get_time() - start_time) > SOC_DS_KEY_CHECK_MAX_WAIT_US) {
|
||||
ds_disable_release();
|
||||
return ESP32S3_ERR_HW_CRYPTO_DS_INVALID_KEY;
|
||||
return ESP_ERR_HW_CRYPTO_DS_INVALID_KEY;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -174,11 +174,11 @@ esp_err_t esp_ds_finish_sign(void *signature, esp_ds_context_t *esp_ds_ctx)
|
||||
esp_err_t return_value = ESP_OK;
|
||||
|
||||
if (sig_check_result == DS_SIGNATURE_MD_FAIL || sig_check_result == DS_SIGNATURE_PADDING_AND_MD_FAIL) {
|
||||
return_value = ESP32S3_ERR_HW_CRYPTO_DS_INVALID_DIGEST;
|
||||
return_value = ESP_ERR_HW_CRYPTO_DS_INVALID_DIGEST;
|
||||
}
|
||||
|
||||
if (sig_check_result == DS_SIGNATURE_PADDING_FAIL) {
|
||||
return_value = ESP32S3_ERR_HW_CRYPTO_DS_INVALID_PADDING;
|
||||
return_value = ESP_ERR_HW_CRYPTO_DS_INVALID_PADDING;
|
||||
}
|
||||
|
||||
free(esp_ds_ctx);
|
||||
|
@@ -133,6 +133,7 @@ INPUT = \
|
||||
$(PROJECT_PATH)/components/esp_hw_support/include/esp_chip_info.h \
|
||||
$(PROJECT_PATH)/components/esp_hw_support/include/esp_cpu.h \
|
||||
$(PROJECT_PATH)/components/esp_hw_support/include/esp_crc.h \
|
||||
$(PROJECT_PATH)/components/esp_hw_support/include/esp_hmac.h \
|
||||
$(PROJECT_PATH)/components/esp_hw_support/include/esp_intr_alloc.h \
|
||||
$(PROJECT_PATH)/components/esp_hw_support/include/esp_mac.h \
|
||||
$(PROJECT_PATH)/components/esp_hw_support/include/esp_random.h \
|
||||
|
@@ -1,3 +1,2 @@
|
||||
INPUT += \
|
||||
$(PROJECT_PATH)/components/esp_hw_support/include/soc/esp32c3/esp_ds.h \
|
||||
$(PROJECT_PATH)/components/esp_hw_support/include/soc/esp32c3/esp_hmac.h \
|
||||
$(PROJECT_PATH)/components/esp_hw_support/include/soc/$(IDF_TARGET)/esp_ds.h \
|
||||
|
@@ -1 +1,2 @@
|
||||
INPUT += \
|
||||
$(PROJECT_PATH)/components/esp_hw_support/include/soc/$(IDF_TARGET)/esp_ds.h \
|
||||
|
@@ -1,3 +1,2 @@
|
||||
INPUT += \
|
||||
$(PROJECT_PATH)/components/esp_hw_support/include/soc/esp32h2/esp_ds.h \
|
||||
$(PROJECT_PATH)/components/esp_hw_support/include/soc/esp32h2/esp_hmac.h \
|
||||
$(PROJECT_PATH)/components/esp_hw_support/include/soc/$(IDF_TARGET)/esp_ds.h \
|
||||
|
@@ -1,7 +1,6 @@
|
||||
INPUT += \
|
||||
$(PROJECT_PATH)/components/driver/$(IDF_TARGET)/include/driver/touch_sensor.h \
|
||||
$(PROJECT_PATH)/components/esp_hw_support/include/soc/esp32s2/esp_ds.h \
|
||||
$(PROJECT_PATH)/components/esp_hw_support/include/soc/esp32s2/esp_hmac.h \
|
||||
$(PROJECT_PATH)/components/esp_hw_support/include/soc/$(IDF_TARGET)/esp_ds.h \
|
||||
$(PROJECT_PATH)/components/soc/$(IDF_TARGET)/include/soc/dac_channel.h \
|
||||
$(PROJECT_PATH)/components/soc/$(IDF_TARGET)/include/soc/rtc_io_channel.h \
|
||||
$(PROJECT_PATH)/components/soc/$(IDF_TARGET)/include/soc/touch_sensor_channel.h \
|
||||
|
@@ -1,7 +1,6 @@
|
||||
INPUT += \
|
||||
$(PROJECT_PATH)/components/driver/$(IDF_TARGET)/include/driver/touch_sensor.h \
|
||||
$(PROJECT_PATH)/components/esp_hw_support/include/soc/$(IDF_TARGET)/esp_ds.h \
|
||||
$(PROJECT_PATH)/components/esp_hw_support/include/soc/$(IDF_TARGET)/esp_hmac.h \
|
||||
$(PROJECT_PATH)/components/soc/$(IDF_TARGET)/include/soc/touch_sensor_channel.h \
|
||||
$(PROJECT_PATH)/components/ulp/ulp_common/include/$(IDF_TARGET)/ulp_common_defs.h \
|
||||
$(PROJECT_PATH)/components/ulp/ulp_fsm/include/$(IDF_TARGET)/ulp.h \
|
||||
|
Reference in New Issue
Block a user