Merge branch 'fix/additional_validation_checks' into 'master'

Some additional validation checks and new API for esp_ds_encrypt_params using KM

See merge request espressif/esp-idf!46312
This commit is contained in:
Mahavir Jain
2026-03-20 13:17:05 +05:30
12 changed files with 172 additions and 35 deletions
+3 -1
View File
@@ -639,7 +639,9 @@ static esp_err_t set_pki_context(esp_tls_t *tls, const esp_tls_pki_t *pki)
esp_ecdsa_opaque_key_t opaque_key = {
.curve = curve,
.efuse_block = tls->ecdsa_efuse_blk,
.use_km_key = false,
#if SOC_KEY_MANAGER_SUPPORTED
.key_recovery_info = NULL,
#endif /* SOC_KEY_MANAGER_SUPPORTED */
};
// Import opaque key reference
@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2025-2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Unlicense OR CC0-1.0
*/
@@ -24,6 +24,11 @@
+ ESP_DS_SIGNATURE_M_PRIME_BIT_LEN \
+ ESP_DS_SIGNATURE_L_BIT_LEN \
+ ESP_DS_SIGNATURE_PADDING_BIT_LEN) / 8))
typedef enum {
ESP_DS_KEY_HMAC,
ESP_DS_KEY_AES,
ESP_DS_KEY_MAX,
} esp_ds_key_type_t;
typedef enum {
ESP_DS_RSA_1024 = (1024 / 32) - 1,
@@ -164,11 +164,16 @@ static esp_err_t esp_ds_sign(const void *message,
return esp_ds_finish_sign(signature, data);
}
static esp_err_t esp_ds_encrypt_params(esp_ds_data_t *data,
const void *iv,
const esp_ds_p_data_t *p_data,
const void *key)
static esp_err_t esp_ds_encrypt_params_using_key_type(esp_ds_data_t *data,
const void *iv,
const esp_ds_p_data_t *p_data,
const void *key,
esp_ds_key_type_t key_type)
{
if (key_type >= ESP_DS_KEY_MAX) {
return ESP_ERR_INVALID_ARG;
}
if (!p_data) {
return ESP_ERR_INVALID_ARG;
}
@@ -188,7 +193,7 @@ static esp_err_t esp_ds_encrypt_params(esp_ds_data_t *data,
ets_ds_data_t *ds_data = (ets_ds_data_t *) data;
const ets_ds_p_data_t *ds_plain_data = (const ets_ds_p_data_t *) p_data;
ets_ds_result_t ets_result = ets_ds_encrypt_params(ds_data, iv, ds_plain_data, key, ETS_DS_KEY_HMAC);
ets_ds_result_t ets_result = ets_ds_encrypt_params(ds_data, iv, ds_plain_data, key, (ets_ds_key_t) key_type);
if (ets_result == ETS_DS_INVALID_PARAM) {
result = ESP_ERR_INVALID_ARG;
@@ -286,11 +291,16 @@ static esp_err_t esp_ds_sign(const void *message,
return esp_ds_finish_sign(signature, (void *)data);
}
static esp_err_t esp_ds_encrypt_params(esp_ds_data_t *data,
const void *iv,
const esp_ds_p_data_t *p_data,
const void *key)
static esp_err_t esp_ds_encrypt_params_using_key_type(esp_ds_data_t *data,
const void *iv,
const esp_ds_p_data_t *p_data,
const void *key,
esp_ds_key_type_t key_type)
{
if (key_type >= ESP_DS_KEY_MAX) {
return ESP_ERR_INVALID_ARG;
}
assert(esp_ptr_internal(p_data) && esp_ptr_word_aligned(p_data));
esp_err_t result = ESP_OK;
@@ -301,7 +311,7 @@ static esp_err_t esp_ds_encrypt_params(esp_ds_data_t *data,
ets_ds_data_t *ds_data = (ets_ds_data_t *) data;
const ets_ds_p_data_t *ds_plain_data = (const ets_ds_p_data_t *) p_data;
ets_ds_result_t ets_result = ets_ds_encrypt_params(ds_data, iv, ds_plain_data, key, ETS_DS_KEY_HMAC);
ets_ds_result_t ets_result = ets_ds_encrypt_params(ds_data, iv, ds_plain_data, key, (ets_ds_key_t) key_type);
if (ets_result == ETS_DS_INVALID_PARAM) {
result = ESP_ERR_INVALID_ARG;
@@ -343,8 +353,8 @@ TEST(ds, digital_signature_parameter_encryption)
p_data.M_prime = t->p_data.M_prime;
p_data.length = t->p_data.length;
esp_err_t r = esp_ds_encrypt_params(&result, t->iv, &p_data,
test_hmac_keys[t->hmac_key_idx]);
esp_err_t r = esp_ds_encrypt_params_using_key_type(&result, t->iv, &p_data,
test_hmac_keys[t->hmac_key_idx], ESP_DS_KEY_HMAC);
ESP_LOGI(TAG, "Encrypting test case %d done", i);
TEST_ASSERT_EQUAL(ESP_OK, r);
TEST_ASSERT_EQUAL(t->p_data.length, result.rsa_length);
+43 -2
View File
@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2020-2025 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2020-2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -27,6 +27,7 @@ extern "C" {
#define ESP_DS_SIGNATURE_M_PRIME_BIT_LEN 32
#define ESP_DS_SIGNATURE_L_BIT_LEN 32
#define ESP_DS_SIGNATURE_PADDING_BIT_LEN 64
#define ESP_DS_DATA_KEY_SIZE 32
/* Length of parameter 'C' stored in flash, in bytes
- Operands Y, M and r_bar; each equal to maximum RSA bit length
@@ -40,6 +41,12 @@ extern "C" {
+ ESP_DS_SIGNATURE_L_BIT_LEN \
+ ESP_DS_SIGNATURE_PADDING_BIT_LEN) / 8))
typedef enum {
ESP_DS_KEY_HMAC,
ESP_DS_KEY_AES,
ESP_DS_KEY_MAX,
} esp_ds_key_type_t;
/**
* @brief Context object used for non-blocking digital signature operations
*
@@ -223,7 +230,7 @@ esp_err_t esp_ds_finish_sign(void *signature, esp_ds_context_t *esp_ds_ctx);
* @param p_data Pointer to input plaintext key data. The expectation is this data will be deleted after this process
* is done and 'data' is stored.
* @param key Pointer to 32 bytes of key data. Type determined by key_type parameter. The expectation is the
* corresponding HMAC key will be stored to efuse and then permanently erased.
* corresponding HMAC key will be stored to efuse and then permanently erased for ESP_DS_KEY_HMAC.
*
* @note
* The numbers Y, M, Rb which are a part of esp_ds_data_t should be provided in little endian format
@@ -241,6 +248,40 @@ esp_err_t esp_ds_encrypt_params(esp_ds_data_t *data,
const esp_ds_p_data_t *p_data,
const void *key);
/**
* @brief Encrypt the private key parameters.
*
* The encryption is a prerequisite step before any signature operation can be done.
* It is not strictly necessary to use this encryption function, the encryption could also happen on an external
* device.
*
* @param data Output buffer to store encrypted data, suitable for later use generating signatures.
* @param iv Pointer to 16 byte IV buffer, will be copied into 'data'. Should be randomly generated bytes each time.
* @param p_data Pointer to input plaintext key data. The expectation is this data will be deleted after this process
* is done and 'data' is stored.
* @param key Pointer to 32 bytes of key data. Type determined by key_type parameter. The expectation is the
* corresponding HMAC key will be stored to efuse and then permanently erased for ESP_DS_KEY_HMAC.
* or the AES key will be used by the the DS peripheral (internally) to decrypt the encrypted RSA private key
* parameters for ESP_DS_KEY_AES.
* @param key_type The type of key parameter (either ESP_DS_KEY_HMAC or ESP_DS_KEY_AES).
*
* @note
* The numbers Y, M, Rb which are a part of esp_ds_data_t should be provided in little endian format
* and should be of length equal to the RSA private key bit length
* The message length in bits should also be equal to the RSA private key bit length.
* No padding is applied to the message automatically, Please ensure the message is appropriate padded before
* calling the API.
*
* @return
* - ESP_OK if successful, the ds operation has been finished and the result is written to signature.
* - ESP_ERR_INVALID_ARG if one of the parameters is NULL or p_data->rsa_length is too long
*/
esp_err_t esp_ds_encrypt_params_using_key_type(esp_ds_data_t *data,
const void *iv,
const esp_ds_p_data_t *p_data,
const void *key,
esp_ds_key_type_t key_type);
#ifdef __cplusplus
}
#endif
+38 -11
View File
@@ -203,11 +203,16 @@ esp_err_t esp_ds_finish_sign(void *signature, esp_ds_context_t *esp_ds_ctx)
return return_value;
}
esp_err_t esp_ds_encrypt_params(esp_ds_data_t *data,
const void *iv,
const esp_ds_p_data_t *p_data,
const void *key)
static esp_err_t ds_encrypt_params_using_key_type(esp_ds_data_t *data,
const void *iv,
const esp_ds_p_data_t *p_data,
const void *key,
esp_ds_key_type_t key_type)
{
if (key_type >= ESP_DS_KEY_MAX) {
return ESP_ERR_INVALID_ARG;
}
// p_data has to be valid, in internal memory and word aligned
if (!p_data) {
return ESP_ERR_INVALID_ARG;
@@ -223,7 +228,7 @@ esp_err_t esp_ds_encrypt_params(esp_ds_data_t *data,
ets_ds_data_t *ds_data = (ets_ds_data_t *) data;
const ets_ds_p_data_t *ds_plain_data = (const ets_ds_p_data_t *) p_data;
ets_ds_result_t ets_result = ets_ds_encrypt_params(ds_data, iv, ds_plain_data, key, ETS_DS_KEY_HMAC);
ets_ds_result_t ets_result = ets_ds_encrypt_params(ds_data, iv, ds_plain_data, key, (ets_ds_key_t) key_type);
if (ets_result == ETS_DS_INVALID_PARAM) {
result = ESP_ERR_INVALID_ARG;
@@ -423,18 +428,23 @@ esp_err_t esp_ds_finish_sign(void *signature, esp_ds_context_t *esp_ds_ctx)
return return_value;
}
esp_err_t esp_ds_encrypt_params(esp_ds_data_t *data,
const void *iv,
const esp_ds_p_data_t *p_data,
const void *key)
static esp_err_t ds_encrypt_params_using_key_type(esp_ds_data_t *data,
const void *iv,
const esp_ds_p_data_t *p_data,
const void *key,
esp_ds_key_type_t key_type)
{
if (key_type >= ESP_DS_KEY_MAX) {
return ESP_ERR_INVALID_ARG;
}
if (!p_data) {
return ESP_ERR_INVALID_ARG;
}
esp_err_t result = ESP_OK;
// The `esp_ds_encrypt_params` operation does not use the Digital Signature peripheral,
// The `esp_ds_encrypt_params_using_key_type` operation does not use the Digital Signature peripheral,
// but just the AES and SHA peripherals, so acquiring locks just for these peripherals
// would be enough rather than acquiring a lock for the Digital Signature peripheral.
esp_crypto_sha_aes_lock_acquire();
@@ -446,7 +456,7 @@ esp_err_t esp_ds_encrypt_params(esp_ds_data_t *data,
ets_ds_data_t *ds_data = (ets_ds_data_t *) data;
const ets_ds_p_data_t *ds_plain_data = (const ets_ds_p_data_t *) p_data;
ets_ds_result_t ets_result = ets_ds_encrypt_params(ds_data, iv, ds_plain_data, key, ETS_DS_KEY_HMAC);
ets_ds_result_t ets_result = ets_ds_encrypt_params(ds_data, iv, ds_plain_data, key, (ets_ds_key_t) key_type);
if (ets_result == ETS_DS_INVALID_PARAM) {
result = ESP_ERR_INVALID_ARG;
@@ -461,3 +471,20 @@ esp_err_t esp_ds_encrypt_params(esp_ds_data_t *data,
return result;
}
#endif
esp_err_t esp_ds_encrypt_params_using_key_type(esp_ds_data_t *data,
const void *iv,
const esp_ds_p_data_t *p_data,
const void *key,
esp_ds_key_type_t key_type)
{
return ds_encrypt_params_using_key_type(data, iv, p_data, key, key_type);
}
esp_err_t esp_ds_encrypt_params(esp_ds_data_t *data,
const void *iv,
const esp_ds_p_data_t *p_data,
const void *key)
{
return ds_encrypt_params_using_key_type(data, iv, p_data, key, ESP_DS_KEY_HMAC);
}
@@ -561,6 +561,11 @@ esp_err_t esp_key_mgr_activate_key(esp_key_mgr_key_recovery_info_t *key_recovery
return ESP_ERR_INVALID_ARG;
}
if (key_recovery_info->magic != KEY_HUK_SECTOR_MAGIC) {
ESP_LOGE(TAG, "Invalid key recovery info magic");
return ESP_ERR_INVALID_ARG;
}
esp_key_mgr_key_type_t key_type = key_recovery_info->key_type;
ESP_LOGD(TAG, "Activating key of type %d", key_type);
@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2020-2023 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2020-2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -79,7 +79,7 @@ TEST_CASE("Digital Signature Parameter Encryption data NULL", "[hw_crypto] [ds]"
esp_ds_p_data_t p_data = {0};
const char key [32] = {0};
TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, esp_ds_encrypt_params(NULL, iv, &p_data, key));
TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, esp_ds_encrypt_params_using_key_type(NULL, iv, &p_data, key, ESP_DS_KEY_HMAC));
}
TEST_CASE("Digital Signature Parameter Encryption iv NULL", "[hw_crypto] [ds]")
@@ -88,7 +88,7 @@ TEST_CASE("Digital Signature Parameter Encryption iv NULL", "[hw_crypto] [ds]")
esp_ds_p_data_t p_data = {0};
const char key [32] = {0};
TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, esp_ds_encrypt_params(&data, NULL, &p_data, key));
TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, esp_ds_encrypt_params_using_key_type(&data, NULL, &p_data, key, ESP_DS_KEY_HMAC));
}
TEST_CASE("Digital Signature Parameter Encryption p_data NULL", "[hw_crypto] [ds]")
@@ -97,7 +97,7 @@ TEST_CASE("Digital Signature Parameter Encryption p_data NULL", "[hw_crypto] [ds
const char iv [32] = {0};
const char key [32] = {0};
TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, esp_ds_encrypt_params(&data, iv, NULL, key));
TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, esp_ds_encrypt_params_using_key_type(&data, iv, NULL, key, ESP_DS_KEY_HMAC));
}
TEST_CASE("Digital Signature Parameter Encryption key NULL", "[hw_crypto] [ds]")
@@ -106,7 +106,7 @@ TEST_CASE("Digital Signature Parameter Encryption key NULL", "[hw_crypto] [ds]")
const char iv [32] = {0};
esp_ds_p_data_t p_data = {0};
TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, esp_ds_encrypt_params(&data, iv, &p_data, NULL));
TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, esp_ds_encrypt_params_using_key_type(&data, iv, &p_data, NULL, ESP_DS_KEY_HMAC));
}
TEST_CASE("Digital Signature Parameter Encryption", "[hw_crypto] [ds]")
@@ -123,8 +123,8 @@ TEST_CASE("Digital Signature Parameter Encryption", "[hw_crypto] [ds]")
p_data.M_prime = t->p_data.M_prime;
p_data.length = t->p_data.length;
esp_err_t r = esp_ds_encrypt_params(&result, t->iv, &p_data,
test_hmac_keys[t->hmac_key_idx]);
esp_err_t r = esp_ds_encrypt_params_using_key_type(&result, t->iv, &p_data,
test_hmac_keys[t->hmac_key_idx], ESP_DS_KEY_HMAC);
printf("Encrypting test case %d done\n", i);
TEST_ASSERT_EQUAL(ESP_OK, r);
TEST_ASSERT_EQUAL(t->p_data.length, result.rsa_length);
@@ -301,6 +301,10 @@ secure_services:
type: IDF
function: esp_sha_512_t_init_hash
args: 1
- id: 113
type: IDF
function: esp_ds_encrypt_params_using_key_type
args: 5
# ID: 134-169 (36) - Reserved for future use
- family: attestation
entries:
@@ -241,6 +241,10 @@ secure_services:
type: IDF
function: esp_sha_set_mode
args: 1
- id: 111
type: IDF
function: esp_ds_encrypt_params_using_key_type
args: 5
# ID: 134-169 (36) - Reserved for future use
- family: attestation
entries:
@@ -245,6 +245,10 @@ secure_services:
type: IDF
function: esp_sha_set_mode
args: 1
- id: 112
type: IDF
function: esp_ds_encrypt_params_using_key_type
args: 5
# ID: 134-169 (36) - Reserved for future use
- family: attestation
entries:
@@ -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
*/
@@ -287,6 +287,18 @@ esp_err_t __wrap_esp_ds_encrypt_params(esp_ds_data_t *data,
esp_crypto_sha_aes_lock_release();
return err;
}
esp_err_t __wrap_esp_ds_encrypt_params_using_key_type(esp_ds_data_t *data,
const void *iv,
const esp_ds_p_data_t *p_data,
const void *key,
esp_ds_key_type_t key_type)
{
esp_crypto_sha_aes_lock_acquire();
esp_err_t err = esp_tee_service_call(6, SS_ESP_DS_ENCRYPT_PARAMS_USING_KEY_TYPE, data, iv, p_data, key, key_type);
esp_crypto_sha_aes_lock_release();
return err;
}
#endif
/* ---------------------------------------------- MPI ------------------------------------------------- */
@@ -347,6 +347,8 @@ esp_err_t _ss_esp_ds_encrypt_params(esp_ds_data_t *data,
(esp_tee_ptr_in_ree((void *)iv) && esp_tee_ptr_in_ree((void *)key)));
valid_addr &= esp_tee_ptr_in_ree((void *)((char *)data + sizeof(esp_ds_data_t)));
valid_addr &= esp_tee_ptr_in_ree((void *)((char *)p_data + sizeof(esp_ds_p_data_t)));
valid_addr &= esp_tee_ptr_in_ree((void *)((char *)key + ESP_DS_DATA_KEY_SIZE));
if (!valid_addr) {
return ESP_ERR_INVALID_ARG;
@@ -355,6 +357,27 @@ esp_err_t _ss_esp_ds_encrypt_params(esp_ds_data_t *data,
return esp_ds_encrypt_params(data, iv, p_data, key);
}
esp_err_t _ss_esp_ds_encrypt_params_using_key_type(esp_ds_data_t *data,
const void *iv,
const esp_ds_p_data_t *p_data,
const void *key,
esp_ds_key_type_t key_type)
{
bool valid_addr = ((esp_tee_ptr_in_ree((void *)data) && esp_tee_ptr_in_ree((void *)p_data)) &&
(esp_tee_ptr_in_ree((void *)iv) && esp_tee_ptr_in_ree((void *)key)));
valid_addr &= esp_tee_ptr_in_ree((void *)((char *)data + sizeof(esp_ds_data_t)));
valid_addr &= esp_tee_ptr_in_ree((void *)((char *)p_data + sizeof(esp_ds_p_data_t)));
valid_addr &= esp_tee_ptr_in_ree((void *)((char *)key + ESP_DS_DATA_KEY_SIZE));
if (!valid_addr) {
return ESP_ERR_INVALID_ARG;
}
ESP_FAULT_ASSERT(valid_addr);
return esp_ds_encrypt_params_using_key_type(data, iv, p_data, key, key_type);
}
#endif
/* ---------------------------------------------- MPI ------------------------------------------------- */