From 6b4d2140ee672708c93a2fdefec6633c2652244d Mon Sep 17 00:00:00 2001 From: Aditya Patwardhan Date: Thu, 12 Oct 2023 16:17:52 +0530 Subject: [PATCH] feat(hal): Added HAL and LL layer for HUK --- components/hal/esp32p4/include/hal/huk_hal.h | 51 +++++++++ components/hal/esp32p4/include/hal/huk_ll.h | 114 +++++++++++++++++++ components/hal/huk_hal.c | 41 +++++++ components/hal/include/hal/huk_types.h | 65 +++++++++++ 4 files changed, 271 insertions(+) create mode 100644 components/hal/esp32p4/include/hal/huk_hal.h create mode 100644 components/hal/esp32p4/include/hal/huk_ll.h create mode 100644 components/hal/huk_hal.c create mode 100644 components/hal/include/hal/huk_types.h diff --git a/components/hal/esp32p4/include/hal/huk_hal.h b/components/hal/esp32p4/include/hal/huk_hal.h new file mode 100644 index 0000000000..cd62ac3d3f --- /dev/null +++ b/components/hal/esp32p4/include/hal/huk_hal.h @@ -0,0 +1,51 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +// The HAL layer for Hardware Unique Key (HUK) Genarator + +#pragma once + +#if SOC_KEY_MANAGER_SUPPORTED +#include "hal/huk_types.h" +#include +#include "esp_err.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * @brief Configure HUK: Generate new HUK information or Recover key from recovery information + * Generation Mode: In this case the Generation mode of the HUK Generator is used. A new HUK is generated and the respective HUK information is copied to the given buffer. This info can be again used to recover the same HUK. + * Recovery Mode: In this case the Recovery mode of the HUK Generator is used. The HUK is recovered from the given HUK information. This is the HUK information generated previously with help of huk_hal_generate_huk_info. + * + * @input + * huk_info_buf(I/O) Pointer to the buffer for the HUK info, size of the given buffer must equal to HUK_INFO_SIZE + * In Generation Mode the buffer shall be populated with the huk_info_buf + * In recovery mode the huk_info stored in the buffer shall be consumed for HUK recovery + */ +void huk_hal_configure(const esp_huk_mode_t huk_mode, uint8_t *huk_info_buf); + +/** + * @brief Read state of Hardware Unique Key Generator + * + * @return esp_huk_state_t + */ +esp_huk_state_t huk_hal_get_state(void); + +/** + * @brief Get the HUK generation status: esp_huk_gen_status_t + */ +uint8_t huk_hal_get_risk_level(void); + +/** + * @brief Read the HUK date information + */ +uint32_t huk_hal_get_date_info(void); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/components/hal/esp32p4/include/hal/huk_ll.h b/components/hal/esp32p4/include/hal/huk_ll.h new file mode 100644 index 0000000000..404dbafab5 --- /dev/null +++ b/components/hal/esp32p4/include/hal/huk_ll.h @@ -0,0 +1,114 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/******************************************************************************* + * NOTICE + * The hal is not public api, don't use it in application code. + ******************************************************************************/ + +#pragma once +#if SOC_KEY_MANAGER_SUPPORTED +#include +#include +#include + +#include "hal/huk_types.h" +#include "soc/huk_reg.h" +#include "soc/soc_caps.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* @brief Configure the HUK mode */ +static inline void huk_ll_configure_mode(const esp_huk_mode_t huk_mode) +{ + REG_SET_FIELD(HUK_CONF_REG, HUK_MODE, huk_mode); +} + +void huk_ll_write_info(const uint8_t *buffer, const size_t size) +{ + memcpy((uint8_t *)HUK_INFO_MEM, buffer, size); +} + +void huk_ll_read_info(uint8_t *buffer, const size_t size) +{ + memcpy(buffer, (uint8_t *)HUK_INFO_MEM, size); +} + +/* @brief Start the HUK at IDLE state */ +static inline void huk_ll_start(void) +{ + REG_SET_FIELD(HUK_START_REG, HUK_START, 1); +} + +/* @brief Continue HUK operation at LOAD/GAIN state */ +static inline void huk_ll_continue(void) +{ + REG_SET_FIELD(HUK_START_REG, HUK_CONTINUE, 1); +} + +/* @bried Enable or Disable the HUK interrupts */ +static inline void huk_ll_configure_interrupt(const esp_huk_interrupt_type_t intr, const bool en) +{ + switch(intr) { + case ESP_HUK_INT_PREP_DONE: + REG_SET_FIELD(HUK_INT_ENA_REG, HUK_PREP_DONE_INT_ENA, en); + case ESP_HUK_INT_PROC_DONE: + REG_SET_FIELD(HUK_INT_ENA_REG, HUK_PROC_DONE_INT_ENA, en); + case ESP_HUK_INT_POST_DONE: + REG_SET_FIELD(HUK_INT_ENA_REG, HUK_POST_DONE_INT_ENA, en); + default: + return; + } +} + +/* @bried Clear the HUK interrupts */ +static inline void huk_ll_clear_int(const esp_huk_interrupt_type_t intr) +{ + switch(intr) { + case ESP_HUK_INT_PREP_DONE: + REG_SET_FIELD(HUK_INT_CLR_REG, HUK_PREP_DONE_INT_CLR, 1); + case ESP_HUK_INT_PROC_DONE: + REG_SET_FIELD(HUK_INT_CLR_REG, HUK_PROC_DONE_INT_CLR, 1); + case ESP_HUK_INT_POST_DONE: + REG_SET_FIELD(HUK_INT_CLR_REG, HUK_POST_DONE_INT_CLR, 1); + default: + return; + } +} + +/** + * @brief Read state of Hardware Unique Key Generator + * + * @return esp_huk_state_t + */ +static inline esp_huk_state_t huk_ll_get_state(void) +{ + return REG_GET_FIELD(HUK_STATE_REG, HUK_STATE); +} + +/** + * @brief Get the HUK generation status: esp_huk_gen_status_t + */ +static inline esp_huk_gen_status_t huk_ll_get_gen_status(void) +{ + return REG_GET_FIELD(HUK_STATUS_REG, HUK_STATUS); +} + +/** + * @brief Read the HUK date information + */ +static inline uint32_t huk_ll_get_date_info(void) +{ + // Only the least siginificant 28 bits have desired information + return (uint32_t)(0x0FFFFFFF & REG_READ(HUK_DATE_REG)); +} + +#ifdef __cplusplus +} +#endif +#endif diff --git a/components/hal/huk_hal.c b/components/hal/huk_hal.c new file mode 100644 index 0000000000..a7995c91c7 --- /dev/null +++ b/components/hal/huk_hal.c @@ -0,0 +1,41 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +// The HAL layer for Hardware Unique Key(HUK) Generator + + +#include "hal/huk_hal.h" +#include "hal/huk_ll.h" +#include "hal/huk_types.h" +#include "hal/assert.h" +#include "hal/log.h" +#include "rom/km.h" + +esp_huk_state_t huk_hal_get_state(void) +{ + return huk_ll_get_state(); +} + +static void inline huk_hal_wait_for_state(esp_huk_state_t state) +{ + while (huk_ll_get_state() != state) { + ; + } +} + +void huk_hal_configure(const esp_huk_mode_t huk_mode, uint8_t *huk_info_buf) +{ + esp_rom_km_huk_conf(huk_mode, huk_info_buf); +} + +uint8_t huk_hal_get_risk_level(void) +{ + return (uint8_t) esp_rom_km_huk_risk(); +} + +uint32_t huk_hal_get_date_info(void) +{ + return huk_ll_get_date_info(); +} diff --git a/components/hal/include/hal/huk_types.h b/components/hal/include/hal/huk_types.h new file mode 100644 index 0000000000..5b09f5c6f1 --- /dev/null +++ b/components/hal/include/hal/huk_types.h @@ -0,0 +1,65 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#pragma once + +#include "soc/soc_caps.h" + +#if SOC_KEY_MANAGER_SUPPORTED + +#include "esp_assert.h" +#include "rom/km.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define HUK_INFO_SIZE 384 + +/** + * @brief Mode for Hardware Unique Key Process: recovery, generation + */ +typedef enum { + ESP_HUK_MODE_RECOVERY = 0, /* HUK recovery mode */ + ESP_HUK_MODE_GENERATION, /* HUK generation mode */ +} esp_huk_mode_t; + +ESP_STATIC_ASSERT(sizeof(esp_huk_mode_t) == sizeof(huk_mode_t), "Size of esp_huk_mode_t should match huk_mode_t (from ROM)"); + +/** + * @brief State of Hardware Unique Key Generator: idle, load, gain or busy. + * + */ +typedef enum { + ESP_HUK_STATE_IDLE = 0, /* Key Manager is idle */ + ESP_HUK_STATE_LOAD, /* Key Manager is read to recieve input */ + ESP_HUK_STATE_GAIN, /* Key Manager is ready to provide output */ + ESP_HUK_STATE_BUSY /* Key Manager is busy */ +} esp_huk_state_t; + +/** + * @brief Status of the Hardware Unique Key Generation: + * not generated, generated and valid, generated and invalid + */ +typedef enum { + ESP_HUK_STATUS_NOT_GENERATED = 0, /* HUK is not generated */ + ESP_HUK_STATUS_GENERATED_AND_VALID, /* HUK is generated and valid */ + ESP_HUK_STATUS_GENERATED_AND_INVALID /* HUK is generated and is invalid */ +} esp_huk_gen_status_t; + +/** + * @brief + * HUK interrupt types + */ +typedef enum { + ESP_HUK_INT_PREP_DONE = 0x01, + ESP_HUK_INT_PROC_DONE, + ESP_HUK_INT_POST_DONE, +} esp_huk_interrupt_type_t; + +#ifdef __cplusplus +} +#endif +#endif