Secure Storage

Overview

The TEE Secure Storage service offers a persistent storage for securely holding sensitive data, such as cryptographic keys, cloud credentials or any other general-purpose information. It utilizes a dedicated flash partition of type data and subtype tee_sec_stg. The confidentiality and integrity of the data is ensured by the TEE.

For enhanced security, data stored in the secure storage is encrypted using a device-specific encryption key with AES-256-GCM algorithm. Additionally, the secure storage provides interfaces for performing the following cryptographic services from the TEE using securely stored key material:

  1. Message signing and public key retrieval with the ecdsa_secp256r1 algorithm

  2. Authenticated encryption and decryption using the aes256_gcm algorithm

Internals

The secure storage partition is 4 KB in size, of which only the first half is used for storing data. The partition is divided into slots which hold data objects. Each data object within the TEE secure storage is encapsulated in a structured format, comprising the metadata and actual data.

TEE Secure storage partition

ESP-TEE: Secure Storage partition

Metadata is represented by the sec_stg_metadata_t structure, which contains details related to the data stored in a specific slot of the storage. These details include information such as the owner, slot ID, data length, encryption parameters, etc.

Element

Description

Owner ID

Application ID defining the data ownership

Slot ID

Slot ID for corresponding owner ID

Encryption: Initialization Vector (IV)

IV for the encryption algorithm

Encryption: Tag

Tag for the encryption algorithm

Data Type

Type of data stored in this slot

Data Length

Actual data length

TEE Secure storage metadata

ESP-TEE: Secure Storage Metadata

Warning

Future ESP-TEE framework releases may modify the internal data structure of the TEE secure storage, which could introduce breaking changes in existing applications.

Each data object in the secure storage is encrypted as specified in the AES-GCM based AEAD encryption policy with a platform instance unique key of length 256 bits, stored in the eFuse.

The TEE Secure Storage feature supports two modes (CONFIG_SECURE_TEE_SEC_STG_MODE) for determining which eFuse block stores the encryption key:

  • Development Mode: The encryption key is embedded (constant for all instances) in the ESP-TEE firmware.

  • Release Mode: The encryption key is stored in eFuse BLK4 - BLK9, depending on the CONFIG_SECURE_TEE_SEC_STG_KEY_EFUSE_BLK Kconfig option.

All the assets pertaining to the TEE secure storage are protected by the APM peripheral and thus, are inaccessible to the REE application. Any attempt to directly access them would result in a system fault.

Note

  • Currently, the TEE secure storage supports the storage of two types of cryptographic keys:

    1. ecdsa_secp256r1 curve key-pairs, including the private and public key components

    2. aes256_gcm keys, including the key and initialization vector (IV)

The internal structures for these key types are as follows:

#define ECDSA_SECP256R1_KEY_LEN  32
#define AES256_GCM_KEY_LEN       32
#define AES256_GCM_IV_LEN        12

typedef struct {
    /* Private key */
    uint8_t priv_key[ECDSA_SECP256R1_KEY_LEN];
    /* Public key - X and Y components */
    uint8_t pub_key[2 * ECDSA_SECP256R1_KEY_LEN];
} sec_stg_ecdsa_secp256r1_t;

typedef struct {
    /* Key */
    uint8_t key[AES256_GCM_KEY_LEN];
    /* Initialization Vector */
    uint8_t iv[AES256_GCM_IV_LEN];
} sec_stg_aes256_gcm_t;
  • Future updates may include support for additional key types and general-purpose data storage.

Application Example

The tee_secure_storage example demonstrates how to generate ECDSA key pairs and AES-256-GCM keys in the TEE secure storage and use them for signing messages and encrypting/decrypting data.

API Reference

Note

To use the TEE Secure Storage APIs in your project, ensure that the tee_sec_storage component is listed as a local dependency in the component manager manifest file idf_component.yml. Refer to the tee_secure_storage example for guidance.

Header File

Functions

esp_err_t esp_tee_sec_storage_init(void)

Initialize the TEE secure storage partition.

Returns:

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)

Generate a unique key and store it in the given secure storage slot.

Parameters:
  • slot_id -- secure storage slot ID

  • key_type -- secure storage key type to generate

Returns:

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)

Generate and return the signature for the specified message digest using the key pair located in the given secure storage slot.

Parameters:
  • slot_id -- [in] secure storage slot ID

  • key_type -- [in] secure storage key type

  • hash -- [in] Message digest

  • hlen -- [in] Digest length

  • out_sign -- [out] Output context holding the signature

Returns:

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)

Return the public key for the given secure storage slot.

Parameters:
  • slot_id -- [in] secure storage slot ID

  • key_type -- [in] secure storage key type

  • pubkey -- [out] Output context holding the public key

Returns:

esp_err_t ESP_OK on success, appropriate error code otherwise.

bool esp_tee_sec_storage_is_slot_empty(uint16_t slot_id)

Check whether the given slot in the secure storage is empty or not.

Parameters:

slot_id -- secure storage slot ID

Returns:

bool true: slot is empty; false otherwise.

esp_err_t esp_tee_sec_storage_clear_slot(uint16_t slot_id)

Erase the given secure storage slot.

Parameters:

slot_id -- secure storage slot ID

Returns:

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)

Perform encryption using AES256-GCM with the key stored in the specified slot.

Parameters:
  • slot_id -- [in] Secure storage slot ID containing the AES-GCM key

  • input -- [in] Pointer to the input data buffer

  • len -- [in] Length of the input data

  • aad -- [in] Pointer to the Additional Authenticated Data (AAD)

  • aad_len -- [in] Length of the AAD

  • tag -- [out] Pointer to the authentication tag buffer

  • tag_len -- [out] Length of the authentication tag

  • output -- [out] Pointer to the output data buffer

Returns:

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)

Perform decryption using AES256-GCM with the key stored in the specified slot.

Parameters:
  • slot_id -- [in] Secure storage slot ID containing the AES-GCM key

  • input -- [in] Pointer to the input data buffer

  • len -- [in] Length of the input data

  • aad -- [in] Pointer to the Additional Authenticated Data (AAD)

  • aad_len -- [in] Length of the AAD

  • tag -- [in] Pointer to the authentication tag buffer

  • tag_len -- [in] Length of the authentication tag

  • output -- [out] Pointer to the output data buffer

Returns:

esp_err_t ESP_OK on success, appropriate error code otherwise.

Structures

struct esp_tee_sec_storage_pubkey_t

Structure holding the X and Y components of the ECDSA public key.

Public Members

uint8_t pub_x[MAX_ECDSA_SUPPORTED_KEY_LEN]

X component

uint8_t pub_y[MAX_ECDSA_SUPPORTED_KEY_LEN]

Y component

struct esp_tee_sec_storage_sign_t

Structure holding the R and S components of the ECDSA signature.

Public Members

uint8_t sign_r[MAX_ECDSA_SUPPORTED_KEY_LEN]

R component

uint8_t sign_s[MAX_ECDSA_SUPPORTED_KEY_LEN]

S component

Macros

MIN_SEC_STG_SLOT_ID

Minimum secure storage slot ID

MAX_SEC_STG_SLOT_ID

Maximum secure storage slot ID

MAX_ECDSA_SUPPORTED_KEY_LEN

Maximum supported size for the ECDSA key

MAX_AES_SUPPORTED_KEY_LEN

Maximum supported size for the AES key

Enumerations

enum esp_tee_sec_storage_type_t

Enum to represent the type of key stored in the secure storage.

Values:

enumerator ESP_SEC_STG_KEY_ECDSA_SECP256R1
enumerator ESP_SEC_STG_KEY_AES256
enumerator ESP_SEC_STG_KEY_ECDSA_SECP192R1
enumerator ESP_SEC_STG_MAX

Was this page helpful?