mirror of
https://github.com/espressif/esp-idf.git
synced 2026-04-27 19:13:21 +00:00
feat(esp_tee): Migrate TEE attestation to the PSA interface
This commit is contained in:
@@ -80,8 +80,8 @@ else()
|
||||
|
||||
idf_component_register(INCLUDE_DIRS include
|
||||
SRCS ${srcs}
|
||||
PRIV_REQUIRES efuse esp_security esp_system esp_stdio spi_flash esptool_py esp_hal_wdt)
|
||||
|
||||
PRIV_REQUIRES efuse esp_hal_wdt esp_security esp_stdio
|
||||
esp_system esptool_py mbedtls spi_flash)
|
||||
if(CONFIG_SECURE_ENABLE_TEE)
|
||||
set(EXTRA_LINK_FLAGS)
|
||||
list(APPEND EXTRA_LINK_FLAGS "-u esp_tee_app_config")
|
||||
|
||||
@@ -127,6 +127,15 @@ menu "ESP-TEE (Trusted Execution Environment)"
|
||||
storing the ECDSA keypair for executing sign/verify operations
|
||||
from the TEE side for attestation.
|
||||
|
||||
config SECURE_TEE_ATT_PSA_CERT_REF
|
||||
depends on SECURE_TEE_ATTESTATION
|
||||
string
|
||||
default "0632793520245-10010" if IDF_TARGET_ESP32C6
|
||||
default "0632793520351-10100" if IDF_TARGET_ESP32H2
|
||||
default "XXXXXXXXXXXXX-XXXXX"
|
||||
help
|
||||
PSA certification ID string for the attestation token
|
||||
|
||||
endmenu
|
||||
|
||||
config SECURE_TEE_EXT_FLASH_MEMPROT_SPI1
|
||||
|
||||
@@ -305,9 +305,13 @@ secure_services:
|
||||
- family: attestation
|
||||
entries:
|
||||
- id: 170
|
||||
type: custom
|
||||
function: esp_tee_att_generate_token
|
||||
args: 6
|
||||
type: IDF
|
||||
function: psa_initial_attest_get_token
|
||||
args: 5
|
||||
- id: 171
|
||||
type: IDF
|
||||
function: psa_initial_attest_get_token_size
|
||||
args: 2
|
||||
# ID: 175-194 (20) - Secure Storage
|
||||
- family: secure_storage
|
||||
entries:
|
||||
|
||||
@@ -245,9 +245,13 @@ secure_services:
|
||||
- family: attestation
|
||||
entries:
|
||||
- id: 170
|
||||
type: custom
|
||||
function: esp_tee_att_generate_token
|
||||
args: 6
|
||||
type: IDF
|
||||
function: psa_initial_attest_get_token
|
||||
args: 5
|
||||
- id: 171
|
||||
type: IDF
|
||||
function: psa_initial_attest_get_token_size
|
||||
args: 2
|
||||
# ID: 175-194 (20) - Secure Storage
|
||||
- family: secure_storage
|
||||
entries:
|
||||
|
||||
@@ -210,9 +210,13 @@ secure_services:
|
||||
- family: attestation
|
||||
entries:
|
||||
- id: 170
|
||||
type: custom
|
||||
function: esp_tee_att_generate_token
|
||||
args: 6
|
||||
type: IDF
|
||||
function: psa_initial_attest_get_token
|
||||
args: 5
|
||||
- id: 171
|
||||
type: IDF
|
||||
function: psa_initial_attest_get_token_size
|
||||
args: 2
|
||||
# ID: 175-194 (20) - Secure Storage
|
||||
- family: secure_storage
|
||||
entries:
|
||||
|
||||
@@ -249,9 +249,13 @@ secure_services:
|
||||
- family: attestation
|
||||
entries:
|
||||
- id: 170
|
||||
type: custom
|
||||
function: esp_tee_att_generate_token
|
||||
args: 6
|
||||
type: IDF
|
||||
function: psa_initial_attest_get_token
|
||||
args: 5
|
||||
- id: 171
|
||||
type: IDF
|
||||
function: psa_initial_attest_get_token_size
|
||||
args: 2
|
||||
# ID: 175-194 (20) - Secure Storage
|
||||
- family: secure_storage
|
||||
entries:
|
||||
|
||||
@@ -14,9 +14,15 @@
|
||||
#include "hal/spi_flash_hal.h"
|
||||
#include "hal/spi_flash_types.h"
|
||||
#include "esp_private/mspi_timing_tuning.h"
|
||||
#if SOC_AES_SUPPORTED
|
||||
#include "aes/esp_aes.h"
|
||||
#endif
|
||||
#if SOC_SHA_SUPPORTED
|
||||
#include "hal/sha_types.h"
|
||||
#include "hal/sha_hal.h"
|
||||
#include "psa_crypto_driver_esp_sha_contexts.h"
|
||||
#endif
|
||||
#if SOC_ECC_SUPPORTED
|
||||
#include "ecc_impl.h"
|
||||
#endif
|
||||
#if SOC_HMAC_SUPPORTED
|
||||
#include "esp_hmac.h"
|
||||
@@ -25,6 +31,7 @@
|
||||
#include "esp_ds.h"
|
||||
#include "rom/digital_signature.h"
|
||||
#endif
|
||||
#include "psa/crypto.h"
|
||||
#include "esp_crypto_lock.h"
|
||||
#include "esp_flash.h"
|
||||
|
||||
@@ -61,12 +68,6 @@ void IRAM_ATTR __wrap_wdt_hal_deinit(wdt_hal_context_t *hal)
|
||||
/* ---------------------------------------------- AES ------------------------------------------------- */
|
||||
|
||||
#if SOC_AES_SUPPORTED
|
||||
typedef struct {
|
||||
uint8_t key_bytes;
|
||||
volatile uint8_t key_in_hardware; /* This variable is used for fault injection checks, so marked volatile to avoid optimisation */
|
||||
uint8_t key[32];
|
||||
} esp_aes_context;
|
||||
|
||||
int __wrap_esp_aes_intr_alloc(void)
|
||||
{
|
||||
return esp_tee_service_call(1, SS_ESP_AES_INTR_ALLOC);
|
||||
@@ -158,49 +159,6 @@ int __wrap_esp_aes_crypt_ofb(esp_aes_context *ctx,
|
||||
/* ---------------------------------------------- SHA ------------------------------------------------- */
|
||||
|
||||
#if SOC_SHA_SUPPORTED
|
||||
typedef enum {
|
||||
ESP_SHA1_STATE_INIT,
|
||||
ESP_SHA1_STATE_IN_PROCESS
|
||||
} esp_sha1_state;
|
||||
|
||||
typedef enum {
|
||||
ESP_SHA256_STATE_INIT,
|
||||
ESP_SHA256_STATE_IN_PROCESS
|
||||
} esp_sha256_state;
|
||||
|
||||
typedef enum {
|
||||
ESP_SHA512_STATE_INIT,
|
||||
ESP_SHA512_STATE_IN_PROCESS
|
||||
} esp_sha512_state;
|
||||
|
||||
typedef struct {
|
||||
uint32_t total[2]; /*!< number of bytes processed */
|
||||
uint32_t state[5]; /*!< intermediate digest state */
|
||||
unsigned char buffer[64]; /*!< data block being processed */
|
||||
int first_block; /*!< if first then true else false */
|
||||
esp_sha_type mode;
|
||||
esp_sha1_state sha_state;
|
||||
} esp_sha1_context;
|
||||
|
||||
typedef struct {
|
||||
uint32_t total[2]; /*!< number of bytes processed */
|
||||
uint32_t state[8]; /*!< intermediate digest state */
|
||||
unsigned char buffer[64]; /*!< data block being processed */
|
||||
int first_block; /*!< if first then true, else false */
|
||||
esp_sha_type mode;
|
||||
esp_sha256_state sha_state;
|
||||
} esp_sha256_context;
|
||||
|
||||
typedef struct {
|
||||
uint64_t total[2]; /*!< number of bytes processed */
|
||||
uint64_t state[8]; /*!< intermediate digest state */
|
||||
unsigned char buffer[128]; /*!< data block being processed */
|
||||
int first_block;
|
||||
esp_sha_type mode;
|
||||
uint32_t t_val; /*!< t_val for 512/t mode */
|
||||
esp_sha512_state sha_state;
|
||||
} esp_sha512_context;
|
||||
|
||||
void __wrap_esp_sha(esp_sha_type sha_type, const unsigned char *input, size_t ilen, unsigned char *output)
|
||||
{
|
||||
esp_tee_service_call(5, SS_ESP_SHA,
|
||||
@@ -343,15 +301,6 @@ void __wrap_esp_crypto_mpi_enable_periph_clk(bool enable)
|
||||
/* ---------------------------------------------- ECC ------------------------------------------------- */
|
||||
|
||||
#if SOC_ECC_SUPPORTED
|
||||
#define P256_LEN (256/8)
|
||||
#define P192_LEN (192/8)
|
||||
|
||||
typedef struct {
|
||||
uint8_t x[P256_LEN]; /* Little endian order */
|
||||
uint8_t y[P256_LEN]; /* Little endian order */
|
||||
unsigned len; /* P192_LEN or P256_LEN */
|
||||
} ecc_point_t;
|
||||
|
||||
int __wrap_esp_ecc_point_multiply(const ecc_point_t *point, const uint8_t *scalar, ecc_point_t *result, bool verify_first)
|
||||
{
|
||||
esp_crypto_ecc_lock_acquire();
|
||||
@@ -541,3 +490,17 @@ void IRAM_ATTR __wrap_spi_timing_get_flash_timing_param(spi_flash_hal_timing_con
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if CONFIG_SECURE_TEE_ATTESTATION
|
||||
psa_status_t __wrap_psa_initial_attest_get_token(const uint8_t *auth_challenge, size_t challenge_size,
|
||||
uint8_t *token_buf, size_t token_buf_size, size_t *token_size)
|
||||
{
|
||||
return (esp_err_t)esp_tee_service_call_with_noniram_intr_disabled(6, SS_PSA_INITIAL_ATTEST_GET_TOKEN, auth_challenge, challenge_size,
|
||||
token_buf, token_buf_size, token_size);
|
||||
}
|
||||
|
||||
psa_status_t __wrap_psa_initial_attest_get_token_size(size_t challenge_size, size_t *token_size)
|
||||
{
|
||||
return (esp_err_t)esp_tee_service_call_with_noniram_intr_disabled(3, SS_PSA_INITIAL_ATTEST_GET_TOKEN_SIZE, challenge_size, token_size);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -28,7 +28,7 @@ set(NON_OS_BUILD 1)
|
||||
list(APPEND COMPONENTS bootloader_support efuse esp_hal_mspi esp_hal_wdt esp_security mbedtls esp_stdio)
|
||||
|
||||
# TEE-specific components
|
||||
list(APPEND COMPONENTS tee_flash_mgr tee_ota_ops tee_sec_storage tee_attestation)
|
||||
list(APPEND COMPONENTS attestation tee_flash_mgr tee_ota_ops tee_sec_storage)
|
||||
|
||||
include_directories("${SECURE_SERVICE_HEADERS_DIR}")
|
||||
|
||||
|
||||
@@ -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
|
||||
*/
|
||||
@@ -155,13 +155,31 @@ esp_err_t esp_att_utils_eat_data_to_json(struct esp_att_sw_claim_list *head, con
|
||||
esp_att_sw_claim_list_t *claim = NULL;
|
||||
char *claim_json = NULL;
|
||||
|
||||
json_gen_obj_set_int(&json_gen, "nonce", cfg->nonce);
|
||||
// Convert auth_challenge to hex string - allocate based on actual challenge size
|
||||
size_t auth_challenge_hexstr_size = cfg->challenge_size * 2 + 1;
|
||||
char *auth_challenge_hexstr = calloc(auth_challenge_hexstr_size, sizeof(char));
|
||||
if (auth_challenge_hexstr == NULL) {
|
||||
free(json_buf);
|
||||
return ESP_ERR_NO_MEM;
|
||||
}
|
||||
|
||||
esp_err_t err = esp_att_utils_hexbuf_to_hexstr(cfg->auth_challenge, cfg->challenge_size,
|
||||
auth_challenge_hexstr, auth_challenge_hexstr_size);
|
||||
if (err != ESP_OK) {
|
||||
free(auth_challenge_hexstr);
|
||||
free(json_buf);
|
||||
return err;
|
||||
}
|
||||
json_gen_obj_set_string(&json_gen, "auth_challenge", auth_challenge_hexstr);
|
||||
free(auth_challenge_hexstr);
|
||||
|
||||
json_gen_obj_set_int(&json_gen, "client_id", cfg->client_id);
|
||||
json_gen_obj_set_int(&json_gen, "device_ver", cfg->device_ver);
|
||||
|
||||
char dev_id_hexstr[ESP_ATT_EAT_DEV_ID_SZ * 2 + 1] = {0};
|
||||
esp_err_t err = esp_att_utils_hexbuf_to_hexstr(cfg->device_id, sizeof(cfg->device_id), dev_id_hexstr, sizeof(dev_id_hexstr));
|
||||
err = esp_att_utils_hexbuf_to_hexstr(cfg->device_id, sizeof(cfg->device_id), dev_id_hexstr, sizeof(dev_id_hexstr));
|
||||
if (err != ESP_OK) {
|
||||
free(json_buf);
|
||||
return err;
|
||||
}
|
||||
json_gen_obj_set_string(&json_gen, "device_id", dev_id_hexstr);
|
||||
@@ -170,6 +188,7 @@ esp_err_t esp_att_utils_eat_data_to_json(struct esp_att_sw_claim_list *head, con
|
||||
char inst_id_hexstr[DIGEST_HEXSTR_LEN] = {0};
|
||||
err = esp_att_utils_hexbuf_to_hexstr(cfg->instance_id, sizeof(cfg->instance_id), inst_id_hexstr, sizeof(inst_id_hexstr));
|
||||
if (err != ESP_OK) {
|
||||
free(json_buf);
|
||||
return err;
|
||||
}
|
||||
json_gen_obj_set_string(&json_gen, "instance_id", inst_id_hexstr);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2024-2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -165,10 +165,17 @@ exit:
|
||||
return err;
|
||||
}
|
||||
|
||||
esp_err_t esp_att_generate_token(const uint32_t nonce, const uint32_t client_id, const char *psa_cert_ref,
|
||||
uint8_t *token_buf, const size_t token_buf_size, uint32_t *token_len)
|
||||
esp_err_t esp_att_generate_token(const uint8_t *auth_challenge, size_t challenge_size,
|
||||
uint8_t *token_buf, size_t token_buf_size, size_t *token_size)
|
||||
{
|
||||
if (token_buf == NULL || token_len == NULL || psa_cert_ref == NULL) {
|
||||
if (auth_challenge == NULL || token_buf == NULL || token_buf_size == 0 || token_size == NULL) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
if (challenge_size != PSA_INITIAL_ATTEST_CHALLENGE_SIZE_32 &&
|
||||
challenge_size != PSA_INITIAL_ATTEST_CHALLENGE_SIZE_48 &&
|
||||
challenge_size != PSA_INITIAL_ATTEST_CHALLENGE_SIZE_64) {
|
||||
ESP_LOGE(TAG, "Invalid challenge size");
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
@@ -191,10 +198,13 @@ esp_err_t esp_att_generate_token(const uint32_t nonce, const uint32_t client_id,
|
||||
}
|
||||
|
||||
esp_att_token_cfg_t cfg = {
|
||||
.nonce = nonce,
|
||||
.client_id = client_id,
|
||||
.auth_challenge = (uint8_t *)auth_challenge,
|
||||
.challenge_size = challenge_size,
|
||||
/* TODO: client_id should point to the API caller (REE or TEE) */
|
||||
.client_id = 0x0FACADE0,
|
||||
/* TODO: PSA cert ref should be configurable or derived from system config */
|
||||
.psa_cert_ref = ESP_ATT_TK_PSA_CERT_REF,
|
||||
};
|
||||
memcpy(cfg.psa_cert_ref, psa_cert_ref, sizeof(cfg.psa_cert_ref));
|
||||
|
||||
err = populate_att_token_cfg(&cfg, &keypair);
|
||||
if (err != ESP_OK) {
|
||||
@@ -285,10 +295,30 @@ esp_err_t esp_att_generate_token(const uint32_t nonce, const uint32_t client_id,
|
||||
free(sign_json);
|
||||
|
||||
json_gen_end_object(&jstr);
|
||||
*token_len = json_gen_str_end(&jstr);
|
||||
*token_size = json_gen_str_end(&jstr);
|
||||
err = ESP_OK;
|
||||
|
||||
exit:
|
||||
free_sw_claim_list();
|
||||
return err;
|
||||
}
|
||||
|
||||
esp_err_t esp_att_get_token_size(size_t challenge_size, size_t *token_size)
|
||||
{
|
||||
if (token_size == NULL) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
switch (challenge_size) {
|
||||
case PSA_INITIAL_ATTEST_CHALLENGE_SIZE_32:
|
||||
case PSA_INITIAL_ATTEST_CHALLENGE_SIZE_48:
|
||||
case PSA_INITIAL_ATTEST_CHALLENGE_SIZE_64:
|
||||
*token_size = ESP_ATT_TK_MIN_SIZE;
|
||||
break;
|
||||
default:
|
||||
*token_size = UINT32_MAX;
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
*/
|
||||
@@ -14,17 +14,31 @@ extern "C" {
|
||||
/**
|
||||
* @brief Generate an entity attestation token
|
||||
*
|
||||
* @param[in] nonce Nonce value to include in the token
|
||||
* @param[in] client_id Client identifier to include in the token
|
||||
* @param[in] psa_cert_ref PSA certificate reference to include in the token
|
||||
* @param[in] auth_challenge Authentication challenge buffer
|
||||
* @param[in] challenge_size Size of the authentication challenge
|
||||
* @param[in] token_buf Buffer to store the generated token
|
||||
* @param[in] token_buf_size Size of the token buffer
|
||||
* @param[out] token_len Pointer to store the actual length of the generated token
|
||||
* @param[out] token_size Pointer to store the actual length of the generated token
|
||||
*
|
||||
* @return esp_err_t ESP_OK on success, or an error code on failure
|
||||
*/
|
||||
esp_err_t esp_att_generate_token(const uint32_t nonce, const uint32_t client_id, const char *psa_cert_ref,
|
||||
uint8_t *token_buf, const size_t token_buf_size, uint32_t *token_len);
|
||||
esp_err_t esp_att_generate_token(const uint8_t *auth_challenge, size_t challenge_size,
|
||||
uint8_t *token_buf, size_t token_buf_size, size_t *token_size);
|
||||
|
||||
/**
|
||||
* @brief Get the required buffer size for an attestation token
|
||||
*
|
||||
* @param[in] challenge_size Size of the authentication challenge in bytes
|
||||
* Must be one of: PSA_INITIAL_ATTEST_CHALLENGE_SIZE_32 (32),
|
||||
* PSA_INITIAL_ATTEST_CHALLENGE_SIZE_48 (48), or
|
||||
* PSA_INITIAL_ATTEST_CHALLENGE_SIZE_64 (64)
|
||||
* @param[out] token_size Pointer to store the required token buffer size
|
||||
*
|
||||
* @return
|
||||
* - `ESP_OK` on success
|
||||
* - `ESP_ERR_INVALID_ARG` if token_size is NULL or challenge_size is invalid
|
||||
*/
|
||||
esp_err_t esp_att_get_token_size(size_t challenge_size, size_t *token_size);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
+13
-4
@@ -12,8 +12,10 @@
|
||||
#include "esp_app_desc.h"
|
||||
|
||||
#include "esp_attestation.h"
|
||||
|
||||
#include "psa/crypto.h"
|
||||
#include "psa/initial_attestation.h"
|
||||
|
||||
#include "sdkconfig.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@@ -42,11 +44,16 @@ extern "C" {
|
||||
#define ESP_ATT_SIGN_JSON_MAX_SZ (192)
|
||||
|
||||
#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_ATT_TK_MIN_SIZE > PSA_INITIAL_ATTEST_MAX_TOKEN_SIZE
|
||||
#error "Attestation token size may exceed the bounds set by the PSA interface"
|
||||
#endif
|
||||
|
||||
#if ESP_TEE_BUILD && CONFIG_SECURE_TEE_ATTESTATION
|
||||
#define ESP_ATT_TK_KEY_ID (CONFIG_SECURE_TEE_ATT_KEY_STR_ID)
|
||||
#define ESP_ATT_TK_KEY_ID (CONFIG_SECURE_TEE_ATT_KEY_STR_ID)
|
||||
#define ESP_ATT_TK_PSA_CERT_REF (CONFIG_SECURE_TEE_ATT_PSA_CERT_REF)
|
||||
#else
|
||||
#define ESP_ATT_TK_KEY_ID ("NULL")
|
||||
#define ESP_ATT_TK_KEY_ID ("NULL")
|
||||
#define ESP_ATT_TK_PSA_CERT_REF ("NULL")
|
||||
#endif
|
||||
|
||||
/**
|
||||
@@ -112,7 +119,8 @@ typedef struct {
|
||||
* @brief Structure to hold the Entity Attestation Token initial configuration
|
||||
*/
|
||||
typedef struct {
|
||||
uint32_t nonce; /**< Nonce value */
|
||||
uint8_t *auth_challenge; /**< Authentication challenge */
|
||||
size_t challenge_size; /**< Challenge size */
|
||||
uint32_t client_id; /**< Client identifier (Attestation relying party) */
|
||||
uint32_t device_ver; /**< Device version */
|
||||
uint8_t device_id[SHA256_DIGEST_SZ]; /**< Device identifier */
|
||||
@@ -120,6 +128,7 @@ typedef struct {
|
||||
char psa_cert_ref[32]; /**< PSA certificate reference */
|
||||
uint8_t device_stat; /**< Flags indicating device status */
|
||||
} esp_att_token_cfg_t;
|
||||
|
||||
/**
|
||||
* @brief Structure to hold an ECDSA key pair
|
||||
*/
|
||||
|
||||
@@ -1,17 +0,0 @@
|
||||
idf_build_get_property(esp_tee_build ESP_TEE_BUILD)
|
||||
|
||||
set(srcs)
|
||||
set(include_dirs ".")
|
||||
set(priv_requires esp_tee)
|
||||
|
||||
if(esp_tee_build)
|
||||
list(APPEND priv_requires attestation main)
|
||||
endif()
|
||||
|
||||
if(CONFIG_SECURE_TEE_ATTESTATION)
|
||||
list(APPEND srcs "esp_tee_attestation.c")
|
||||
endif()
|
||||
|
||||
idf_component_register(SRCS ${srcs}
|
||||
INCLUDE_DIRS ${include_dirs}
|
||||
PRIV_REQUIRES ${priv_requires})
|
||||
@@ -1,55 +0,0 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
#include <inttypes.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "esp_log.h"
|
||||
#include "esp_err.h"
|
||||
|
||||
#if ESP_TEE_BUILD
|
||||
#include "esp_fault.h"
|
||||
#include "esp_tee_memory_utils.h"
|
||||
#include "esp_attestation.h"
|
||||
#endif
|
||||
|
||||
#include "esp_tee.h"
|
||||
#include "secure_service_num.h"
|
||||
|
||||
#include "sdkconfig.h"
|
||||
|
||||
static __attribute__((unused)) const char *TAG = "esp_tee_att";
|
||||
|
||||
#if ESP_TEE_BUILD
|
||||
|
||||
esp_err_t _ss_esp_tee_att_generate_token(const uint32_t nonce, const uint32_t client_id, const char *psa_cert_ref,
|
||||
uint8_t *token_buf, const size_t token_buf_size, uint32_t *token_len)
|
||||
{
|
||||
bool valid_addr = (esp_tee_ptr_in_ree((void *)psa_cert_ref) &&
|
||||
esp_tee_ptr_in_ree((void *)token_buf) &&
|
||||
esp_tee_ptr_in_ree((void *)token_len));
|
||||
valid_addr &= (esp_tee_ptr_in_ree((void *)((char *)psa_cert_ref + 20)) &&
|
||||
esp_tee_ptr_in_ree((void *)((char *)token_buf + token_buf_size)));
|
||||
|
||||
if (!valid_addr) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
ESP_FAULT_ASSERT(valid_addr);
|
||||
|
||||
return esp_att_generate_token(nonce, client_id, psa_cert_ref, token_buf, token_buf_size, token_len);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
esp_err_t esp_tee_att_generate_token(const uint32_t nonce, const uint32_t client_id, const char *psa_cert_ref,
|
||||
uint8_t *token_buf, const size_t token_buf_size, uint32_t *token_len)
|
||||
{
|
||||
return (esp_err_t)esp_tee_service_call_with_noniram_intr_disabled(7, SS_ESP_TEE_ATT_GENERATE_TOKEN, nonce, client_id,
|
||||
psa_cert_ref, token_buf, token_buf_size, token_len);
|
||||
}
|
||||
#endif
|
||||
@@ -1,42 +0,0 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "esp_err.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Generate and return an entity attestation token (EAT) from the TEE
|
||||
*
|
||||
* The EAT consists of the below details:
|
||||
* - For all firmware images (Bootloader, active TEE and non-secure app)
|
||||
* - Project and ESP-IDF version
|
||||
* - Digest (SHA256)
|
||||
* - Public key corresponding to the private key used for signing (in compressed format)
|
||||
* - Signature generated using the ECDSA key stored in the configured slot of the TEE's Secure Storage (`r` and `s` components)
|
||||
*
|
||||
* @param[in] nonce Attestation request identification
|
||||
* @param[in] client_id Relying Party identification
|
||||
* @param[in] psa_cert_ref PSA certification ID
|
||||
* @param[in] token_buf Output buffer which will hold the resultant EAT in JSON format
|
||||
* @param[in] token_buf_size Size of the output buffer
|
||||
* @param[out] token_len Actual length of the output EAT JSON
|
||||
*
|
||||
* @return
|
||||
* - `ESP_OK` on success
|
||||
* - `ESP_ERR_INVALID_ARG` in case token_buf or token_len are NULL or token_buf_size is 0
|
||||
* - `ESP_ERR_NO_MEM` in case memory could not be allocated for the internal structures
|
||||
* - `ESP_FAIL` other errors
|
||||
*/
|
||||
esp_err_t esp_tee_att_generate_token(const uint32_t nonce, const uint32_t client_id, const char *psa_cert_ref,
|
||||
uint8_t *token_buf, const size_t token_buf_size, uint32_t *token_len);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
@@ -1,10 +1,11 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2024-2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "esp_err.h"
|
||||
#include "esp_fault.h"
|
||||
#include "soc/soc_caps.h"
|
||||
|
||||
@@ -24,6 +25,7 @@
|
||||
#if SOC_ECC_SUPPORTED
|
||||
#include "ecc_impl.h"
|
||||
#endif
|
||||
#include "psa/initial_attestation.h"
|
||||
#include "esp_crypto_periph_clk.h"
|
||||
|
||||
#include "esp_tee.h"
|
||||
@@ -32,6 +34,9 @@
|
||||
|
||||
#include "esp_tee_sec_storage.h"
|
||||
#include "esp_tee_ota_ops.h"
|
||||
#include "esp_attestation.h"
|
||||
|
||||
#include "sdkconfig.h"
|
||||
|
||||
static __attribute__((unused)) const char *TAG = "esp_tee_sec_srv";
|
||||
|
||||
@@ -426,3 +431,49 @@ esp_err_t _ss_esp_tee_sec_storage_gen_key(const esp_tee_sec_storage_key_cfg_t *c
|
||||
{
|
||||
return esp_tee_sec_storage_gen_key(cfg);
|
||||
}
|
||||
|
||||
/* ---------------------------------------------- PSA Attestation ------------------------------------------------- */
|
||||
|
||||
__attribute__((unused)) static psa_status_t esp_err_to_psa_status(esp_err_t err)
|
||||
{
|
||||
switch (err) {
|
||||
case ESP_OK:
|
||||
return PSA_SUCCESS;
|
||||
case ESP_ERR_INVALID_ARG:
|
||||
return PSA_ERROR_INVALID_ARGUMENT;
|
||||
case ESP_ERR_INVALID_SIZE:
|
||||
return PSA_ERROR_BUFFER_TOO_SMALL;
|
||||
default:
|
||||
return PSA_ERROR_GENERIC_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
psa_status_t _ss_psa_initial_attest_get_token(const uint8_t *auth_challenge, size_t challenge_size,
|
||||
uint8_t *token_buf, size_t token_buf_size, size_t *token_size)
|
||||
{
|
||||
#if CONFIG_SECURE_TEE_ATTESTATION
|
||||
bool valid_addr = (esp_tee_ptr_in_ree((void *)auth_challenge) &&
|
||||
esp_tee_ptr_in_ree((void *)token_buf) &&
|
||||
esp_tee_ptr_in_ree((void *)token_size));
|
||||
valid_addr &= (esp_tee_ptr_in_ree((void *)((uint8_t *)auth_challenge + challenge_size)) &&
|
||||
esp_tee_ptr_in_ree((void *)((uint8_t *)token_buf + token_buf_size)));
|
||||
|
||||
if (!valid_addr) {
|
||||
return PSA_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
ESP_FAULT_ASSERT(valid_addr);
|
||||
|
||||
return esp_err_to_psa_status(esp_att_generate_token(auth_challenge, challenge_size, token_buf, token_buf_size, token_size));
|
||||
#else
|
||||
return PSA_ERROR_NOT_SUPPORTED;
|
||||
#endif
|
||||
}
|
||||
|
||||
psa_status_t _ss_psa_initial_attest_get_token_size(size_t challenge_size, size_t *token_size)
|
||||
{
|
||||
#if CONFIG_SECURE_TEE_ATTESTATION
|
||||
return esp_err_to_psa_status(esp_att_get_token_size(challenge_size, token_size));
|
||||
#else
|
||||
return PSA_ERROR_NOT_SUPPORTED;
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -188,7 +188,6 @@ endif()
|
||||
set(mbedtls_targets mbedtls mbedx509 tfpsacrypto builtin)
|
||||
|
||||
target_include_directories(tfpsacrypto PUBLIC "port/include")
|
||||
target_include_directories(tfpsacrypto PRIVATE "port/psa_crypto_storage/include")
|
||||
|
||||
if(CONFIG_MBEDTLS_HARDWARE_SHA OR CONFIG_MBEDTLS_HARDWARE_AES)
|
||||
target_include_directories(tfpsacrypto PUBLIC "${COMPONENT_DIR}/port/psa_driver/include")
|
||||
@@ -241,6 +240,11 @@ if(NOT ${IDF_TARGET} STREQUAL "linux")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# PSA Attestation
|
||||
if(CONFIG_SECURE_TEE_ATTESTATION)
|
||||
target_sources(tfpsacrypto PRIVATE "${COMPONENT_DIR}/port/psa_attestation/psa_initial_attestation.c")
|
||||
endif()
|
||||
|
||||
if(CONFIG_MBEDTLS_DYNAMIC_BUFFER)
|
||||
set(mbedtls_target_sources ${mbedtls_target_sources}
|
||||
"${COMPONENT_DIR}/port/dynamic/esp_mbedtls_dynamic_impl.c"
|
||||
|
||||
@@ -118,3 +118,6 @@ if(CONFIG_SOC_HMAC_SUPPORTED)
|
||||
# HMAC-based PBKDF2 implementation
|
||||
target_sources(tfpsacrypto PRIVATE "${COMPONENT_DIR}/port/esp_hmac_pbkdf2.c")
|
||||
endif()
|
||||
|
||||
# PSA Attestation
|
||||
target_include_directories(tfpsacrypto PUBLIC "${COMPONENT_DIR}/port/psa_attestation")
|
||||
|
||||
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* PSA Attestation implementation
|
||||
*/
|
||||
|
||||
#ifndef PSA_INITIAL_ATTESTATION_H
|
||||
#define PSA_INITIAL_ATTESTATION_H
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "psa/crypto_values.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define PSA_INITIAL_ATTEST_API_VERSION_MAJOR 1 /*!< Major version of this implementation of the Attestation API */
|
||||
#define PSA_INITIAL_ATTEST_API_VERSION_MINOR 0 /*!< Minor version of this implementation of the Attestation API */
|
||||
|
||||
#define PSA_INITIAL_ATTEST_MAX_TOKEN_SIZE 2048 /*!< Maximum size of an attestation token in bytes */
|
||||
|
||||
#define PSA_INITIAL_ATTEST_CHALLENGE_SIZE_32 (32u)
|
||||
#define PSA_INITIAL_ATTEST_CHALLENGE_SIZE_48 (48u)
|
||||
#define PSA_INITIAL_ATTEST_CHALLENGE_SIZE_64 (64u)
|
||||
#define PSA_INITIAL_ATTEST_CHALLENGE_SIZE_MAX (PSA_INITIAL_ATTEST_CHALLENGE_SIZE_64) /*!< Maximum supported challenge size */
|
||||
|
||||
/**
|
||||
* @brief Generate an entity attestation token
|
||||
*
|
||||
* Generates an attestation token containing device identity and security claims, signed and
|
||||
* encoded in the JSON format.
|
||||
*
|
||||
* @param auth_challenge Pointer to a buffer containing the challenge data from the verifier
|
||||
* @param challenge_size Size of the challenge in bytes. Must be 32, 48, or 64 bytes
|
||||
* @param token_buf Pointer to a buffer where the attestation token will be written
|
||||
* @param token_buf_size Size of the token buffer in bytes
|
||||
* @param token_size On success, will be set to the actual size of the generated token
|
||||
*
|
||||
* @return psa_status_t PSA_SUCCESS on success,
|
||||
* PSA_ERROR_INVALID_ARGUMENT if parameters are invalid,
|
||||
* PSA_ERROR_BUFFER_TOO_SMALL if token_buf is too small,
|
||||
* PSA_ERROR_NOT_SUPPORTED if the requested challenge size is not supported,
|
||||
* or another error code on failure
|
||||
*/
|
||||
psa_status_t psa_initial_attest_get_token(const uint8_t *auth_challenge, size_t challenge_size,
|
||||
uint8_t *token_buf, size_t token_buf_size, size_t *token_size);
|
||||
|
||||
/**
|
||||
* @brief Get the size of the attestation token that would be generated
|
||||
*
|
||||
* This can be used to allocate an appropriately sized buffer before calling psa_initial_attest_get_token().
|
||||
*
|
||||
* @param challenge_size Size of the challenge in bytes. Must be 32, 48, or 64 bytes
|
||||
* @param token_size On success, will be set to the size of the token that would be generated
|
||||
*
|
||||
* @return psa_status_t PSA_SUCCESS on success,
|
||||
* PSA_ERROR_INVALID_ARGUMENT if challenge_size is invalid,
|
||||
* PSA_ERROR_NOT_SUPPORTED if the requested challenge size is not supported,
|
||||
* or another error code on failure
|
||||
*/
|
||||
psa_status_t psa_initial_attest_get_token_size(size_t challenge_size, size_t *token_size);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // PSA_INITIAL_ATTESTATION_H
|
||||
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* PSA Attestation implementation
|
||||
*/
|
||||
|
||||
#include "mbedtls/platform.h"
|
||||
#include "mbedtls/platform_util.h"
|
||||
#include "psa/initial_attestation.h"
|
||||
|
||||
#include <limits.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "esp_log.h"
|
||||
|
||||
static const char *TAG = "esp_psa_initial_attest";
|
||||
|
||||
/**
|
||||
* @brief Dummy implementation of PSA attestation APIs
|
||||
*
|
||||
*/
|
||||
psa_status_t psa_initial_attest_get_token(const uint8_t *auth_challenge, size_t challenge_size,
|
||||
uint8_t *token_buf, size_t token_buf_size, size_t *token_size)
|
||||
{
|
||||
ESP_LOGE(TAG, "Attestation service is not supported");
|
||||
return PSA_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
psa_status_t psa_initial_attest_get_token_size(size_t challenge_size, size_t *token_size)
|
||||
{
|
||||
ESP_LOGE(TAG, "Attestation service is not supported");
|
||||
return PSA_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
Reference in New Issue
Block a user