feat(esp_ds): Support using the AES key used by DS peripheral for encrypting params

This commit is contained in:
harshal.patil
2026-02-21 16:36:46 +05:30
committed by Mahavir Jain
parent 4495f9028c
commit 0db717b9ec
10 changed files with 159 additions and 34 deletions
+42 -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
*/
@@ -40,6 +40,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 +229,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 +247,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);
}
@@ -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);