forked from espressif/esp-idf
refactor(esp_tee): Update TEE secure storage interface APIs
This commit is contained in:
@ -72,24 +72,24 @@ menu "ESP-TEE (Trusted Execution Environment)"
|
||||
config SECURE_TEE_SEC_STG_MODE_DEVELOPMENT
|
||||
bool "Development"
|
||||
help
|
||||
Secure storage will be encrypted by the data stored in eFuse BLK2
|
||||
Secure storage will be encrypted by a constant key embedded in the TEE firmware
|
||||
|
||||
config SECURE_TEE_SEC_STG_MODE_RELEASE
|
||||
depends on IDF_TARGET_ESP32C6
|
||||
bool "Release"
|
||||
help
|
||||
Secure storage will be encrypted by the data stored in eFuse block
|
||||
configured through the SECURE_TEE_SEC_STG_KEY_EFUSE_BLK option
|
||||
configured through the SECURE_TEE_SEC_STG_EFUSE_HMAC_KEY_ID option
|
||||
|
||||
endchoice
|
||||
|
||||
config SECURE_TEE_SEC_STG_KEY_EFUSE_BLK
|
||||
int "Secure Storage: Encryption key eFuse block"
|
||||
config SECURE_TEE_SEC_STG_EFUSE_HMAC_KEY_ID
|
||||
int "Secure Storage: eFuse HMAC key ID"
|
||||
depends on SECURE_TEE_SEC_STG_MODE_RELEASE
|
||||
range 4 10
|
||||
default 10
|
||||
range -1 5
|
||||
default -1
|
||||
help
|
||||
eFuse block ID storing the TEE secure storage encryption key
|
||||
eFuse block key ID storing the HMAC key for deriving the TEE secure storage encryption keys
|
||||
|
||||
config SECURE_TEE_SEC_STG_SUPPORT_SECP192R1_SIGN
|
||||
bool "Secure Storage: Support signing with the ECDSA SECP192R1 curve"
|
||||
@ -104,13 +104,12 @@ menu "ESP-TEE (Trusted Execution Environment)"
|
||||
This configuration enables the support for the Attestation service.
|
||||
|
||||
|
||||
config SECURE_TEE_ATT_KEY_SLOT_ID
|
||||
config SECURE_TEE_ATT_KEY_STR_ID
|
||||
depends on SECURE_TEE_ATTESTATION
|
||||
int "Attestation: Secure Storage slot ID for EAT signing"
|
||||
default 0
|
||||
range 0 14
|
||||
string "Attestation: Secure Storage key ID for EAT signing"
|
||||
default "tee_att_key0"
|
||||
help
|
||||
This configuration sets the slot ID from the TEE secure storage
|
||||
This configuration sets the key ID from the TEE secure storage
|
||||
storing the ECDSA keypair for executing sign/verify operations
|
||||
from the TEE side for attestation.
|
||||
|
||||
|
@ -252,36 +252,28 @@ secure_services:
|
||||
entries:
|
||||
- id: 175
|
||||
type: custom
|
||||
function: esp_tee_sec_storage_init
|
||||
args: 0
|
||||
function: esp_tee_sec_storage_clear_key
|
||||
args: 1
|
||||
- id: 176
|
||||
type: custom
|
||||
function: esp_tee_sec_storage_gen_key
|
||||
args: 2
|
||||
args: 1
|
||||
- id: 177
|
||||
type: custom
|
||||
function: esp_tee_sec_storage_get_signature
|
||||
args: 5
|
||||
function: esp_tee_sec_storage_ecdsa_sign
|
||||
args: 4
|
||||
- id: 178
|
||||
type: custom
|
||||
function: esp_tee_sec_storage_get_pubkey
|
||||
args: 3
|
||||
function: esp_tee_sec_storage_ecdsa_get_pubkey
|
||||
args: 2
|
||||
- id: 179
|
||||
type: custom
|
||||
function: esp_tee_sec_storage_encrypt
|
||||
args: 8
|
||||
function: esp_tee_sec_storage_aead_encrypt
|
||||
args: 4
|
||||
- id: 180
|
||||
type: custom
|
||||
function: esp_tee_sec_storage_decrypt
|
||||
args: 8
|
||||
- id: 181
|
||||
type: custom
|
||||
function: esp_tee_sec_storage_is_slot_empty
|
||||
args: 1
|
||||
- id: 182
|
||||
type: custom
|
||||
function: esp_tee_sec_storage_clear_slot
|
||||
args: 1
|
||||
function: esp_tee_sec_storage_aead_decrypt
|
||||
args: 4
|
||||
# ID: 195-199 (5) - OTA
|
||||
- family: ota
|
||||
entries:
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@ -41,26 +41,23 @@ static esp_err_t gen_ecdsa_keypair_secp256r1(esp_att_ecdsa_keypair_t *keypair)
|
||||
if (keypair == NULL) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
memset(keypair, 0x00, sizeof(esp_att_ecdsa_keypair_t));
|
||||
|
||||
uint16_t slot_id = ESP_ATT_TK_KEY_ID;
|
||||
esp_tee_sec_storage_pubkey_t pubkey = {0};
|
||||
esp_tee_sec_storage_key_cfg_t key_cfg = {
|
||||
.id = (const char *)(ESP_ATT_TK_KEY_ID),
|
||||
.type = ESP_SEC_STG_KEY_ECDSA_SECP256R1,
|
||||
};
|
||||
|
||||
esp_err_t err = esp_tee_sec_storage_init();
|
||||
if (err != ESP_OK) {
|
||||
esp_err_t err = esp_tee_sec_storage_gen_key(&key_cfg);
|
||||
if (err == ESP_ERR_INVALID_STATE) {
|
||||
ESP_LOGW(TAG, "Using pre-existing key...");
|
||||
} else if (err != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Failed to generate ECDSA keypair (%d)", err);
|
||||
return err;
|
||||
}
|
||||
|
||||
if (esp_tee_sec_storage_is_slot_empty(slot_id)) {
|
||||
err = esp_tee_sec_storage_gen_key(slot_id, ESP_SEC_STG_KEY_ECDSA_SECP256R1);
|
||||
if (err != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Failed to generate ECDSA keypair (%d)", err);
|
||||
return err;
|
||||
}
|
||||
}
|
||||
|
||||
err = esp_tee_sec_storage_get_pubkey(slot_id, ESP_SEC_STG_KEY_ECDSA_SECP256R1, &pubkey);
|
||||
esp_tee_sec_storage_ecdsa_pubkey_t pubkey = {};
|
||||
err = esp_tee_sec_storage_ecdsa_get_pubkey(&key_cfg, &pubkey);
|
||||
if (err != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Failed to fetch ECDSA pubkey (%d)", err);
|
||||
return err;
|
||||
@ -83,8 +80,13 @@ static esp_err_t get_ecdsa_sign_secp256r1(const esp_att_ecdsa_keypair_t *keypair
|
||||
return ESP_ERR_INVALID_SIZE;
|
||||
}
|
||||
|
||||
esp_tee_sec_storage_sign_t sign = {};
|
||||
esp_err_t err = esp_tee_sec_storage_get_signature(ESP_ATT_TK_KEY_ID, ESP_SEC_STG_KEY_ECDSA_SECP256R1, (uint8_t *)digest, len, &sign);
|
||||
esp_tee_sec_storage_key_cfg_t key_cfg = {
|
||||
.id = (const char *)(ESP_ATT_TK_KEY_ID),
|
||||
.type = ESP_SEC_STG_KEY_ECDSA_SECP256R1,
|
||||
};
|
||||
|
||||
esp_tee_sec_storage_ecdsa_sign_t sign = {};
|
||||
esp_err_t err = esp_tee_sec_storage_ecdsa_sign(&key_cfg, (uint8_t *)digest, len, &sign);
|
||||
if (err != ESP_OK) {
|
||||
return err;
|
||||
}
|
||||
|
@ -126,7 +126,7 @@ esp_err_t esp_att_utils_header_to_json(const esp_att_token_hdr_t *tk_hdr, char *
|
||||
json_gen_obj_set_string(&json_gen, "encr_alg", NULL);
|
||||
json_gen_obj_set_string(&json_gen, "sign_alg", ESP_ATT_TK_SIGN_ALG);
|
||||
|
||||
json_gen_obj_set_int(&json_gen, "key_id", ESP_ATT_TK_KEY_ID);
|
||||
json_gen_obj_set_string(&json_gen, "key_id", ESP_ATT_TK_KEY_ID);
|
||||
|
||||
// End the top-level JSON object
|
||||
json_gen_end_object(&json_gen);
|
||||
|
@ -42,9 +42,9 @@ extern "C" {
|
||||
#define ESP_ATT_TK_MIN_SIZE (ESP_ATT_HDR_JSON_MAX_SZ + ESP_ATT_EAT_JSON_MAX_SZ + ESP_ATT_PUBKEY_JSON_MAX_SZ + ESP_ATT_SIGN_JSON_MAX_SZ)
|
||||
|
||||
#if ESP_TEE_BUILD && CONFIG_SECURE_TEE_ATTESTATION
|
||||
#define ESP_ATT_TK_KEY_ID (CONFIG_SECURE_TEE_ATT_KEY_SLOT_ID)
|
||||
#define ESP_ATT_TK_KEY_ID (CONFIG_SECURE_TEE_ATT_KEY_STR_ID)
|
||||
#else
|
||||
#define ESP_ATT_TK_KEY_ID (-1)
|
||||
#define ESP_ATT_TK_KEY_ID ("NULL")
|
||||
#endif
|
||||
|
||||
/**
|
||||
|
@ -5,7 +5,7 @@ set(priv_requires efuse mbedtls spi_flash)
|
||||
|
||||
if(esp_tee_build)
|
||||
list(APPEND srcs "tee_sec_storage.c")
|
||||
list(APPEND priv_requires log tee_flash_mgr)
|
||||
list(APPEND priv_requires esp_partition log nvs_flash tee_flash_mgr)
|
||||
else()
|
||||
list(APPEND srcs "tee_sec_storage_wrapper.c")
|
||||
set(priv_requires esp_tee)
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@ -12,138 +12,142 @@ extern "C" {
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include "esp_err.h"
|
||||
|
||||
#define MIN_SEC_STG_SLOT_ID 0 /*!< Minimum secure storage slot ID */
|
||||
#define MAX_SEC_STG_SLOT_ID 14 /*!< Maximum secure storage slot ID */
|
||||
#include "esp_err.h"
|
||||
#include "esp_bit_defs.h"
|
||||
|
||||
#define MAX_ECDSA_SUPPORTED_KEY_LEN 32 /*!< Maximum supported size for the ECDSA key */
|
||||
#define MAX_AES_SUPPORTED_KEY_LEN 32 /*!< Maximum supported size for the AES key */
|
||||
|
||||
#define SEC_STORAGE_FLAG_NONE 0 /*!< No flags */
|
||||
#define SEC_STORAGE_FLAG_WRITE_ONCE BIT(0) /*!< Data can only be written once */
|
||||
|
||||
/**
|
||||
* @brief Enum to represent the type of key stored in the secure storage
|
||||
*
|
||||
*/
|
||||
typedef enum {
|
||||
ESP_SEC_STG_KEY_ECDSA_SECP256R1 = 0,
|
||||
ESP_SEC_STG_KEY_AES256 = 1,
|
||||
ESP_SEC_STG_KEY_AES256 = 0,
|
||||
ESP_SEC_STG_KEY_ECDSA_SECP256R1 = 1,
|
||||
ESP_SEC_STG_KEY_ECDSA_SECP192R1 = 2,
|
||||
ESP_SEC_STG_MAX,
|
||||
ESP_SEC_STG_TYPE_MAX,
|
||||
} esp_tee_sec_storage_type_t;
|
||||
|
||||
/**
|
||||
* @brief Structure holding the X and Y components
|
||||
* of the ECDSA public key
|
||||
* @brief Configuration structure for key generation/import
|
||||
*
|
||||
*/
|
||||
typedef struct {
|
||||
const char *id; /*!< Unique identifier for the key */
|
||||
esp_tee_sec_storage_type_t type; /*!< Type of key (AES256, ECDSA_SECP256R1, etc.) */
|
||||
uint32_t flags; /*!< Key flags (e.g. WRITE_ONCE) */
|
||||
} esp_tee_sec_storage_key_cfg_t;
|
||||
|
||||
/**
|
||||
* @brief Context structure for AES-GCM AEAD encryption/decryption operations
|
||||
*
|
||||
*/
|
||||
typedef struct {
|
||||
const char *key_id; /*!< Identifier of the key to use */
|
||||
const uint8_t *aad; /*!< Additional authenticated data */
|
||||
size_t aad_len; /*!< Length of additional authenticated data */
|
||||
const uint8_t *input; /*!< Input data buffer */
|
||||
size_t input_len; /*!< Length of input data */
|
||||
} esp_tee_sec_storage_aead_ctx_t;
|
||||
|
||||
/**
|
||||
* @brief Structure holding the X and Y components of the ECDSA public key
|
||||
*
|
||||
*/
|
||||
typedef struct {
|
||||
uint8_t pub_x[MAX_ECDSA_SUPPORTED_KEY_LEN]; /*!< X component */
|
||||
uint8_t pub_y[MAX_ECDSA_SUPPORTED_KEY_LEN]; /*!< Y component */
|
||||
} __attribute__((__packed__)) esp_tee_sec_storage_pubkey_t;
|
||||
} __attribute__((__packed__)) esp_tee_sec_storage_ecdsa_pubkey_t;
|
||||
|
||||
/**
|
||||
* @brief Structure holding the R and S components
|
||||
* of the ECDSA signature
|
||||
* @brief Structure holding the R and S components of the ECDSA signature
|
||||
*
|
||||
*/
|
||||
typedef struct {
|
||||
uint8_t sign_r[MAX_ECDSA_SUPPORTED_KEY_LEN]; /*!< R component */
|
||||
uint8_t sign_s[MAX_ECDSA_SUPPORTED_KEY_LEN]; /*!< S component */
|
||||
} __attribute__((__packed__)) esp_tee_sec_storage_sign_t;
|
||||
} __attribute__((__packed__)) esp_tee_sec_storage_ecdsa_sign_t;
|
||||
|
||||
#if ESP_TEE_BUILD && !(__DOXYGEN__)
|
||||
/**
|
||||
* @brief Initialize the TEE secure storage partition
|
||||
* @brief Initialize the secure storage
|
||||
*
|
||||
* @note Must be invoked as part of the TEE initialization sequence.
|
||||
*
|
||||
* @return esp_err_t ESP_OK on success, appropriate error code otherwise.
|
||||
*/
|
||||
esp_err_t esp_tee_sec_storage_init(void);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Generate a unique key and store it in the given secure storage slot
|
||||
* @brief Clear a key from secure storage
|
||||
*
|
||||
* @param slot_id secure storage slot ID
|
||||
* @param key_type secure storage key type to generate
|
||||
* @param key_id Key identifier string
|
||||
*
|
||||
* @return esp_err_t ESP_OK on success, appropriate error code otherwise.
|
||||
*/
|
||||
esp_err_t esp_tee_sec_storage_gen_key(uint16_t slot_id, esp_tee_sec_storage_type_t key_type);
|
||||
esp_err_t esp_tee_sec_storage_clear_key(const char *key_id);
|
||||
|
||||
/**
|
||||
* @brief Generate a unique key and store it in the secure storage
|
||||
*
|
||||
* @param cfg Pointer to the key configuration
|
||||
*
|
||||
* @return esp_err_t ESP_OK on success, appropriate error code otherwise.
|
||||
*/
|
||||
esp_err_t esp_tee_sec_storage_gen_key(const esp_tee_sec_storage_key_cfg_t *cfg);
|
||||
|
||||
/**
|
||||
* @brief Generate and return the signature for the specified message digest using
|
||||
* the key pair located in the given secure storage slot.
|
||||
* the key pair located in the secure storage.
|
||||
*
|
||||
* @param[in] slot_id secure storage slot ID
|
||||
* @param[in] key_type secure storage key type
|
||||
* @param[in] cfg Pointer to the key configuration
|
||||
* @param[in] hash Message digest
|
||||
* @param[in] hlen Digest length
|
||||
* @param[out] out_sign Output context holding the signature
|
||||
*
|
||||
* @return esp_err_t ESP_OK on success, appropriate error code otherwise.
|
||||
*/
|
||||
esp_err_t esp_tee_sec_storage_get_signature(uint16_t slot_id, esp_tee_sec_storage_type_t key_type, uint8_t *hash, size_t hlen, esp_tee_sec_storage_sign_t *out_sign);
|
||||
esp_err_t esp_tee_sec_storage_ecdsa_sign(const esp_tee_sec_storage_key_cfg_t *cfg, const uint8_t *hash, size_t hlen, esp_tee_sec_storage_ecdsa_sign_t *out_sign);
|
||||
|
||||
/**
|
||||
* @brief Return the public key for the given secure storage slot
|
||||
* @brief Return the public key from secure storage
|
||||
*
|
||||
* @param[in] slot_id secure storage slot ID
|
||||
* @param[in] key_type secure storage key type
|
||||
* @param[out] pubkey Output context holding the public key
|
||||
* @param[in] cfg Pointer to the key configuration
|
||||
* @param[out] out_pubkey Output context holding the public key
|
||||
*
|
||||
* @return esp_err_t ESP_OK on success, appropriate error code otherwise.
|
||||
*/
|
||||
esp_err_t esp_tee_sec_storage_get_pubkey(uint16_t slot_id, esp_tee_sec_storage_type_t key_type, esp_tee_sec_storage_pubkey_t *pubkey);
|
||||
esp_err_t esp_tee_sec_storage_ecdsa_get_pubkey(const esp_tee_sec_storage_key_cfg_t *cfg, esp_tee_sec_storage_ecdsa_pubkey_t *out_pubkey);
|
||||
|
||||
/**
|
||||
* @brief Check whether the given slot in the secure storage is empty or not
|
||||
* @brief Perform encryption using AES256-GCM with the key from secure storage
|
||||
*
|
||||
* @param slot_id secure storage slot ID
|
||||
*
|
||||
* @return bool true: slot is empty; false otherwise.
|
||||
*/
|
||||
bool esp_tee_sec_storage_is_slot_empty(uint16_t slot_id);
|
||||
|
||||
/**
|
||||
* @brief Erase the given secure storage slot
|
||||
*
|
||||
* @param slot_id secure storage slot ID
|
||||
*
|
||||
* @return esp_err_t ESP_OK on success, appropriate error code otherwise.
|
||||
*/
|
||||
esp_err_t esp_tee_sec_storage_clear_slot(uint16_t slot_id);
|
||||
|
||||
/**
|
||||
* @brief Perform encryption using AES256-GCM with the key stored in the specified slot
|
||||
*
|
||||
* @param[in] slot_id Secure storage slot ID containing the AES-GCM key
|
||||
* @param[in] input Pointer to the input data buffer
|
||||
* @param[in] len Length of the input data
|
||||
* @param[in] aad Pointer to the Additional Authenticated Data (AAD)
|
||||
* @param[in] aad_len Length of the AAD
|
||||
* @param[out] tag Pointer to the authentication tag buffer
|
||||
* @param[out] tag_len Length of the authentication tag
|
||||
* @param[out] output Pointer to the output data buffer
|
||||
*
|
||||
* @return esp_err_t ESP_OK on success, appropriate error code otherwise.
|
||||
*/
|
||||
esp_err_t esp_tee_sec_storage_encrypt(uint16_t slot_id, uint8_t *input, uint8_t len, uint8_t *aad,
|
||||
uint16_t aad_len, uint8_t *tag, uint16_t tag_len, uint8_t *output);
|
||||
|
||||
/**
|
||||
* @brief Perform decryption using AES256-GCM with the key stored in the specified slot
|
||||
*
|
||||
* @param[in] slot_id Secure storage slot ID containing the AES-GCM key
|
||||
* @param[in] input Pointer to the input data buffer
|
||||
* @param[in] len Length of the input data
|
||||
* @param[in] aad Pointer to the Additional Authenticated Data (AAD)
|
||||
* @param[in] aad_len Length of the AAD
|
||||
* @param[in] tag Pointer to the authentication tag buffer
|
||||
* @param[in] tag_len Length of the authentication tag
|
||||
* @param[in] ctx Pointer to the AEAD operation context
|
||||
* @param[out] tag Pointer to the authentication tag buffer
|
||||
* @param[in] tag_len Length of the authentication tag
|
||||
* @param[out] output Pointer to the output data buffer
|
||||
*
|
||||
* @return esp_err_t ESP_OK on success, appropriate error code otherwise.
|
||||
*/
|
||||
esp_err_t esp_tee_sec_storage_decrypt(uint16_t slot_id, uint8_t *input, uint8_t len, uint8_t *aad,
|
||||
uint16_t aad_len, uint8_t *tag, uint16_t tag_len, uint8_t *output);
|
||||
esp_err_t esp_tee_sec_storage_aead_encrypt(const esp_tee_sec_storage_aead_ctx_t *ctx, uint8_t *tag, size_t tag_len, uint8_t *output);
|
||||
|
||||
/**
|
||||
* @brief Perform decryption using AES256-GCM with the key from secure storage
|
||||
*
|
||||
* @param[in] ctx Pointer to the AEAD operation context
|
||||
* @param[in] tag Pointer to the authentication tag buffer
|
||||
* @param[in] tag_len Length of the authentication tag
|
||||
* @param[out] output Pointer to the output data buffer
|
||||
*
|
||||
* @return esp_err_t ESP_OK on success, appropriate error code otherwise.
|
||||
*/
|
||||
esp_err_t esp_tee_sec_storage_aead_decrypt(const esp_tee_sec_storage_aead_ctx_t *ctx, const uint8_t *tag, size_t tag_len, uint8_t *output);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
@ -5,53 +5,43 @@
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "esp_log.h"
|
||||
#include "esp_cpu.h"
|
||||
#include "esp_fault.h"
|
||||
#include "esp_flash.h"
|
||||
#include "esp_efuse.h"
|
||||
#include "esp_random.h"
|
||||
#include "spi_flash_mmap.h"
|
||||
|
||||
#include "mbedtls/aes.h"
|
||||
#include "mbedtls/gcm.h"
|
||||
#include "mbedtls/sha256.h"
|
||||
|
||||
#include "mbedtls/entropy.h"
|
||||
#include "mbedtls/ctr_drbg.h"
|
||||
#include "mbedtls/ecdsa.h"
|
||||
#include "mbedtls/error.h"
|
||||
|
||||
#include "esp_flash.h"
|
||||
#include "esp_efuse.h"
|
||||
#include "soc/efuse_reg.h"
|
||||
#include "rom/efuse.h"
|
||||
#if SOC_HMAC_SUPPORTED
|
||||
#include "rom/hmac.h"
|
||||
#endif
|
||||
#include "esp_rom_sys.h"
|
||||
#include "nvs.h"
|
||||
#include "nvs_flash.h"
|
||||
|
||||
#include "esp_random.h"
|
||||
#include "esp_tee.h"
|
||||
#include "esp_tee_flash.h"
|
||||
#include "esp_tee_sec_storage.h"
|
||||
|
||||
#include "secure_service_num.h"
|
||||
#include "esp_rom_sys.h"
|
||||
#include "esp_log.h"
|
||||
#include "spi_flash_mmap.h"
|
||||
|
||||
#define ALIGN_UP(num, align) (((num) + ((align) - 1)) & ~((align) - 1))
|
||||
|
||||
#define SECURE_STORAGE_SIZE 2048
|
||||
|
||||
#define AES256_GCM_KEY_LEN 32
|
||||
#define AES256_GCM_KEY_BITS (AES256_GCM_KEY_LEN * 8)
|
||||
#define AES256_KEY_LEN 32
|
||||
#define AES256_KEY_BITS (AES256_KEY_LEN * 8)
|
||||
#define AES256_DEFAULT_IV_LEN 16
|
||||
#define AES256_GCM_IV_LEN 12
|
||||
#define AES256_GCM_TAG_LEN 16
|
||||
#define AES256_GCM_AAD_LEN 16
|
||||
|
||||
#define ECDSA_SECP256R1_KEY_LEN 32
|
||||
#define ECDSA_SECP192R1_KEY_LEN 24
|
||||
|
||||
/* Structure to hold metadata for secure storage slots */
|
||||
typedef struct {
|
||||
uint16_t owner_id; /* Identifier for the owner of this slot */
|
||||
uint16_t slot_id; /* Unique identifier for this storage slot */
|
||||
uint8_t reserved; /* Reserved for future use */
|
||||
uint8_t iv[AES256_GCM_IV_LEN]; /* Initialization vector for AES-GCM */
|
||||
uint8_t tag[AES256_GCM_TAG_LEN]; /* Authentication tag for AES-GCM */
|
||||
uint8_t data_type; /* Type of data stored in this slot */
|
||||
uint16_t data_len; /* Length of the data stored in this slot */
|
||||
} __attribute__((aligned(4))) __attribute__((__packed__)) sec_stg_metadata_t;
|
||||
#define EKEY_SEED 0xAEBE5A5A
|
||||
#define TKEY_SEED 0xCEDEA5A5
|
||||
|
||||
/* Structure to hold ECDSA SECP256R1 key pair */
|
||||
typedef struct {
|
||||
@ -65,38 +55,36 @@ typedef struct {
|
||||
uint8_t pub_key[2 * ECDSA_SECP192R1_KEY_LEN]; /* Public key for ECDSA SECP192R1 (X and Y coordinates) */
|
||||
} __attribute__((aligned(4))) __attribute__((__packed__)) sec_stg_ecdsa_secp192r1_t;
|
||||
|
||||
/* Structure to hold AES-256 GCM key and IV */
|
||||
/* Structure to hold AES-256 key and IV */
|
||||
typedef struct {
|
||||
uint8_t key[AES256_GCM_KEY_LEN]; /* Key for AES-256 GCM */
|
||||
uint8_t iv[AES256_GCM_IV_LEN]; /* Initialization vector for AES-256 GCM */
|
||||
} __attribute__((aligned(4))) __attribute__((__packed__)) sec_stg_aes256_gcm_t;
|
||||
uint8_t key[AES256_KEY_LEN]; /* Key for AES-256 */
|
||||
uint8_t iv[AES256_DEFAULT_IV_LEN]; /* Initialization vector for AES-256 */
|
||||
} __attribute__((aligned(4))) __attribute__((__packed__)) sec_stg_aes256_t;
|
||||
|
||||
/* Union to hold different types of cryptographic keys */
|
||||
typedef union {
|
||||
sec_stg_ecdsa_secp256r1_t ecdsa_secp256r1; /* ECDSA SECP256R1 key pair */
|
||||
sec_stg_ecdsa_secp192r1_t ecdsa_secp192r1; /* ECDSA SECP192R1 key pair */
|
||||
sec_stg_aes256_gcm_t aes256_gcm; /* AES-256 GCM key and IV */
|
||||
/* Structure to hold the cryptographic keys in NVS */
|
||||
typedef struct {
|
||||
const esp_tee_sec_storage_type_t type; /* Type of the key */
|
||||
uint32_t flags; /* Flags associated with the key */
|
||||
union {
|
||||
sec_stg_ecdsa_secp256r1_t ecdsa_secp256r1; /* ECDSA SECP256R1 key pair */
|
||||
sec_stg_ecdsa_secp192r1_t ecdsa_secp192r1; /* ECDSA SECP192R1 key pair */
|
||||
sec_stg_aes256_t aes256; /* AES-256 key and IV */
|
||||
};
|
||||
uint32_t reserved[38]; /* Reserved space for future use */
|
||||
} __attribute__((aligned(4))) __attribute__((__packed__)) sec_stg_key_t;
|
||||
|
||||
_Static_assert(sizeof(sec_stg_metadata_t) == 36, "Incorrect sec_stg_metadata_t size");
|
||||
_Static_assert(sizeof(sec_stg_key_t) == 96, "Incorrect sec_stg_key_t size");
|
||||
_Static_assert(sizeof(sec_stg_key_t) == 256, "Incorrect sec_stg_key_t size");
|
||||
|
||||
// Need this buffer to read the flash data and then modify and write it back
|
||||
// esp_rom_spiflash_write requires that we erase the region before writing to it
|
||||
// TODO: IDF-7586
|
||||
static uint8_t tmp_buf[SECURE_STORAGE_SIZE];
|
||||
#define TEE_SEC_STG_PART_LABEL "tee_nvs"
|
||||
#define TEE_SEC_STG_NVS_NAMESPACE "tee_sec_stg"
|
||||
|
||||
// AAD buffer
|
||||
static uint8_t aad_buf[AES256_GCM_AAD_LEN];
|
||||
|
||||
// Partition for the secure storage partition
|
||||
static esp_partition_pos_t part_pos;
|
||||
static nvs_handle_t tee_nvs_hdl;
|
||||
|
||||
static const char *TAG = "secure_storage";
|
||||
|
||||
/* ---------------------------------------------- Helper APIs ------------------------------------------------- */
|
||||
#if CONFIG_SECURE_TEE_SEC_STG_KEY_EFUSE_BLK > 9
|
||||
#error "TEE Secure Storage: Configured eFuse block for encryption key out of range! (see CONFIG_SECURE_TEE_SEC_STG_KEY_EFUSE_BLK)"
|
||||
#if CONFIG_SECURE_TEE_SEC_STG_EFUSE_HMAC_KEY_ID < 0
|
||||
#error "TEE Secure Storage: Configured eFuse block (CONFIG_SECURE_TEE_SEC_STG_EFUSE_HMAC_KEY_ID) out of range!"
|
||||
#endif
|
||||
|
||||
static int buffer_hexdump(const char *label, const void *buffer, size_t length)
|
||||
@ -138,224 +126,142 @@ static int buffer_hexdump(const char *label, const void *buffer, size_t length)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static esp_err_t get_sec_stg_encr_key(uint8_t *key_buf, size_t key_buf_len)
|
||||
{
|
||||
// NOTE: Key should strictly be of 256-bits
|
||||
if (!key_buf || key_buf_len != AES256_GCM_KEY_LEN) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
esp_err_t err = ESP_OK;
|
||||
|
||||
#if CONFIG_SECURE_TEE_SEC_STG_MODE_RELEASE
|
||||
esp_efuse_block_t blk = (esp_efuse_block_t)(CONFIG_SECURE_TEE_SEC_STG_KEY_EFUSE_BLK);
|
||||
|
||||
if (blk < EFUSE_BLK_KEY0 || blk >= EFUSE_BLK_KEY_MAX) {
|
||||
ESP_LOGE(TAG, "Invalid eFuse block - %d", blk);
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
esp_efuse_purpose_t blk_purpose = esp_efuse_get_key_purpose(blk);
|
||||
if (blk_purpose != ESP_EFUSE_KEY_PURPOSE_USER) {
|
||||
ESP_LOGE(TAG, "Invalid eFuse block purpose - %d", blk_purpose);
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
|
||||
memset(key_buf, 0x00, key_buf_len);
|
||||
err = esp_efuse_read_block(blk, key_buf, 0, AES256_GCM_KEY_BITS);
|
||||
if (err != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Failed to read eFuse block (err - %d)", err);
|
||||
return err;
|
||||
}
|
||||
#else
|
||||
memset(key_buf, 0xA5, key_buf_len);
|
||||
#endif
|
||||
|
||||
// Check if eFuse is empty
|
||||
uint8_t empty_key_buf[AES256_GCM_KEY_LEN] = {0};
|
||||
if (memcmp(empty_key_buf, key_buf, key_buf_len) == 0) {
|
||||
ESP_LOGE(TAG, "All-zeroes key read from eFuse");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static int rand_func(void *rng_state, unsigned char *output, size_t len)
|
||||
{
|
||||
esp_fill_random(output, len);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int secure_storage_write(uint16_t slot_id, uint8_t *data, size_t len, uint8_t type)
|
||||
#if CONFIG_SECURE_TEE_SEC_STG_MODE_RELEASE
|
||||
static esp_err_t compute_nvs_keys_with_hmac(ets_efuse_block_t hmac_key, nvs_sec_cfg_t *cfg)
|
||||
{
|
||||
uint8_t iv[AES256_GCM_IV_LEN];
|
||||
uint8_t tag[AES256_GCM_TAG_LEN];
|
||||
uint8_t key[AES256_GCM_KEY_LEN];
|
||||
uint8_t out_data[256] = {0};
|
||||
uint32_t ekey_seed[8] = {[0 ... 7] = EKEY_SEED};
|
||||
uint32_t tkey_seed[8] = {[0 ... 7] = TKEY_SEED};
|
||||
|
||||
buffer_hexdump("Plaintext data", data, len);
|
||||
memset(cfg, 0x00, sizeof(nvs_sec_cfg_t));
|
||||
|
||||
mbedtls_gcm_context gcm;
|
||||
mbedtls_gcm_init(&gcm);
|
||||
int ret = -1;
|
||||
ets_hmac_enable();
|
||||
ret = ets_hmac_calculate_message(hmac_key, ekey_seed, sizeof(ekey_seed), (uint8_t *)cfg->eky);
|
||||
ret = ets_hmac_calculate_message(hmac_key, tkey_seed, sizeof(tkey_seed), (uint8_t *)cfg->tky);
|
||||
ets_hmac_disable();
|
||||
|
||||
esp_err_t err = get_sec_stg_encr_key(key, sizeof(key));
|
||||
if (ret != 0) {
|
||||
ESP_LOGE(TAG, "Failed to calculate seed HMAC");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
ESP_FAULT_ASSERT(ret == 0);
|
||||
|
||||
/* NOTE: If the XTS E-key and T-key are the same, we have a hash collision */
|
||||
ESP_FAULT_ASSERT(memcmp(cfg->eky, cfg->tky, NVS_KEY_SIZE) != 0);
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
static esp_err_t read_security_cfg_hmac(nvs_sec_cfg_t *cfg)
|
||||
{
|
||||
if (cfg == NULL) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
#if CONFIG_SECURE_TEE_SEC_STG_MODE_RELEASE
|
||||
ets_efuse_block_t hmac_key = (ets_efuse_block_t)(ETS_EFUSE_BLOCK_KEY0 + CONFIG_SECURE_TEE_SEC_STG_EFUSE_HMAC_KEY_ID);
|
||||
ets_efuse_purpose_t hmac_efuse_blk_purpose = ets_efuse_get_key_purpose(hmac_key);
|
||||
if (hmac_efuse_blk_purpose != ETS_EFUSE_KEY_PURPOSE_HMAC_UP) {
|
||||
ESP_LOGE(TAG, "HMAC key is not burnt in eFuse block");
|
||||
return ESP_ERR_NOT_FOUND;
|
||||
}
|
||||
|
||||
esp_err_t err = compute_nvs_keys_with_hmac(hmac_key, cfg);
|
||||
if (err != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Failed to fetch key from eFuse!");
|
||||
goto exit;
|
||||
return err;
|
||||
}
|
||||
#else
|
||||
memset(&cfg->eky, 0x33, sizeof(cfg->eky));
|
||||
memset(&cfg->tky, 0xCC, sizeof(cfg->tky));
|
||||
#endif
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
static esp_err_t secure_storage_find_key(const char *key_id)
|
||||
{
|
||||
nvs_type_t out_type;
|
||||
return nvs_find_key(tee_nvs_hdl, key_id, &out_type);
|
||||
}
|
||||
|
||||
static esp_err_t secure_storage_write(const char *key_id, const void *data, size_t len)
|
||||
{
|
||||
esp_err_t err = nvs_set_blob(tee_nvs_hdl, key_id, data, len);
|
||||
if (err != ESP_OK) {
|
||||
return err;
|
||||
}
|
||||
|
||||
int ret = mbedtls_gcm_setkey(&gcm, MBEDTLS_CIPHER_ID_AES, key, AES256_GCM_KEY_BITS);
|
||||
if (ret != 0) {
|
||||
ESP_LOGE(TAG, "Error in setting key: %d", ret);
|
||||
err = ESP_FAIL;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
// Generate different IV every time GCM encrypt is called
|
||||
esp_fill_random(iv, AES256_GCM_IV_LEN);
|
||||
|
||||
ret = mbedtls_gcm_crypt_and_tag(&gcm, MBEDTLS_GCM_ENCRYPT, len, iv, AES256_GCM_IV_LEN,
|
||||
aad_buf, AES256_GCM_AAD_LEN, data, out_data, AES256_GCM_TAG_LEN, tag);
|
||||
if (ret != 0) {
|
||||
ESP_LOGE(TAG, "Error in encrypting data: %d", ret);
|
||||
err = ESP_FAIL;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
buffer_hexdump("Encrypted data", out_data, len);
|
||||
buffer_hexdump("TAG data", tag, sizeof(tag));
|
||||
|
||||
// Currently keeping the owner ID as 0
|
||||
sec_stg_metadata_t metadata;
|
||||
metadata.owner_id = 0;
|
||||
metadata.slot_id = slot_id;
|
||||
memcpy(metadata.iv, iv, AES256_GCM_IV_LEN);
|
||||
memcpy(metadata.tag, tag, AES256_GCM_TAG_LEN);
|
||||
metadata.data_type = type;
|
||||
metadata.data_len = len;
|
||||
|
||||
uint32_t slot_offset = (sizeof(sec_stg_metadata_t) + sizeof(sec_stg_key_t)) * slot_id;
|
||||
|
||||
/* ROM flash APIs require the region to be erased before writing to it.
|
||||
* For that, we read the entire sector, make changes in read buffer, and then write
|
||||
* the entire data back in flash.
|
||||
*
|
||||
* This opens up a small window when the sector has been erased but the device resets before writing the
|
||||
* data back in flash. This can lead to loss of data.
|
||||
*
|
||||
* TODO: IDF-7586
|
||||
*/
|
||||
ret = esp_tee_flash_read(part_pos.offset, (uint32_t *)tmp_buf, SECURE_STORAGE_SIZE, false);
|
||||
if (ret != 0) {
|
||||
ESP_LOGE(TAG, "Error reading flash contents: %d", ret);
|
||||
err = ESP_ERR_FLASH_OP_FAIL;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
memcpy(&tmp_buf[slot_offset], &metadata, sizeof(sec_stg_metadata_t));
|
||||
memcpy(&tmp_buf[slot_offset + sizeof(sec_stg_metadata_t)], out_data, len);
|
||||
|
||||
ret = esp_tee_flash_erase_range(part_pos.offset, ALIGN_UP(SECURE_STORAGE_SIZE, FLASH_SECTOR_SIZE));
|
||||
ret |= esp_tee_flash_write(part_pos.offset, (uint32_t *)tmp_buf, SECURE_STORAGE_SIZE, false);
|
||||
if (ret != 0) {
|
||||
ESP_LOGE(TAG, "Error writing encrypted data: %d", ret);
|
||||
err = ESP_ERR_FLASH_OP_FAIL;
|
||||
goto exit;
|
||||
}
|
||||
err = ESP_OK;
|
||||
|
||||
exit:
|
||||
mbedtls_gcm_free(&gcm);
|
||||
err = nvs_commit(tee_nvs_hdl);
|
||||
return err;
|
||||
}
|
||||
|
||||
static esp_err_t secure_storage_read(uint16_t slot_id, uint8_t *data, size_t len, uint8_t type)
|
||||
static esp_err_t secure_storage_read(const char *key_id, void *data, size_t *len)
|
||||
{
|
||||
esp_err_t err;
|
||||
|
||||
sec_stg_metadata_t metadata;
|
||||
uint32_t slot_offset = (sizeof(sec_stg_metadata_t) + sizeof(sec_stg_key_t)) * slot_id;
|
||||
|
||||
uint8_t key[AES256_GCM_KEY_BITS / 8];
|
||||
uint8_t flash_data[256] = {0};
|
||||
|
||||
int ret = esp_tee_flash_read(part_pos.offset + slot_offset, (uint32_t *)&metadata, sizeof(sec_stg_metadata_t), false);
|
||||
if (ret != 0) {
|
||||
ESP_LOGE(TAG, "Error reading metadata: %d", ret);
|
||||
err = ESP_ERR_FLASH_OP_FAIL;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if (metadata.data_type != type || metadata.data_len != len) {
|
||||
ESP_LOGE(TAG, "Data type/length mismatch");
|
||||
err = ESP_ERR_NOT_FOUND;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
ret = esp_tee_flash_read(part_pos.offset + slot_offset + sizeof(sec_stg_metadata_t), (uint32_t *)flash_data, metadata.data_len, false);
|
||||
if (ret != 0) {
|
||||
ESP_LOGE(TAG, "Error reading data: %d", ret);
|
||||
err = ESP_ERR_FLASH_OP_FAIL;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
buffer_hexdump("Encrypted data", flash_data, len);
|
||||
buffer_hexdump("TAG data", metadata.tag, AES256_GCM_TAG_LEN);
|
||||
|
||||
mbedtls_gcm_context gcm;
|
||||
mbedtls_gcm_init(&gcm);
|
||||
|
||||
err = get_sec_stg_encr_key(key, sizeof(key));
|
||||
if (err != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Failed to fetch key from eFuse!");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
ret = mbedtls_gcm_setkey(&gcm, MBEDTLS_CIPHER_ID_AES, key, AES256_GCM_KEY_BITS);
|
||||
if (ret != 0) {
|
||||
err = ESP_FAIL;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
ret = mbedtls_gcm_auth_decrypt(&gcm, metadata.data_len, metadata.iv, AES256_GCM_IV_LEN,
|
||||
aad_buf, AES256_GCM_AAD_LEN, metadata.tag, AES256_GCM_TAG_LEN, flash_data, data);
|
||||
if (ret != 0) {
|
||||
ESP_LOGE(TAG, "Error in decrypting data: %d", ret);
|
||||
err = ESP_FAIL;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
buffer_hexdump("Decrypted data", data, len);
|
||||
err = ESP_OK;
|
||||
|
||||
cleanup:
|
||||
mbedtls_gcm_free(&gcm);
|
||||
exit:
|
||||
return err;
|
||||
return nvs_get_blob(tee_nvs_hdl, key_id, data, len);
|
||||
}
|
||||
|
||||
/* ---------------------------------------------- Interface APIs ------------------------------------------------- */
|
||||
|
||||
esp_err_t esp_tee_sec_storage_init(void)
|
||||
{
|
||||
ESP_LOGI(TAG, "Initializing secure storage...");
|
||||
esp_partition_info_t part_info = {};
|
||||
esp_err_t err = esp_tee_flash_find_partition(PART_TYPE_DATA, PART_SUBTYPE_DATA_TEE_SEC_STORAGE, NULL, &part_info);
|
||||
nvs_sec_cfg_t cfg = {};
|
||||
esp_err_t err = read_security_cfg_hmac(&cfg);
|
||||
if (err != ESP_OK) {
|
||||
ESP_LOGE(TAG, "No secure storage partition found (0x%08x)", err);
|
||||
return err;
|
||||
} else {
|
||||
#if CONFIG_SECURE_TEE_SEC_STG_MODE_DEVELOPMENT
|
||||
ESP_LOGW(TAG, "TEE Secure Storage enabled in insecure DEVELOPMENT mode");
|
||||
#endif
|
||||
// Take backup of the partition for future usage
|
||||
part_pos = part_info.pos;
|
||||
}
|
||||
|
||||
err = nvs_flash_secure_init_partition(TEE_SEC_STG_PART_LABEL, &cfg);
|
||||
if (err != ESP_OK) {
|
||||
return err;
|
||||
}
|
||||
|
||||
err = nvs_open_from_partition(TEE_SEC_STG_PART_LABEL, TEE_SEC_STG_NVS_NAMESPACE, NVS_READWRITE, &tee_nvs_hdl);
|
||||
if (err != ESP_OK) {
|
||||
return err;
|
||||
}
|
||||
|
||||
#if CONFIG_SECURE_TEE_SEC_STG_MODE_DEVELOPMENT
|
||||
ESP_LOGW(TAG, "TEE Secure Storage enabled in insecure DEVELOPMENT mode");
|
||||
#endif
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t esp_tee_sec_storage_clear_key(const char *key_id)
|
||||
{
|
||||
if (secure_storage_find_key(key_id) != ESP_OK) {
|
||||
return ESP_ERR_NOT_FOUND;
|
||||
}
|
||||
|
||||
sec_stg_key_t keyctx;
|
||||
size_t keyctx_len = sizeof(keyctx);
|
||||
|
||||
esp_err_t err = secure_storage_read(key_id, (void *)&keyctx, &keyctx_len);
|
||||
if (err != ESP_OK) {
|
||||
return err;
|
||||
}
|
||||
|
||||
if (keyctx.flags & SEC_STORAGE_FLAG_WRITE_ONCE) {
|
||||
ESP_LOGE(TAG, "Key is write-once only and cannot be cleared!");
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
|
||||
err = nvs_erase_key(tee_nvs_hdl, key_id);
|
||||
if (err != ESP_OK) {
|
||||
return err;
|
||||
}
|
||||
|
||||
err = nvs_commit(tee_nvs_hdl);
|
||||
return err;
|
||||
}
|
||||
|
||||
static int generate_ecdsa_key(sec_stg_key_t *keyctx, esp_tee_sec_storage_type_t key_type)
|
||||
{
|
||||
if (keyctx == NULL) {
|
||||
@ -370,19 +276,18 @@ static int generate_ecdsa_key(sec_stg_key_t *keyctx, esp_tee_sec_storage_type_t
|
||||
curve_id = MBEDTLS_ECP_DP_SECP192R1;
|
||||
key_len = ECDSA_SECP192R1_KEY_LEN;
|
||||
#else
|
||||
ESP_LOGE(TAG, "Unsupported key type!");
|
||||
ESP_LOGE(TAG, "Unsupported key-type!");
|
||||
return -1;
|
||||
#endif
|
||||
}
|
||||
|
||||
ESP_LOGI(TAG, "Generating ECDSA key for curve %d...", curve_id);
|
||||
ESP_LOGD(TAG, "Generating ECDSA key for curve %d...", curve_id);
|
||||
|
||||
mbedtls_ecdsa_context ctxECDSA;
|
||||
mbedtls_ecdsa_init(&ctxECDSA);
|
||||
|
||||
int ret = mbedtls_ecdsa_genkey(&ctxECDSA, curve_id, rand_func, NULL);
|
||||
if (ret != 0) {
|
||||
ESP_LOGE(TAG, "Failed to generate ECDSA key");
|
||||
goto exit;
|
||||
}
|
||||
|
||||
@ -425,48 +330,49 @@ exit:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int generate_aes256_gcm_key(sec_stg_key_t *keyctx)
|
||||
static int generate_aes256_key(sec_stg_key_t *keyctx)
|
||||
{
|
||||
if (keyctx == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
ESP_LOGI(TAG, "Generating AES-256-GCM key...");
|
||||
ESP_LOGD(TAG, "Generating AES-256 key...");
|
||||
|
||||
esp_fill_random(&keyctx->aes256_gcm.key, AES256_GCM_KEY_LEN);
|
||||
esp_fill_random(&keyctx->aes256_gcm.iv, AES256_GCM_IV_LEN);
|
||||
esp_fill_random(&keyctx->aes256.key, AES256_KEY_LEN);
|
||||
esp_fill_random(&keyctx->aes256.iv, AES256_DEFAULT_IV_LEN);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
esp_err_t esp_tee_sec_storage_gen_key(uint16_t slot_id, esp_tee_sec_storage_type_t key_type)
|
||||
esp_err_t esp_tee_sec_storage_gen_key(const esp_tee_sec_storage_key_cfg_t *cfg)
|
||||
{
|
||||
if (slot_id > MAX_SEC_STG_SLOT_ID) {
|
||||
ESP_LOGE(TAG, "Invalid slot ID");
|
||||
if (cfg == NULL || cfg->id == NULL) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
if (!esp_tee_sec_storage_is_slot_empty(slot_id)) {
|
||||
ESP_LOGE(TAG, "Slot already occupied - clear before reuse");
|
||||
if (secure_storage_find_key(cfg->id) == ESP_OK) {
|
||||
ESP_LOGE(TAG, "Key ID already exists");
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
|
||||
int ret = -1;
|
||||
sec_stg_key_t keyctx;
|
||||
sec_stg_key_t keyctx = {
|
||||
.type = cfg->type,
|
||||
.flags = cfg->flags,
|
||||
};
|
||||
|
||||
switch (key_type) {
|
||||
switch (cfg->type) {
|
||||
case ESP_SEC_STG_KEY_ECDSA_SECP256R1:
|
||||
#if CONFIG_SECURE_TEE_SEC_STG_SUPPORT_SECP192R1_SIGN
|
||||
case ESP_SEC_STG_KEY_ECDSA_SECP192R1:
|
||||
#endif
|
||||
if (generate_ecdsa_key(&keyctx, key_type) != 0) {
|
||||
ESP_LOGE(TAG, "Failed to generate ECDSA keypair (%d)", ret);
|
||||
if (generate_ecdsa_key(&keyctx, cfg->type) != 0) {
|
||||
ESP_LOGE(TAG, "Failed to generate ECDSA keypair");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
break;
|
||||
case ESP_SEC_STG_KEY_AES256:
|
||||
if (generate_aes256_gcm_key(&keyctx) != 0) {
|
||||
ESP_LOGE(TAG, "Failed to generate AES key (%d)", ret);
|
||||
if (generate_aes256_key(&keyctx) != 0) {
|
||||
ESP_LOGE(TAG, "Failed to generate AES key");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
break;
|
||||
@ -475,33 +381,41 @@ esp_err_t esp_tee_sec_storage_gen_key(uint16_t slot_id, esp_tee_sec_storage_type
|
||||
return ESP_ERR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
return secure_storage_write(slot_id, (uint8_t *)&keyctx, sizeof(keyctx), key_type);
|
||||
return secure_storage_write(cfg->id, (void *)&keyctx, sizeof(keyctx));
|
||||
}
|
||||
|
||||
esp_err_t esp_tee_sec_storage_get_signature(uint16_t slot_id, esp_tee_sec_storage_type_t key_type, uint8_t *hash, size_t hlen, esp_tee_sec_storage_sign_t *out_sign)
|
||||
esp_err_t esp_tee_sec_storage_ecdsa_sign(const esp_tee_sec_storage_key_cfg_t *cfg, const uint8_t *hash, size_t hlen, esp_tee_sec_storage_ecdsa_sign_t *out_sign)
|
||||
{
|
||||
if (slot_id > MAX_SEC_STG_SLOT_ID || hash == NULL || out_sign == NULL) {
|
||||
if (cfg == NULL || cfg->id == NULL || hash == NULL || out_sign == NULL || hlen == 0) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
if (hlen == 0) {
|
||||
return ESP_ERR_INVALID_SIZE;
|
||||
}
|
||||
|
||||
#if !CONFIG_SECURE_TEE_SEC_STG_SUPPORT_SECP192R1_SIGN
|
||||
if (key_type == ESP_SEC_STG_KEY_ECDSA_SECP192R1) {
|
||||
ESP_LOGE(TAG, "Unsupported key type!");
|
||||
if (cfg->type == ESP_SEC_STG_KEY_ECDSA_SECP192R1) {
|
||||
ESP_LOGE(TAG, "Unsupported key-type!");
|
||||
return ESP_ERR_NOT_SUPPORTED;
|
||||
}
|
||||
#endif
|
||||
|
||||
sec_stg_key_t keyctx;
|
||||
esp_err_t err = secure_storage_read(slot_id, (uint8_t *)&keyctx, sizeof(sec_stg_key_t), key_type);
|
||||
esp_err_t err = secure_storage_find_key(cfg->id);
|
||||
if (err != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Failed to fetch key from slot");
|
||||
ESP_LOGE(TAG, "Key ID not found");
|
||||
return err;
|
||||
}
|
||||
|
||||
sec_stg_key_t keyctx;
|
||||
size_t keyctx_len = sizeof(keyctx);
|
||||
err = secure_storage_read(cfg->id, (void *)&keyctx, &keyctx_len);
|
||||
if (err != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Failed to fetch key from storage");
|
||||
return err;
|
||||
}
|
||||
|
||||
if (keyctx.type != cfg->type) {
|
||||
ESP_LOGE(TAG, "Key type mismatch");
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
|
||||
mbedtls_mpi r, s;
|
||||
mbedtls_ecp_keypair priv_key;
|
||||
mbedtls_ecdsa_context sign_ctx;
|
||||
@ -513,18 +427,15 @@ esp_err_t esp_tee_sec_storage_get_signature(uint16_t slot_id, esp_tee_sec_storag
|
||||
|
||||
size_t key_len = 0;
|
||||
int ret = -1;
|
||||
if (key_type == ESP_SEC_STG_KEY_ECDSA_SECP256R1) {
|
||||
|
||||
if (cfg->type == ESP_SEC_STG_KEY_ECDSA_SECP256R1) {
|
||||
ret = mbedtls_ecp_read_key(MBEDTLS_ECP_DP_SECP256R1, &priv_key, keyctx.ecdsa_secp256r1.priv_key, sizeof(keyctx.ecdsa_secp256r1.priv_key));
|
||||
key_len = ECDSA_SECP256R1_KEY_LEN;
|
||||
#if CONFIG_SECURE_TEE_SEC_STG_SUPPORT_SECP192R1_SIGN
|
||||
} else if (key_type == ESP_SEC_STG_KEY_ECDSA_SECP192R1) {
|
||||
} else if (cfg->type == ESP_SEC_STG_KEY_ECDSA_SECP192R1) {
|
||||
ret = mbedtls_ecp_read_key(MBEDTLS_ECP_DP_SECP192R1, &priv_key, keyctx.ecdsa_secp192r1.priv_key, sizeof(keyctx.ecdsa_secp192r1.priv_key));
|
||||
key_len = ECDSA_SECP192R1_KEY_LEN;
|
||||
#endif
|
||||
} else {
|
||||
ESP_LOGE(TAG, "Unsupported key type for signature generation");
|
||||
err = ESP_ERR_NOT_SUPPORTED;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if (ret != 0) {
|
||||
@ -538,7 +449,7 @@ esp_err_t esp_tee_sec_storage_get_signature(uint16_t slot_id, esp_tee_sec_storag
|
||||
goto exit;
|
||||
}
|
||||
|
||||
ESP_LOGI(TAG, "Generating ECDSA signature...");
|
||||
ESP_LOGD(TAG, "Generating ECDSA signature...");
|
||||
|
||||
ret = mbedtls_ecdsa_sign(&sign_ctx.MBEDTLS_PRIVATE(grp), &r, &s, &sign_ctx.MBEDTLS_PRIVATE(d), hash, hlen,
|
||||
rand_func, NULL);
|
||||
@ -548,7 +459,7 @@ esp_err_t esp_tee_sec_storage_get_signature(uint16_t slot_id, esp_tee_sec_storag
|
||||
goto exit;
|
||||
}
|
||||
|
||||
memset(out_sign, 0x00, sizeof(esp_tee_sec_storage_sign_t));
|
||||
memset(out_sign, 0x00, sizeof(esp_tee_sec_storage_ecdsa_sign_t));
|
||||
|
||||
ret = mbedtls_mpi_write_binary(&r, out_sign->sign_r, key_len);
|
||||
if (ret != 0) {
|
||||
@ -572,142 +483,93 @@ exit:
|
||||
return err;
|
||||
}
|
||||
|
||||
esp_err_t esp_tee_sec_storage_get_pubkey(uint16_t slot_id, esp_tee_sec_storage_type_t key_type, esp_tee_sec_storage_pubkey_t *pubkey)
|
||||
esp_err_t esp_tee_sec_storage_ecdsa_get_pubkey(const esp_tee_sec_storage_key_cfg_t *cfg, esp_tee_sec_storage_ecdsa_pubkey_t *out_pubkey)
|
||||
{
|
||||
if (slot_id > MAX_SEC_STG_SLOT_ID || pubkey == NULL) {
|
||||
if (cfg == NULL || cfg->id == NULL || out_pubkey == NULL) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
sec_stg_key_t keyctx;
|
||||
size_t key_len;
|
||||
uint8_t *pub_key_src;
|
||||
|
||||
if (key_type == ESP_SEC_STG_KEY_ECDSA_SECP256R1) {
|
||||
key_len = ECDSA_SECP256R1_KEY_LEN;
|
||||
pub_key_src = keyctx.ecdsa_secp256r1.pub_key;
|
||||
#if CONFIG_SECURE_TEE_SEC_STG_SUPPORT_SECP192R1_SIGN
|
||||
} else if (key_type == ESP_SEC_STG_KEY_ECDSA_SECP192R1) {
|
||||
key_len = ECDSA_SECP192R1_KEY_LEN;
|
||||
pub_key_src = keyctx.ecdsa_secp192r1.pub_key;
|
||||
#endif
|
||||
} else {
|
||||
ESP_LOGE(TAG, "Unsupported key type");
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
esp_err_t err = secure_storage_read(slot_id, (uint8_t *)&keyctx, sizeof(sec_stg_key_t), key_type);
|
||||
esp_err_t err = secure_storage_find_key(cfg->id);
|
||||
if (err != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Failed to fetch key from slot");
|
||||
ESP_LOGE(TAG, "Key ID not found");
|
||||
return err;
|
||||
}
|
||||
|
||||
// Copy public key components in one shot
|
||||
memcpy(pubkey->pub_x, pub_key_src, key_len);
|
||||
memcpy(pubkey->pub_y, pub_key_src + key_len, key_len);
|
||||
sec_stg_key_t keyctx;
|
||||
size_t keyctx_len = sizeof(keyctx);
|
||||
uint8_t *pub_key_src = NULL;
|
||||
size_t pub_key_len = 0;
|
||||
|
||||
switch (cfg->type) {
|
||||
case ESP_SEC_STG_KEY_ECDSA_SECP256R1:
|
||||
pub_key_src = keyctx.ecdsa_secp256r1.pub_key;
|
||||
pub_key_len = ECDSA_SECP256R1_KEY_LEN;
|
||||
break;
|
||||
#if CONFIG_SECURE_TEE_SEC_STG_SUPPORT_SECP192R1_SIGN
|
||||
case ESP_SEC_STG_KEY_ECDSA_SECP192R1:
|
||||
pub_key_src = keyctx.ecdsa_secp192r1.pub_key;
|
||||
pub_key_len = ECDSA_SECP192R1_KEY_LEN;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
ESP_LOGE(TAG, "Unsupported key-type");
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
err = secure_storage_read(cfg->id, (void *)&keyctx, &keyctx_len);
|
||||
if (err != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Failed to read key from secure storage");
|
||||
return err;
|
||||
}
|
||||
|
||||
if (keyctx.type != cfg->type) {
|
||||
ESP_LOGE(TAG, "Key type mismatch");
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
|
||||
memcpy(out_pubkey->pub_x, pub_key_src, pub_key_len);
|
||||
memcpy(out_pubkey->pub_y, pub_key_src + pub_key_len, pub_key_len);
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
bool esp_tee_sec_storage_is_slot_empty(uint16_t slot_id)
|
||||
{
|
||||
if (slot_id > MAX_SEC_STG_SLOT_ID) {
|
||||
ESP_LOGE(TAG, "Invalid slot ID");
|
||||
return false;
|
||||
}
|
||||
|
||||
sec_stg_metadata_t metadata, blank_metadata;
|
||||
memset(&blank_metadata, 0xFF, sizeof(sec_stg_metadata_t));
|
||||
|
||||
uint32_t slot_offset = (sizeof(sec_stg_metadata_t) + sizeof(sec_stg_key_t)) * slot_id;
|
||||
bool ret = false;
|
||||
|
||||
int err = esp_tee_flash_read(part_pos.offset + slot_offset, (uint32_t *)&metadata, sizeof(sec_stg_metadata_t), false);
|
||||
if (err != 0) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if (memcmp(&metadata, &blank_metadata, sizeof(sec_stg_metadata_t)) && metadata.slot_id == slot_id) {
|
||||
goto exit;
|
||||
}
|
||||
ret = true;
|
||||
|
||||
exit:
|
||||
return ret;
|
||||
}
|
||||
|
||||
esp_err_t esp_tee_sec_storage_clear_slot(uint16_t slot_id)
|
||||
{
|
||||
if (slot_id > MAX_SEC_STG_SLOT_ID) {
|
||||
ESP_LOGE(TAG, "Invalid slot ID");
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
if (esp_tee_sec_storage_is_slot_empty(slot_id)) {
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
sec_stg_key_t blank_data;
|
||||
memset(&blank_data, 0xFF, sizeof(blank_data));
|
||||
|
||||
sec_stg_metadata_t blank_metadata;
|
||||
memset(&blank_metadata, 0xFF, sizeof(sec_stg_metadata_t));
|
||||
|
||||
uint32_t slot_offset = (sizeof(sec_stg_metadata_t) + sizeof(sec_stg_key_t)) * slot_id;
|
||||
esp_err_t err;
|
||||
|
||||
int ret = esp_tee_flash_read(part_pos.offset, (uint32_t *)tmp_buf, SECURE_STORAGE_SIZE, false);
|
||||
if (ret != 0) {
|
||||
ESP_LOGE(TAG, "Error reading flash contents: %d", ret);
|
||||
err = ESP_ERR_FLASH_OP_FAIL;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
memcpy(&tmp_buf[slot_offset], &blank_metadata, sizeof(sec_stg_metadata_t));
|
||||
memcpy(&tmp_buf[slot_offset + sizeof(sec_stg_metadata_t)], &blank_data, sizeof(sec_stg_key_t));
|
||||
|
||||
ret = esp_tee_flash_erase_range(part_pos.offset, ALIGN_UP(SECURE_STORAGE_SIZE, FLASH_SECTOR_SIZE));
|
||||
ret |= esp_tee_flash_write(part_pos.offset, (uint32_t *)tmp_buf, SECURE_STORAGE_SIZE, false);
|
||||
if (ret != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Error clearing slot: %d", ret);
|
||||
err = ESP_ERR_FLASH_OP_FAIL;
|
||||
goto exit;
|
||||
}
|
||||
err = ESP_OK;
|
||||
|
||||
exit:
|
||||
return err;
|
||||
}
|
||||
|
||||
static esp_err_t tee_sec_storage_crypt_common(uint16_t slot_id, uint8_t *input, uint8_t len, uint8_t *aad,
|
||||
uint16_t aad_len, uint8_t *tag, uint16_t tag_len, uint8_t *output,
|
||||
static esp_err_t tee_sec_storage_crypt_common(const char *key_id, const uint8_t *input, size_t len, const uint8_t *aad,
|
||||
size_t aad_len, uint8_t *tag, size_t tag_len, uint8_t *output,
|
||||
bool is_encrypt)
|
||||
{
|
||||
if (slot_id > MAX_SEC_STG_SLOT_ID) {
|
||||
ESP_LOGE(TAG, "Invalid slot ID");
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
if (input == NULL || output == NULL || tag == NULL) {
|
||||
ESP_LOGE(TAG, "Invalid input/output/tag buffer");
|
||||
if (key_id == NULL || input == NULL || output == NULL || tag == NULL) {
|
||||
ESP_LOGE(TAG, "Invalid arguments");
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
if (len == 0 || tag_len == 0) {
|
||||
ESP_LOGE(TAG, "Invalid length/tag length");
|
||||
ESP_LOGE(TAG, "Invalid input/tag length");
|
||||
return ESP_ERR_INVALID_SIZE;
|
||||
}
|
||||
|
||||
sec_stg_key_t keyctx;
|
||||
esp_err_t err = secure_storage_read(slot_id, (uint8_t *)&keyctx, sizeof(keyctx), ESP_SEC_STG_KEY_AES256);
|
||||
esp_err_t err = secure_storage_find_key(key_id);
|
||||
if (err != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Failed to fetch key from slot");
|
||||
ESP_LOGE(TAG, "Key ID not found");
|
||||
return err;
|
||||
}
|
||||
|
||||
sec_stg_key_t keyctx;
|
||||
size_t keyctx_len = sizeof(keyctx);
|
||||
err = secure_storage_read(key_id, (void *)&keyctx, &keyctx_len);
|
||||
if (err != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Failed to fetch key from storage");
|
||||
return err;
|
||||
}
|
||||
|
||||
if (keyctx.type != ESP_SEC_STG_KEY_AES256) {
|
||||
ESP_LOGE(TAG, "Key type mismatch");
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
|
||||
mbedtls_gcm_context gcm;
|
||||
mbedtls_gcm_init(&gcm);
|
||||
|
||||
int ret = mbedtls_gcm_setkey(&gcm, MBEDTLS_CIPHER_ID_AES, keyctx.aes256_gcm.key, AES256_GCM_KEY_BITS);
|
||||
int ret = mbedtls_gcm_setkey(&gcm, MBEDTLS_CIPHER_ID_AES, keyctx.aes256.key, AES256_KEY_BITS);
|
||||
if (ret != 0) {
|
||||
ESP_LOGE(TAG, "Error in setting key: %d", ret);
|
||||
err = ESP_FAIL;
|
||||
@ -715,7 +577,7 @@ static esp_err_t tee_sec_storage_crypt_common(uint16_t slot_id, uint8_t *input,
|
||||
}
|
||||
|
||||
if (is_encrypt) {
|
||||
ret = mbedtls_gcm_crypt_and_tag(&gcm, MBEDTLS_GCM_ENCRYPT, len, keyctx.aes256_gcm.iv, AES256_GCM_IV_LEN,
|
||||
ret = mbedtls_gcm_crypt_and_tag(&gcm, MBEDTLS_GCM_ENCRYPT, len, keyctx.aes256.iv, AES256_GCM_IV_LEN,
|
||||
aad, aad_len, input, output, tag_len, tag);
|
||||
if (ret != 0) {
|
||||
ESP_LOGE(TAG, "Error in encrypting data: %d", ret);
|
||||
@ -723,7 +585,7 @@ static esp_err_t tee_sec_storage_crypt_common(uint16_t slot_id, uint8_t *input,
|
||||
goto exit;
|
||||
}
|
||||
} else {
|
||||
ret = mbedtls_gcm_auth_decrypt(&gcm, len, keyctx.aes256_gcm.iv, AES256_GCM_IV_LEN,
|
||||
ret = mbedtls_gcm_auth_decrypt(&gcm, len, keyctx.aes256.iv, AES256_GCM_IV_LEN,
|
||||
aad, aad_len, tag, tag_len, input, output);
|
||||
if (ret != 0) {
|
||||
ESP_LOGE(TAG, "Error in decrypting data: %d", ret);
|
||||
@ -738,14 +600,12 @@ exit:
|
||||
return err;
|
||||
}
|
||||
|
||||
esp_err_t esp_tee_sec_storage_encrypt(uint16_t slot_id, uint8_t *input, uint8_t len, uint8_t *aad,
|
||||
uint16_t aad_len, uint8_t *tag, uint16_t tag_len, uint8_t *output)
|
||||
esp_err_t esp_tee_sec_storage_aead_encrypt(const esp_tee_sec_storage_aead_ctx_t *ctx, uint8_t *tag, size_t tag_len, uint8_t *output)
|
||||
{
|
||||
return tee_sec_storage_crypt_common(slot_id, input, len, aad, aad_len, tag, tag_len, output, true);
|
||||
return tee_sec_storage_crypt_common(ctx->key_id, ctx->input, ctx->input_len, ctx->aad, ctx->aad_len, tag, tag_len, output, true);
|
||||
}
|
||||
|
||||
esp_err_t esp_tee_sec_storage_decrypt(uint16_t slot_id, uint8_t *input, uint8_t len, uint8_t *aad,
|
||||
uint16_t aad_len, uint8_t *tag, uint16_t tag_len, uint8_t *output)
|
||||
esp_err_t esp_tee_sec_storage_aead_decrypt(const esp_tee_sec_storage_aead_ctx_t *ctx, const uint8_t *tag, size_t tag_len, uint8_t *output)
|
||||
{
|
||||
return tee_sec_storage_crypt_common(slot_id, input, len, aad, aad_len, tag, tag_len, output, false);
|
||||
return tee_sec_storage_crypt_common(ctx->key_id, ctx->input, ctx->input_len, ctx->aad, ctx->aad_len, (uint8_t *)tag, tag_len, output, false);
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@ -8,46 +8,32 @@
|
||||
#include "esp_err.h"
|
||||
#include "esp_tee_sec_storage.h"
|
||||
|
||||
esp_err_t esp_tee_sec_storage_init(void)
|
||||
esp_err_t esp_tee_sec_storage_clear_key(const char *key_id)
|
||||
{
|
||||
return esp_tee_service_call_with_noniram_intr_disabled(1, SS_ESP_TEE_SEC_STORAGE_INIT);
|
||||
return esp_tee_service_call_with_noniram_intr_disabled(2, SS_ESP_TEE_SEC_STORAGE_CLEAR_KEY, key_id);
|
||||
}
|
||||
|
||||
esp_err_t esp_tee_sec_storage_gen_key(uint16_t slot_id, esp_tee_sec_storage_type_t key_type)
|
||||
esp_err_t esp_tee_sec_storage_gen_key(const esp_tee_sec_storage_key_cfg_t *cfg)
|
||||
{
|
||||
return esp_tee_service_call_with_noniram_intr_disabled(3, SS_ESP_TEE_SEC_STORAGE_GEN_KEY, slot_id, key_type);
|
||||
return esp_tee_service_call_with_noniram_intr_disabled(2, SS_ESP_TEE_SEC_STORAGE_GEN_KEY, cfg);
|
||||
}
|
||||
|
||||
esp_err_t esp_tee_sec_storage_get_signature(uint16_t slot_id, esp_tee_sec_storage_type_t key_type, uint8_t *hash, size_t hlen, esp_tee_sec_storage_sign_t *sign)
|
||||
esp_err_t esp_tee_sec_storage_ecdsa_sign(const esp_tee_sec_storage_key_cfg_t *cfg, const uint8_t *hash, size_t hlen, esp_tee_sec_storage_ecdsa_sign_t *out_sign)
|
||||
{
|
||||
return esp_tee_service_call_with_noniram_intr_disabled(6, SS_ESP_TEE_SEC_STORAGE_GET_SIGNATURE, slot_id, key_type, hash, hlen, sign);
|
||||
return esp_tee_service_call_with_noniram_intr_disabled(5, SS_ESP_TEE_SEC_STORAGE_ECDSA_SIGN, cfg, hash, hlen, out_sign);
|
||||
}
|
||||
|
||||
esp_err_t esp_tee_sec_storage_get_pubkey(uint16_t slot_id, esp_tee_sec_storage_type_t key_type, esp_tee_sec_storage_pubkey_t *pubkey)
|
||||
esp_err_t esp_tee_sec_storage_ecdsa_get_pubkey(const esp_tee_sec_storage_key_cfg_t *cfg, esp_tee_sec_storage_ecdsa_pubkey_t *out_pubkey)
|
||||
{
|
||||
return esp_tee_service_call_with_noniram_intr_disabled(4, SS_ESP_TEE_SEC_STORAGE_GET_PUBKEY, slot_id, key_type, pubkey);
|
||||
return esp_tee_service_call_with_noniram_intr_disabled(3, SS_ESP_TEE_SEC_STORAGE_ECDSA_GET_PUBKEY, cfg, out_pubkey);
|
||||
}
|
||||
|
||||
bool esp_tee_sec_storage_is_slot_empty(uint16_t slot_id)
|
||||
esp_err_t esp_tee_sec_storage_aead_encrypt(const esp_tee_sec_storage_aead_ctx_t *ctx, uint8_t *tag, size_t tag_len, uint8_t *output)
|
||||
{
|
||||
return esp_tee_service_call_with_noniram_intr_disabled(2, SS_ESP_TEE_SEC_STORAGE_IS_SLOT_EMPTY, slot_id);
|
||||
return esp_tee_service_call_with_noniram_intr_disabled(5, SS_ESP_TEE_SEC_STORAGE_AEAD_ENCRYPT, ctx, tag, tag_len, output);
|
||||
}
|
||||
|
||||
esp_err_t esp_tee_sec_storage_clear_slot(uint16_t slot_id)
|
||||
esp_err_t esp_tee_sec_storage_aead_decrypt(const esp_tee_sec_storage_aead_ctx_t *ctx, const uint8_t *tag, size_t tag_len, uint8_t *output)
|
||||
{
|
||||
return esp_tee_service_call_with_noniram_intr_disabled(2, SS_ESP_TEE_SEC_STORAGE_CLEAR_SLOT, slot_id);
|
||||
}
|
||||
|
||||
esp_err_t esp_tee_sec_storage_encrypt(uint16_t slot_id, uint8_t *input, uint8_t len, uint8_t *aad,
|
||||
uint16_t aad_len, uint8_t *tag, uint16_t tag_len, uint8_t *output)
|
||||
{
|
||||
return esp_tee_service_call_with_noniram_intr_disabled(9, SS_ESP_TEE_SEC_STORAGE_ENCRYPT, slot_id,
|
||||
input, len, aad, aad_len, tag, tag_len, output);
|
||||
}
|
||||
|
||||
esp_err_t esp_tee_sec_storage_decrypt(uint16_t slot_id, uint8_t *input, uint8_t len, uint8_t *aad,
|
||||
uint16_t aad_len, uint8_t *tag, uint16_t tag_len, uint8_t *output)
|
||||
{
|
||||
return esp_tee_service_call_with_noniram_intr_disabled(9, SS_ESP_TEE_SEC_STORAGE_DECRYPT, slot_id,
|
||||
input, len, aad, aad_len, tag, tag_len, output);
|
||||
return esp_tee_service_call_with_noniram_intr_disabled(5, SS_ESP_TEE_SEC_STORAGE_AEAD_DECRYPT, ctx, tag, tag_len, output);
|
||||
}
|
||||
|
@ -205,6 +205,10 @@ esp_err_t _ss_esp_hmac_calculate(hmac_key_id_t key_id, const void *message, size
|
||||
bool valid_addr = ((esp_tee_ptr_in_ree((void *)message) && esp_tee_ptr_in_ree((void *)hmac)) &&
|
||||
esp_tee_ptr_in_ree((void *)((char *)message + message_len)));
|
||||
|
||||
#if CONFIG_SECURE_TEE_SEC_STG_MODE_RELEASE
|
||||
valid_addr &= (key_id != (hmac_key_id_t)CONFIG_SECURE_TEE_SEC_STG_EFUSE_HMAC_KEY_ID);
|
||||
#endif
|
||||
|
||||
if (!valid_addr) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
@ -217,6 +221,10 @@ esp_err_t _ss_esp_hmac_jtag_enable(hmac_key_id_t key_id, const uint8_t *token)
|
||||
{
|
||||
bool valid_addr = (esp_tee_ptr_in_ree((void *)token));
|
||||
|
||||
#if CONFIG_SECURE_TEE_SEC_STG_MODE_RELEASE
|
||||
valid_addr &= (key_id != (hmac_key_id_t)CONFIG_SECURE_TEE_SEC_STG_EFUSE_HMAC_KEY_ID);
|
||||
#endif
|
||||
|
||||
if (!valid_addr) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
@ -239,6 +247,10 @@ esp_err_t _ss_esp_ds_sign(const void *message,
|
||||
esp_tee_ptr_in_ree((void *)data) &&
|
||||
esp_tee_ptr_in_ree((void *)signature));
|
||||
|
||||
#if CONFIG_SECURE_TEE_SEC_STG_MODE_RELEASE
|
||||
valid_addr &= (key_id != (hmac_key_id_t)CONFIG_SECURE_TEE_SEC_STG_EFUSE_HMAC_KEY_ID);
|
||||
#endif
|
||||
|
||||
if (!valid_addr) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
@ -256,6 +268,10 @@ esp_err_t _ss_esp_ds_start_sign(const void *message,
|
||||
esp_tee_ptr_in_ree((void *)data) &&
|
||||
esp_tee_ptr_in_ree((void *)esp_ds_ctx));
|
||||
|
||||
#if CONFIG_SECURE_TEE_SEC_STG_MODE_RELEASE
|
||||
valid_addr &= (key_id != (hmac_key_id_t)CONFIG_SECURE_TEE_SEC_STG_EFUSE_HMAC_KEY_ID);
|
||||
#endif
|
||||
|
||||
if (!valid_addr) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
@ -356,22 +372,12 @@ int _ss_esp_tee_ota_end(void)
|
||||
|
||||
/* ---------------------------------------------- Secure Storage ------------------------------------------------- */
|
||||
|
||||
esp_err_t _ss_esp_tee_sec_storage_init(void)
|
||||
esp_err_t _ss_esp_tee_sec_storage_clear_key(const char *key_id)
|
||||
{
|
||||
return esp_tee_sec_storage_init();
|
||||
return esp_tee_sec_storage_clear_key(key_id);
|
||||
}
|
||||
|
||||
esp_err_t _ss_esp_tee_sec_storage_gen_key(uint16_t slot_id, uint8_t key_type)
|
||||
esp_err_t _ss_esp_tee_sec_storage_gen_key(const esp_tee_sec_storage_key_cfg_t *cfg)
|
||||
{
|
||||
return esp_tee_sec_storage_gen_key(slot_id, key_type);
|
||||
}
|
||||
|
||||
bool _ss_esp_tee_sec_storage_is_slot_empty(uint16_t slot_id)
|
||||
{
|
||||
return esp_tee_sec_storage_is_slot_empty(slot_id);
|
||||
}
|
||||
|
||||
esp_err_t _ss_esp_tee_sec_storage_clear_slot(uint16_t slot_id)
|
||||
{
|
||||
return esp_tee_sec_storage_clear_slot(slot_id);
|
||||
return esp_tee_sec_storage_gen_key(cfg);
|
||||
}
|
||||
|
@ -85,46 +85,45 @@ void _ss_wdt_hal_deinit(wdt_hal_context_t *hal)
|
||||
|
||||
/* ---------------------------------------------- Secure Storage ------------------------------------------------- */
|
||||
|
||||
esp_err_t _ss_esp_tee_sec_storage_get_signature(uint16_t slot_id, esp_tee_sec_storage_type_t key_type, uint8_t *hash, size_t hlen, esp_tee_sec_storage_sign_t *out_sign)
|
||||
esp_err_t _ss_esp_tee_sec_storage_ecdsa_sign(const esp_tee_sec_storage_key_cfg_t *cfg, const uint8_t *hash, size_t hlen, esp_tee_sec_storage_ecdsa_sign_t *out_sign)
|
||||
{
|
||||
bool valid_addr = ((esp_tee_ptr_in_ree((void *)hash) && esp_tee_ptr_in_ree((void *)out_sign)) &
|
||||
bool valid_addr = ((esp_tee_ptr_in_ree((void *)hash) && esp_tee_ptr_in_ree((void *)out_sign)) &&
|
||||
(esp_tee_ptr_in_ree((void *)(hash + hlen)) &&
|
||||
esp_tee_ptr_in_ree((void *)((char *)out_sign + sizeof(esp_tee_sec_storage_sign_t)))));
|
||||
esp_tee_ptr_in_ree((void *)((char *)out_sign + sizeof(esp_tee_sec_storage_ecdsa_sign_t)))));
|
||||
|
||||
if (!valid_addr) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
ESP_FAULT_ASSERT(valid_addr);
|
||||
|
||||
return esp_tee_sec_storage_get_signature(slot_id, key_type, hash, hlen, out_sign);
|
||||
return esp_tee_sec_storage_ecdsa_sign(cfg, hash, hlen, out_sign);
|
||||
}
|
||||
|
||||
esp_err_t _ss_esp_tee_sec_storage_get_pubkey(uint16_t slot_id, esp_tee_sec_storage_type_t key_type, esp_tee_sec_storage_pubkey_t *pubkey)
|
||||
esp_err_t _ss_esp_tee_sec_storage_ecdsa_get_pubkey(const esp_tee_sec_storage_key_cfg_t *cfg, esp_tee_sec_storage_ecdsa_pubkey_t *out_pubkey)
|
||||
{
|
||||
bool valid_addr = ((esp_tee_ptr_in_ree((void *)pubkey)) &
|
||||
(esp_tee_ptr_in_ree((void *)((char *)pubkey + sizeof(esp_tee_sec_storage_pubkey_t)))));
|
||||
bool valid_addr = ((esp_tee_ptr_in_ree((void *)out_pubkey)) &&
|
||||
(esp_tee_ptr_in_ree((void *)((char *)out_pubkey + sizeof(esp_tee_sec_storage_ecdsa_pubkey_t)))));
|
||||
|
||||
if (!valid_addr) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
ESP_FAULT_ASSERT(valid_addr);
|
||||
|
||||
return esp_tee_sec_storage_get_pubkey(slot_id, key_type, pubkey);
|
||||
return esp_tee_sec_storage_ecdsa_get_pubkey(cfg, out_pubkey);
|
||||
}
|
||||
|
||||
esp_err_t _ss_esp_tee_sec_storage_encrypt(uint16_t slot_id, uint8_t *input, uint8_t len, uint8_t *aad,
|
||||
uint16_t aad_len, uint8_t *tag, uint16_t tag_len, uint8_t *output)
|
||||
esp_err_t _ss_esp_tee_sec_storage_aead_encrypt(const esp_tee_sec_storage_aead_ctx_t *ctx, uint8_t *tag, size_t tag_len, uint8_t *output)
|
||||
{
|
||||
bool valid_addr = (esp_tee_ptr_in_ree((void *)input) &&
|
||||
bool valid_addr = (esp_tee_ptr_in_ree((void *)ctx->input) &&
|
||||
esp_tee_ptr_in_ree((void *)tag) &&
|
||||
esp_tee_ptr_in_ree((void *)output));
|
||||
|
||||
valid_addr &= (esp_tee_ptr_in_ree((void *)(input + len)) &&
|
||||
valid_addr &= (esp_tee_ptr_in_ree((void *)(ctx->input + ctx->input_len)) &&
|
||||
esp_tee_ptr_in_ree((void *)(tag + tag_len)) &&
|
||||
esp_tee_ptr_in_ree((void *)(output + len)));
|
||||
esp_tee_ptr_in_ree((void *)(output + ctx->input_len)));
|
||||
|
||||
if (aad) {
|
||||
valid_addr &= (esp_tee_ptr_in_ree((void *)aad) && esp_tee_ptr_in_ree((void *)(aad + aad_len)));
|
||||
if (ctx->aad) {
|
||||
valid_addr &= (esp_tee_ptr_in_ree((void *)ctx->aad) && esp_tee_ptr_in_ree((void *)(ctx->aad + ctx->aad_len)));
|
||||
}
|
||||
|
||||
if (!valid_addr) {
|
||||
@ -132,22 +131,21 @@ esp_err_t _ss_esp_tee_sec_storage_encrypt(uint16_t slot_id, uint8_t *input, uint
|
||||
}
|
||||
ESP_FAULT_ASSERT(valid_addr);
|
||||
|
||||
return esp_tee_sec_storage_encrypt(slot_id, input, len, aad, aad_len, tag, tag_len, output);
|
||||
return esp_tee_sec_storage_aead_encrypt(ctx, tag, tag_len, output);
|
||||
}
|
||||
|
||||
esp_err_t _ss_esp_tee_sec_storage_decrypt(uint16_t slot_id, uint8_t *input, uint8_t len, uint8_t *aad,
|
||||
uint16_t aad_len, uint8_t *tag, uint16_t tag_len, uint8_t *output)
|
||||
esp_err_t _ss_esp_tee_sec_storage_aead_decrypt(const esp_tee_sec_storage_aead_ctx_t *ctx, const uint8_t *tag, size_t tag_len, uint8_t *output)
|
||||
{
|
||||
bool valid_addr = (esp_tee_ptr_in_ree((void *)input) &&
|
||||
bool valid_addr = (esp_tee_ptr_in_ree((void *)ctx->input) &&
|
||||
esp_tee_ptr_in_ree((void *)tag) &&
|
||||
esp_tee_ptr_in_ree((void *)output));
|
||||
|
||||
valid_addr &= (esp_tee_ptr_in_ree((void *)(input + len)) &&
|
||||
valid_addr &= (esp_tee_ptr_in_ree((void *)(ctx->input + ctx->input_len)) &&
|
||||
esp_tee_ptr_in_ree((void *)(tag + tag_len)) &&
|
||||
esp_tee_ptr_in_ree((void *)(output + len)));
|
||||
esp_tee_ptr_in_ree((void *)(output + ctx->input_len)));
|
||||
|
||||
if (aad) {
|
||||
valid_addr &= (esp_tee_ptr_in_ree((void *)aad) && esp_tee_ptr_in_ree((void *)(aad + aad_len)));
|
||||
if (ctx->aad) {
|
||||
valid_addr &= (esp_tee_ptr_in_ree((void *)ctx->aad) && esp_tee_ptr_in_ree((void *)(ctx->aad + ctx->aad_len)));
|
||||
}
|
||||
|
||||
if (!valid_addr) {
|
||||
@ -155,7 +153,7 @@ esp_err_t _ss_esp_tee_sec_storage_decrypt(uint16_t slot_id, uint8_t *input, uint
|
||||
}
|
||||
ESP_FAULT_ASSERT(valid_addr);
|
||||
|
||||
return esp_tee_sec_storage_decrypt(slot_id, input, len, aad, aad_len, tag, tag_len, output);
|
||||
return esp_tee_sec_storage_aead_decrypt(ctx, tag, tag_len, output);
|
||||
}
|
||||
|
||||
/* ---------------------------------------------- MMU HAL ------------------------------------------------- */
|
||||
|
@ -14,6 +14,7 @@
|
||||
|
||||
#include "esp_tee_brownout.h"
|
||||
#include "esp_tee_flash.h"
|
||||
#include "esp_tee_sec_storage.h"
|
||||
#include "bootloader_utility_tee.h"
|
||||
|
||||
#if __has_include("esp_app_desc.h")
|
||||
@ -23,11 +24,8 @@
|
||||
|
||||
/* TEE symbols */
|
||||
extern uint32_t _tee_stack;
|
||||
extern uint32_t _tee_intr_stack_bottom;
|
||||
extern uint32_t _tee_bss_start;
|
||||
extern uint32_t _tee_bss_end;
|
||||
|
||||
extern uint32_t _sec_world_entry;
|
||||
extern uint32_t _tee_s_intr_handler;
|
||||
|
||||
extern uint8_t _tee_heap_start[];
|
||||
@ -159,6 +157,14 @@ void __attribute__((noreturn)) esp_tee_init(uint32_t ree_entry_addr, uint32_t re
|
||||
}
|
||||
ESP_FAULT_ASSERT(err == ESP_OK);
|
||||
|
||||
/* Initializing the secure storage */
|
||||
err = esp_tee_sec_storage_init();
|
||||
if (err != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Failed to initialize the secure storage! (0x%08x)", err);
|
||||
abort();
|
||||
}
|
||||
ESP_FAULT_ASSERT(err == ESP_OK);
|
||||
|
||||
/* Setting up the running non-secure app partition as per the address provided by the bootloader */
|
||||
err = esp_tee_flash_set_running_ree_partition(ree_drom_addr);
|
||||
if (err != ESP_OK) {
|
||||
|
@ -19,14 +19,14 @@ static const char *TAG = "esp_tee_apm_prot_cfg";
|
||||
|
||||
/* NOTE: Figuring out the eFuse protection range based on where the TEE secure storage key is stored */
|
||||
#if CONFIG_SECURE_TEE_SEC_STG_MODE_RELEASE
|
||||
#if CONFIG_SECURE_TEE_SEC_STG_KEY_EFUSE_BLK > 9
|
||||
#error "TEE: eFuse protection region for APM out of range! (see CONFIG_SECURE_TEE_SEC_STG_KEY_EFUSE_BLK)"
|
||||
#if CONFIG_SECURE_TEE_SEC_STG_EFUSE_HMAC_KEY_ID < 0
|
||||
#error "TEE: eFuse protection region for APM out of range! (see CONFIG_SECURE_TEE_SEC_STG_EFUSE_HMAC_KEY_ID)"
|
||||
#endif
|
||||
#define LP_APM_EFUSE_REG_START \
|
||||
(EFUSE_RD_KEY0_DATA0_REG + (((CONFIG_SECURE_TEE_SEC_STG_KEY_EFUSE_BLK) - 4) * 0x20))
|
||||
(EFUSE_RD_KEY0_DATA0_REG + (CONFIG_SECURE_TEE_SEC_STG_EFUSE_HMAC_KEY_ID * 0x20))
|
||||
|
||||
#define LP_APM_EFUSE_REG_END \
|
||||
(EFUSE_RD_KEY1_DATA0_REG + (((CONFIG_SECURE_TEE_SEC_STG_KEY_EFUSE_BLK) - 4) * 0x20))
|
||||
(EFUSE_RD_KEY1_DATA0_REG + (CONFIG_SECURE_TEE_SEC_STG_EFUSE_HMAC_KEY_ID * 0x20))
|
||||
#elif CONFIG_SECURE_TEE_SEC_STG_MODE_DEVELOPMENT
|
||||
#define LP_APM_EFUSE_REG_START EFUSE_RD_KEY5_DATA0_REG
|
||||
#if CONFIG_SECURE_TEE_TEST_MODE
|
||||
|
@ -11,7 +11,7 @@ CONFIG_SECURE_TEE_LOG_LEVEL_DEBUG=y
|
||||
CONFIG_SECURE_TEE_SEC_STG_SUPPORT_SECP192R1_SIGN=y
|
||||
|
||||
# secure storage key slot for attestation
|
||||
CONFIG_SECURE_TEE_ATT_KEY_SLOT_ID=14
|
||||
CONFIG_SECURE_TEE_ATT_KEY_STR_ID="tee_att_keyN"
|
||||
|
||||
# Enabling flash protection over SPI1
|
||||
CONFIG_SECURE_TEE_EXT_FLASH_MEMPROT_SPI1=y
|
||||
|
@ -410,7 +410,7 @@ static int esp_ecdsa_sign(mbedtls_ecp_group *grp, mbedtls_mpi* r, mbedtls_mpi* s
|
||||
|
||||
|
||||
#if CONFIG_MBEDTLS_TEE_SEC_STG_ECDSA_SIGN
|
||||
int esp_ecdsa_tee_load_pubkey(mbedtls_ecp_keypair *keypair, int slot_id)
|
||||
int esp_ecdsa_tee_load_pubkey(mbedtls_ecp_keypair *keypair, const char *tee_key_id)
|
||||
{
|
||||
int ret = -1;
|
||||
uint16_t len;
|
||||
@ -426,8 +426,13 @@ int esp_ecdsa_tee_load_pubkey(mbedtls_ecp_keypair *keypair, int slot_id)
|
||||
return MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
|
||||
}
|
||||
|
||||
esp_tee_sec_storage_pubkey_t pubkey = {};
|
||||
if (esp_tee_sec_storage_get_pubkey(slot_id, key_type, &pubkey) != ESP_OK) {
|
||||
esp_tee_sec_storage_key_cfg_t cfg = {
|
||||
.id = tee_key_id,
|
||||
.type = key_type
|
||||
};
|
||||
|
||||
esp_tee_sec_storage_ecdsa_pubkey_t pubkey = {};
|
||||
if (esp_tee_sec_storage_ecdsa_get_pubkey(&cfg, &pubkey) != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Failed to get public key from secure storage");
|
||||
goto cleanup;
|
||||
}
|
||||
@ -457,9 +462,9 @@ int esp_ecdsa_tee_set_pk_context(mbedtls_pk_context *key_ctx, esp_ecdsa_pk_conf_
|
||||
return ret;
|
||||
}
|
||||
|
||||
int slot_id = conf->tee_slot_id;
|
||||
if (slot_id < MIN_SEC_STG_SLOT_ID || slot_id > MAX_SEC_STG_SLOT_ID) {
|
||||
ESP_LOGE(TAG, "Invalid slot id");
|
||||
const char *key_id = conf->tee_key_id;
|
||||
if (!key_id) {
|
||||
ESP_LOGE(TAG, "Invalid TEE key id");
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -477,8 +482,14 @@ int esp_ecdsa_tee_set_pk_context(mbedtls_pk_context *key_ctx, esp_ecdsa_pk_conf_
|
||||
|
||||
mbedtls_mpi_init(&(keypair->MBEDTLS_PRIVATE(d)));
|
||||
keypair->MBEDTLS_PRIVATE(d).MBEDTLS_PRIVATE(s) = ECDSA_KEY_MAGIC_TEE;
|
||||
keypair->MBEDTLS_PRIVATE(d).MBEDTLS_PRIVATE(n) = slot_id;
|
||||
keypair->MBEDTLS_PRIVATE(d).MBEDTLS_PRIVATE(p) = NULL;
|
||||
keypair->MBEDTLS_PRIVATE(d).MBEDTLS_PRIVATE(n) = 1;
|
||||
|
||||
mbedtls_mpi_uint *key_id_mpi = malloc(sizeof(mbedtls_mpi_uint));
|
||||
if (!key_id_mpi) {
|
||||
return -1;
|
||||
}
|
||||
key_id_mpi[0] = (mbedtls_mpi_uint)(uintptr_t)key_id;
|
||||
keypair->MBEDTLS_PRIVATE(d).MBEDTLS_PRIVATE(p) = key_id_mpi;
|
||||
|
||||
if ((ret = mbedtls_ecp_group_load(&(keypair->MBEDTLS_PRIVATE(grp)), conf->grp_id)) != 0) {
|
||||
ESP_LOGE(TAG, "Loading ecp group failed, mbedtls_pk_ec() returned %d", ret);
|
||||
@ -486,7 +497,7 @@ int esp_ecdsa_tee_set_pk_context(mbedtls_pk_context *key_ctx, esp_ecdsa_pk_conf_
|
||||
}
|
||||
|
||||
if (conf->load_pubkey) {
|
||||
if ((ret = esp_ecdsa_tee_load_pubkey(keypair, slot_id)) != 0) {
|
||||
if ((ret = esp_ecdsa_tee_load_pubkey(keypair, key_id)) != 0) {
|
||||
ESP_LOGE(TAG, "Loading public key context failed, esp_ecdsa_load_pubkey() returned %d", ret);
|
||||
return ret;
|
||||
}
|
||||
@ -525,10 +536,15 @@ static int esp_ecdsa_tee_sign(mbedtls_ecp_group *grp, mbedtls_mpi* r, mbedtls_mp
|
||||
return MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
|
||||
}
|
||||
|
||||
int slot_id = d->MBEDTLS_PRIVATE(n);
|
||||
const char *key_id = (const char *)(uintptr_t)(d->MBEDTLS_PRIVATE(p)[0]);
|
||||
|
||||
esp_tee_sec_storage_sign_t sign = {};
|
||||
esp_err_t err = esp_tee_sec_storage_get_signature(slot_id, key_type, (uint8_t *)msg, msg_len, &sign);
|
||||
esp_tee_sec_storage_key_cfg_t cfg = {
|
||||
.id = key_id,
|
||||
.type = key_type
|
||||
};
|
||||
|
||||
esp_tee_sec_storage_ecdsa_sign_t sign = {};
|
||||
esp_err_t err = esp_tee_sec_storage_ecdsa_sign(&cfg, (uint8_t *)msg, msg_len, &sign);
|
||||
if (err != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Failed to get signature");
|
||||
return MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
|
||||
|
@ -29,8 +29,8 @@ typedef struct {
|
||||
mbedtls_ecp_group_id grp_id; /*!< MbedTLS ECP group identifier */
|
||||
union {
|
||||
uint8_t efuse_block; /*!< EFuse block id for ECDSA private key */
|
||||
uint8_t tee_slot_id; /*!< TEE secure storage slot id for ECDSA private key */
|
||||
}; /*!< Union to hold either EFuse block id or TEE secure storage slot id for ECDSA private key */
|
||||
const char *tee_key_id; /*!< TEE secure storage key id for ECDSA private key */
|
||||
}; /*!< Union to hold either EFuse block id or TEE secure storage key id for ECDSA private key */
|
||||
#if SOC_ECDSA_SUPPORT_EXPORT_PUBKEY || CONFIG_MBEDTLS_TEE_SEC_STG_ECDSA_SIGN
|
||||
bool load_pubkey; /*!< Export ECDSA public key from the hardware */
|
||||
|
||||
@ -120,11 +120,11 @@ int esp_ecdsa_set_pk_context(mbedtls_pk_context *key_ctx, esp_ecdsa_pk_conf_t *c
|
||||
* the TEE secure storage.
|
||||
*
|
||||
* @param keypair The mbedtls ECP key-pair structure
|
||||
* @param slot_id The TEE secure storage slot id that holds the private key.
|
||||
* @param tee_key_id The TEE secure storage key id of the private key
|
||||
*
|
||||
* @return - 0 if successful else MBEDTLS_ERR_ECP_BAD_INPUT_DATA
|
||||
*/
|
||||
int esp_ecdsa_tee_load_pubkey(mbedtls_ecp_keypair *keypair, int slot_id);
|
||||
int esp_ecdsa_tee_load_pubkey(mbedtls_ecp_keypair *keypair, const char *tee_key_id);
|
||||
|
||||
/**
|
||||
* @brief Initialize PK context and fully populate the mbedtls_ecp_keypair context.
|
||||
|
@ -1,7 +1,8 @@
|
||||
# Name, Type, SubType, Offset, Size, Flags
|
||||
# Note: if you have increased the bootloader size, make sure to update the offsets to avoid overlap
|
||||
tee, app, tee_0, , 192K,
|
||||
secure_storage, data, tee_sec_stg, , 64K,
|
||||
tee_nvs, data, nvs, , 32K,
|
||||
secure_storage, data, tee_sec_stg, , 32K,
|
||||
factory, app, factory, , 1536K,
|
||||
nvs, data, nvs, , 24K,
|
||||
phy_init, data, phy, , 4K,
|
||||
|
|
@ -3,7 +3,8 @@
|
||||
tee_0, app, tee_0, , 192K,
|
||||
tee_1, app, tee_1, , 192K,
|
||||
tee_otadata, data, tee_ota, , 8K,
|
||||
secure_storage, data, tee_sec_stg, , 56K,
|
||||
tee_nvs, data, nvs, , 32K,
|
||||
secure_storage, data, tee_sec_stg, , 24K,
|
||||
ota_0, app, ota_0, , 1536K,
|
||||
ota_1, app, ota_1, , 1536K,
|
||||
otadata, data, ota, , 8K,
|
||||
|
|
Reference in New Issue
Block a user