feat: adds new Kconfig variable for DS peripheral

This commit is contained in:
Ashish Sharma
2026-01-19 14:57:29 +08:00
parent 93349d05b2
commit b1f14d19d0
16 changed files with 486 additions and 338 deletions
+1
View File
@@ -27,6 +27,7 @@ menu "ESP-TLS"
config ESP_TLS_USE_DS_PERIPHERAL
bool "Use Digital Signature (DS) Peripheral with ESP-TLS"
depends on ESP_TLS_USING_MBEDTLS && SOC_DIG_SIGN_SUPPORTED
select MBEDTLS_HARDWARE_RSA_DS_PERIPHERAL
default y
help
Enable use of the Digital Signature Peripheral for ESP-TLS.The DS peripheral
+8 -8
View File
@@ -45,7 +45,7 @@ static esp_err_t esp_set_atecc608a_pki_context(esp_tls_t *tls, const void *pki);
#if defined(CONFIG_ESP_TLS_USE_DS_PERIPHERAL)
#include <pk_wrap.h>
#include "psa/crypto.h"
#include "psa_crypto_driver_esp_ds.h"
#include "psa_crypto_driver_esp_rsa_ds.h"
static esp_err_t esp_mbedtls_init_pk_ctx_for_ds(const void *pki);
#endif /* CONFIG_ESP_TLS_USE_DS_PERIPHERAL */
@@ -118,7 +118,7 @@ typedef struct esp_tls_pki_t {
const unsigned char *privkey_password;
unsigned int privkey_password_len;
#ifdef CONFIG_ESP_TLS_USE_DS_PERIPHERAL
void *esp_ds_data;
void *esp_rsa_ds_data;
#endif
} esp_tls_pki_t;
@@ -601,10 +601,10 @@ static esp_err_t set_pki_context(esp_tls_t *tls, const esp_tls_pki_t *pki)
}
#ifdef CONFIG_ESP_TLS_USE_DS_PERIPHERAL
if (pki->esp_ds_data != NULL) {
if (pki->esp_rsa_ds_data != NULL) {
ret = esp_mbedtls_init_pk_ctx_for_ds(pki);
if (ret != ESP_OK) {
ESP_LOGE(TAG, "Failed to initialize pk context for esp_ds");
ESP_LOGE(TAG, "Failed to initialize pk context for esp_rsa_ds");
return ret;
}
} else
@@ -1063,7 +1063,7 @@ esp_err_t set_client_config(const char *hostname, size_t hostlen, esp_tls_cfg_t
ESP_LOGE(TAG, "Client certificate is also required with the DS parameters");
return ESP_ERR_INVALID_STATE;
}
esp_ds_opaque_set_session_timeout(cfg->timeout_ms);
esp_rsa_ds_opaque_set_session_timeout(cfg->timeout_ms);
/* set private key pointer to NULL since the DS peripheral with its own configuration data is used */
esp_tls_pki_t pki = {
.public_cert = &tls->clientcert,
@@ -1074,7 +1074,7 @@ esp_err_t set_client_config(const char *hostname, size_t hostlen, esp_tls_cfg_t
.privkey_pem_bytes = 0,
.privkey_password = NULL,
.privkey_password_len = 0,
.esp_ds_data = cfg->ds_data,
.esp_rsa_ds_data = cfg->ds_data,
};
esp_err_t esp_ret = set_pki_context(tls, &pki);
@@ -1406,7 +1406,7 @@ static esp_err_t esp_set_atecc608a_pki_context(esp_tls_t *tls, const void *pki)
#ifdef CONFIG_ESP_TLS_USE_DS_PERIPHERAL
static esp_err_t esp_mbedtls_init_pk_ctx_for_ds(const void *pki)
{
esp_ds_data_ctx_t *ds_data = ((const esp_tls_pki_t*)pki)->esp_ds_data;
esp_ds_data_ctx_t *ds_data = ((const esp_tls_pki_t*)pki)->esp_rsa_ds_data;
if (ds_data == NULL) {
ESP_LOGE(TAG, "DS data context is NULL");
return ESP_ERR_INVALID_ARG;
@@ -1430,7 +1430,7 @@ static esp_err_t esp_mbedtls_init_pk_ctx_for_ds(const void *pki)
psa_set_key_bits(&ds_key_attributes, ds_data->rsa_length_bits);
psa_set_key_usage_flags(&ds_key_attributes, PSA_KEY_USAGE_SIGN_HASH);
psa_set_key_algorithm(&ds_key_attributes, alg);
psa_set_key_lifetime(&ds_key_attributes, PSA_KEY_LIFETIME_ESP_DS);
psa_set_key_lifetime(&ds_key_attributes, PSA_KEY_LIFETIME_ESP_RSA_DS);
status = psa_import_key(&ds_key_attributes,
(const uint8_t *)ds_data,
sizeof(esp_ds_data_ctx_t),
@@ -150,9 +150,9 @@ static esp_err_t esp_ds_finish_sign(void *signature, const esp_ds_data_t *data)
}
static esp_err_t esp_ds_sign(const void *message,
const esp_ds_data_t *data,
uint32_t key_id,
void *signature)
const esp_ds_data_t *data,
uint32_t key_id,
void *signature)
{
esp_err_t result = esp_ds_start_sign(message, data, key_id);
if (result != ESP_OK) {
+3 -7
View File
@@ -379,18 +379,14 @@ if(CONFIG_SOC_HMAC_SUPPORTED)
target_link_libraries(tfpsacrypto PRIVATE idf::efuse)
endif()
if(CONFIG_SOC_DIG_SIGN_SUPPORTED)
if(CONFIG_SOC_DIG_SIGN_SUPPORTED AND CONFIG_MBEDTLS_HARDWARE_RSA_DS_PERIPHERAL)
target_compile_definitions(tfpsacrypto PRIVATE ESP_DS_DRIVER_ENABLED)
target_sources(tfpsacrypto PRIVATE
"${COMPONENT_DIR}/port/psa_driver/esp_ds/psa_crypto_driver_esp_ds.c"
"${COMPONENT_DIR}/port/psa_driver/esp_ds/psa_crypto_driver_esp_ds_utilities.c"
"${COMPONENT_DIR}/port/psa_driver/esp_rsa_ds/psa_crypto_driver_esp_rsa_ds.c"
"${COMPONENT_DIR}/port/psa_driver/esp_rsa_ds/psa_crypto_driver_esp_rsa_ds_utilities.c"
)
target_link_libraries(tfpsacrypto PRIVATE idf::efuse)
endif()
# # CONFIG_ESP_TLS_USE_DS_PERIPHERAL can be enabled only for the supported targets.
if(CONFIG_ESP_TLS_USE_DS_PERIPHERAL)
# target_sources(tfpsacrypto PRIVATE "${COMPONENT_DIR}/port/esp_ds/esp_rsa_sign_alt.c")
endif()
if(CONFIG_SOC_HMAC_SUPPORTED)
target_sources(tfpsacrypto PRIVATE "${COMPONENT_DIR}/port/esp_hmac_pbkdf2.c")
+7
View File
@@ -1540,6 +1540,13 @@ menu "mbedTLS"
help
This option enables hardware acceleration for ECDSA sign function, only
when using ATECC608A cryptoauth chip.
config MBEDTLS_HARDWARE_RSA_DS_PERIPHERAL
bool "Enable hardware RSA digital signature peripheral acceleration"
default n
depends on SOC_DIG_SIGN_SUPPORTED
help
Enable hardware accelerated digital signature peripheral for RSA digital signature generation.
endmenu
menu "Entropy and Random Number Generation"
@@ -28,7 +28,7 @@ extern "C" {
* PSA_ERROR_INVALID_ARGUMENT if arguments are invalid
* PSA_SUCCESS on success
*/
psa_status_t esp_ds_pad_v15_encode(psa_algorithm_t alg, unsigned int hashlen,
psa_status_t esp_rsa_ds_pad_v15_encode(psa_algorithm_t alg, unsigned int hashlen,
const unsigned char *hash,
size_t dst_len,
unsigned char *dst);
@@ -45,7 +45,7 @@ psa_status_t esp_ds_pad_v15_encode(psa_algorithm_t alg, unsigned int hashlen,
* PSA_ERROR_INVALID_ARGUMENT if arguments are invalid
* PSA_SUCCESS on success
*/
psa_status_t esp_ds_pad_v15_unpad(unsigned char *input,
psa_status_t esp_rsa_ds_pad_v15_unpad(unsigned char *input,
size_t ilen,
unsigned char *output,
size_t output_max_len,
@@ -66,7 +66,7 @@ psa_status_t esp_ds_pad_v15_unpad(unsigned char *input,
* PSA_ERROR_INVALID_ARGUMENT if arguments are invalid
* PSA_SUCCESS on success
*/
psa_status_t esp_ds_pad_v21_encode(psa_algorithm_t hash_alg,
psa_status_t esp_rsa_ds_pad_v21_encode(psa_algorithm_t hash_alg,
unsigned int hashlen,
const unsigned char *hash,
int saltlen,
@@ -86,7 +86,7 @@ psa_status_t esp_ds_pad_v21_encode(psa_algorithm_t hash_alg,
* PSA_ERROR_INVALID_ARGUMENT if arguments are invalid
* PSA_SUCCESS on success
*/
psa_status_t esp_ds_pad_oaep_unpad(unsigned char *input,
psa_status_t esp_rsa_ds_pad_oaep_unpad(unsigned char *input,
size_t ilen,
unsigned char *output,
size_t output_max_len,
@@ -9,53 +9,54 @@
#include "freertos/FreeRTOS.h"
#include "freertos/semphr.h"
#include "psa_crypto_driver_esp_ds.h"
#include "psa_crypto_driver_esp_ds_contexts.h"
#include "include/psa_crypto_driver_esp_ds_utilities.h"
#include "psa_crypto_driver_esp_rsa_ds.h"
#include "psa_crypto_driver_esp_rsa_ds_contexts.h"
#include "include/psa_crypto_driver_esp_rsa_ds_utilities.h"
#include "esp_log.h"
#include "esp_efuse.h"
#include "soc/soc_caps.h"
static const char *TAG = "PSA_DS_DRIVER";
#define ESP_RSA_DS_TIMEOUT_BUFFER_MS 1000
static const char *TAG = "PSA_RSA_DS";
static SemaphoreHandle_t s_ds_lock = NULL;
static int s_timeout_ms = 0;
void esp_ds_release_ds_lock(void);
void esp_rsa_ds_release_ds_lock(void);
static int esp_ds_pad(esp_ds_padding_t padding, psa_algorithm_t hash_alg, unsigned int hashlen,
static int esp_rsa_ds_pad(esp_rsa_ds_padding_t padding, psa_algorithm_t hash_alg, unsigned int hashlen,
const unsigned char *hash,
int saltlen,
unsigned char *sig, size_t dst_len)
{
if (padding == ESP_DS_PADDING_PKCS_V15) {
if (padding == ESP_RSA_DS_PADDING_PKCS_V15) {
(void)saltlen;
return esp_ds_pad_v15_encode(hash_alg, hashlen, hash, dst_len, sig);
return esp_rsa_ds_pad_v15_encode(hash_alg, hashlen, hash, dst_len, sig);
}
#if CONFIG_MBEDTLS_SSL_PROTO_TLS1_3
else if (padding == ESP_DS_PADDING_PSS) {
return esp_ds_pad_v21_encode(hash_alg, hashlen, hash, saltlen, sig, dst_len);
else if (padding == ESP_RSA_DS_PADDING_PSS) {
return esp_rsa_ds_pad_v21_encode(hash_alg, hashlen, hash, saltlen, sig, dst_len);
}
#endif /* CONFIG_MBEDTLS_SSL_PROTO_TLS1_3 */
else {
ESP_LOGE(TAG, "Unsupported padding scheme");
return PSA_ERROR_NOT_SUPPORTED;
}
}
/* Lock for the DS session, other TLS connections trying to use the DS peripheral will be blocked
* till this DS session is completed (i.e. TLS handshake for this connection is completed) */
static void __attribute__((constructor)) esp_ds_conn_lock(void)
static void __attribute__((constructor)) esp_rsa_ds_conn_lock(void)
{
if ((s_ds_lock = xSemaphoreCreateMutex()) == NULL) {
ESP_EARLY_LOGE(TAG, "mutex for the DS session lock could not be created");
ESP_EARLY_LOGE(TAG, "Failed to create DS lock");
}
}
void esp_ds_release_ds_lock(void)
void esp_rsa_ds_release_ds_lock(void)
{
if (s_ds_lock == NULL) {
ESP_LOGE(TAG, "s_ds_lock is NULL, cannot release lock");
return;
}
if (xSemaphoreGetMutexHolder(s_ds_lock) == xTaskGetCurrentTaskHandle()) {
@@ -64,42 +65,36 @@ void esp_ds_release_ds_lock(void)
}
}
static int esp_ds_validate_opaque_key(const esp_ds_data_ctx_t *opaque_key)
static int esp_rsa_ds_validate_opaque_key(const esp_ds_data_ctx_t *opaque_key)
{
if (opaque_key == NULL) {
ESP_LOGE(TAG, "Opaque key is NULL");
return PSA_ERROR_INVALID_ARGUMENT;
}
if (opaque_key->esp_ds_data == NULL) {
ESP_LOGE(TAG, "esp_ds_data pointer in opaque key is NULL");
if (opaque_key->esp_rsa_ds_data == NULL) {
return PSA_ERROR_INVALID_ARGUMENT;
}
if (EFUSE_BLK_KEY0 + opaque_key->efuse_key_id >= EFUSE_BLK_KEY_MAX) {
ESP_LOGE(TAG, "Invalid efuse_key_id in opaque key");
return PSA_ERROR_INVALID_ARGUMENT;
}
if (opaque_key->rsa_length_bits % 32 != 0) {
ESP_LOGE(TAG, "RSA key length must be a multiple of 32 bits");
return PSA_ERROR_INVALID_ARGUMENT;
}
if (opaque_key->rsa_length_bits < 1024 || opaque_key->rsa_length_bits > 4096) {
ESP_LOGE(TAG, "RSA key length must be between 1024 and 4096 bits");
if (opaque_key->rsa_length_bits < 1024 || opaque_key->rsa_length_bits > SOC_DS_SIGNATURE_MAX_BIT_LEN) {
return PSA_ERROR_INVALID_ARGUMENT;
}
esp_efuse_purpose_t purpose = esp_efuse_get_key_purpose(EFUSE_BLK_KEY0 + opaque_key->efuse_key_id);
if (purpose != ESP_EFUSE_KEY_PURPOSE_HMAC_DOWN_DIGITAL_SIGNATURE) {
ESP_LOGE(TAG, "Efuse key id purpose is not HMAC_DOWN_DIGITAL_SIGNATURE");
return PSA_ERROR_NOT_PERMITTED;
}
return PSA_SUCCESS;
}
psa_status_t esp_ds_opaque_sign_hash_start(
esp_ds_opaque_sign_hash_operation_t *operation,
psa_status_t esp_rsa_ds_opaque_sign_hash_start(
esp_rsa_ds_opaque_sign_hash_operation_t *operation,
const psa_key_attributes_t *attributes,
const uint8_t *key_buffer,
size_t key_buffer_size,
@@ -107,7 +102,7 @@ psa_status_t esp_ds_opaque_sign_hash_start(
const uint8_t *hash,
size_t hash_length)
{
if (!attributes || !key_buffer || !hash) {
if (!attributes || !key_buffer || !hash || !operation) {
return PSA_ERROR_INVALID_ARGUMENT;
}
@@ -122,20 +117,21 @@ psa_status_t esp_ds_opaque_sign_hash_start(
operation->alg = alg;
const esp_ds_data_ctx_t *opaque_key = (const esp_ds_data_ctx_t *)key_buffer;
operation->esp_ds_opaque_key = opaque_key;
operation->esp_rsa_ds_opaque_key = opaque_key;
if (esp_ds_validate_opaque_key(opaque_key) != PSA_SUCCESS) {
if (esp_rsa_ds_validate_opaque_key(opaque_key) != PSA_SUCCESS) {
return PSA_ERROR_INVALID_ARGUMENT;
}
if ((xSemaphoreTake(s_ds_lock, s_timeout_ms / portTICK_PERIOD_MS) != pdTRUE)) {
ESP_LOGE(TAG, "ds_lock could not be obtained in specified time");
return PSA_ERROR_GENERIC_ERROR;
}
int padding = ESP_DS_PADDING_PKCS_V15;
esp_rsa_ds_padding_t padding = ESP_RSA_DS_PADDING_INVALID;
if (PSA_ALG_IS_RSA_PSS(operation->alg)) {
padding = ESP_DS_PADDING_PSS;
padding = ESP_RSA_DS_PADDING_PSS;
} else if (PSA_ALG_IS_RSA_PKCS1V15_SIGN(operation->alg)) {
padding = ESP_RSA_DS_PADDING_PKCS_V15;
}
psa_algorithm_t hash_alg = PSA_ALG_SIGN_GET_HASH(operation->alg);
@@ -143,60 +139,61 @@ psa_status_t esp_ds_opaque_sign_hash_start(
const size_t words_len = (opaque_key->rsa_length_bits / 32);
const size_t rsa_len_bytes = words_len * 4;
operation->sig_buffer_size = rsa_len_bytes;
operation->sig_buffer = NULL;
unsigned char *em = heap_caps_malloc_prefer(rsa_len_bytes, 1, MALLOC_CAP_32BIT | MALLOC_CAP_INTERNAL, MALLOC_CAP_DEFAULT | MALLOC_CAP_INTERNAL);
if (em == NULL) {
ESP_LOGE(TAG, "Could not allocate memory for internal DS operations");
esp_ds_release_ds_lock();
esp_rsa_ds_release_ds_lock();
return PSA_ERROR_INSUFFICIENT_MEMORY;
}
psa_status_t status = esp_ds_pad(
psa_status_t status = esp_rsa_ds_pad(
padding, hash_alg, hash_length, hash, -1, em, rsa_len_bytes);
if (status != PSA_SUCCESS) {
ESP_LOGE(TAG, "Error in esp_ds_pad, returned %d ", status);
heap_caps_free(em);
esp_ds_release_ds_lock();
return status;
goto error;
}
operation->sig_buffer = heap_caps_malloc_prefer(rsa_len_bytes, 2, MALLOC_CAP_32BIT | MALLOC_CAP_INTERNAL, MALLOC_CAP_DEFAULT | MALLOC_CAP_INTERNAL);
if (operation->sig_buffer == NULL) {
ESP_LOGE(TAG, "Could not allocate memory for internal DS operations");
heap_caps_free(em);
esp_ds_release_ds_lock();
return PSA_ERROR_INSUFFICIENT_MEMORY;
status = PSA_ERROR_INSUFFICIENT_MEMORY;
goto error;
}
{
uint32_t *sig_words = (uint32_t *)operation->sig_buffer;
const uint32_t *em_words = (const uint32_t *)em;
for (unsigned int i = 0; i < words_len; i++) {
sig_words[i] = SWAP_INT32(em_words[words_len - (i + 1)]);
}
uint32_t *sig_words = (uint32_t *)operation->sig_buffer;
const uint32_t *em_words = (const uint32_t *)em;
for (unsigned int i = 0; i < words_len; i++) {
sig_words[i] = SWAP_INT32(em_words[words_len - (i + 1)]);
}
heap_caps_free(em);
memcpy(&operation->esp_ds_data, opaque_key->esp_ds_data, sizeof(esp_ds_data_t));
operation->esp_ds_data.rsa_length = (opaque_key->rsa_length_bits / 32) - 1;
memcpy(&operation->esp_rsa_ds_data, opaque_key->esp_rsa_ds_data, sizeof(esp_ds_data_t));
operation->esp_rsa_ds_data.rsa_length = (opaque_key->rsa_length_bits / 32) - 1;
esp_err_t err = esp_ds_start_sign((const void *)operation->sig_buffer,
&operation->esp_ds_data,
&operation->esp_rsa_ds_data,
(hmac_key_id_t) opaque_key->efuse_key_id,
&operation->esp_ds_ctx);
&operation->esp_rsa_ds_ctx);
if (err != ESP_OK) {
ESP_LOGE(TAG, "Error in esp_ds_start_sign, returned %X ", err);
heap_caps_free(operation->sig_buffer);
esp_ds_release_ds_lock();
return PSA_ERROR_GENERIC_ERROR;
status = PSA_ERROR_GENERIC_ERROR;
goto error;
}
return PSA_SUCCESS;
error:
if (em) {
heap_caps_free(em);
em = NULL;
}
if (status != PSA_SUCCESS) {
if (operation->sig_buffer) {
heap_caps_free(operation->sig_buffer);
operation->sig_buffer = NULL;
}
esp_rsa_ds_release_ds_lock();
}
return status;
}
psa_status_t esp_ds_opaque_sign_hash_complete(
esp_ds_opaque_sign_hash_operation_t *operation,
psa_status_t esp_rsa_ds_opaque_sign_hash_complete(
esp_rsa_ds_opaque_sign_hash_operation_t *operation,
uint8_t *signature, size_t signature_size,
size_t *signature_length)
{
@@ -204,17 +201,20 @@ psa_status_t esp_ds_opaque_sign_hash_complete(
return PSA_ERROR_INVALID_ARGUMENT;
}
int expected_signature_size = operation->esp_ds_opaque_key->rsa_length_bits / 8;
if ((operation->esp_rsa_ds_ctx == NULL) || (operation->sig_buffer == NULL)) {
return PSA_ERROR_BAD_STATE;
}
int expected_signature_size = operation->esp_rsa_ds_opaque_key->rsa_length_bits / 8;
if (signature_size < expected_signature_size) {
return PSA_ERROR_BUFFER_TOO_SMALL;
}
esp_err_t err = esp_ds_finish_sign((void *)operation->sig_buffer, operation->esp_ds_ctx);
esp_err_t err = esp_ds_finish_sign((void *)operation->sig_buffer, operation->esp_rsa_ds_ctx);
if (err != ESP_OK) {
ESP_LOGE(TAG, "Error in esp_ds_finish_sign, returned %X ", err);
memset(operation->sig_buffer, 0, operation->sig_buffer_size);
heap_caps_free(operation->sig_buffer);
esp_ds_release_ds_lock();
esp_rsa_ds_release_ds_lock();
return PSA_ERROR_GENERIC_ERROR;
}
@@ -228,12 +228,12 @@ psa_status_t esp_ds_opaque_sign_hash_complete(
*signature_length = expected_signature_size;
memset(operation->sig_buffer, 0, operation->sig_buffer_size);
heap_caps_free(operation->sig_buffer);
esp_ds_release_ds_lock();
esp_rsa_ds_release_ds_lock();
return PSA_SUCCESS;
}
psa_status_t esp_ds_opaque_sign_hash_abort(
esp_ds_opaque_sign_hash_operation_t *operation)
psa_status_t esp_rsa_ds_opaque_sign_hash_abort(
esp_rsa_ds_opaque_sign_hash_operation_t *operation)
{
if (!operation) {
return PSA_ERROR_INVALID_ARGUMENT;
@@ -241,20 +241,21 @@ psa_status_t esp_ds_opaque_sign_hash_abort(
// Free allocated memory if exists
if (operation->sig_buffer) {
memset(operation->sig_buffer, 0, operation->sig_buffer_size);
heap_caps_free(operation->sig_buffer);
operation->sig_buffer = NULL;
}
// Release the DS lock if held
esp_ds_release_ds_lock();
esp_rsa_ds_release_ds_lock();
// Clear the operation structure
memset(operation, 0, sizeof(esp_ds_opaque_sign_hash_operation_t));
memset(operation, 0, sizeof(esp_rsa_ds_opaque_sign_hash_operation_t));
return PSA_SUCCESS;
}
psa_status_t esp_ds_opaque_signature_sign_hash(
psa_status_t esp_rsa_ds_opaque_signature_sign_hash(
const psa_key_attributes_t *attributes,
const uint8_t *key_buffer,
size_t key_buffer_size,
@@ -266,8 +267,8 @@ psa_status_t esp_ds_opaque_signature_sign_hash(
size_t *signature_length
)
{
esp_ds_opaque_sign_hash_operation_t operation = {0};
psa_status_t status = esp_ds_opaque_sign_hash_start(
esp_rsa_ds_opaque_sign_hash_operation_t operation = {0};
psa_status_t status = esp_rsa_ds_opaque_sign_hash_start(
&operation,
attributes,
key_buffer,
@@ -277,25 +278,22 @@ psa_status_t esp_ds_opaque_signature_sign_hash(
hash_length
);
if (status != PSA_SUCCESS) {
ESP_LOGE(TAG, "Error in esp_ds_opaque_sign_hash_start, returned %d ", status);
esp_ds_opaque_sign_hash_abort(&operation);
esp_rsa_ds_opaque_sign_hash_abort(&operation);
return status;
}
status = esp_ds_opaque_sign_hash_complete(
status = esp_rsa_ds_opaque_sign_hash_complete(
&operation,
signature,
signature_size,
signature_length
);
if (status != PSA_SUCCESS) {
esp_ds_opaque_sign_hash_abort(&operation);
return status;
}
return PSA_SUCCESS;
esp_rsa_ds_opaque_sign_hash_abort(&operation);
return status;
}
psa_status_t esp_ds_opaque_import_key(
psa_status_t esp_rsa_ds_opaque_import_key(
const psa_key_attributes_t *attributes,
const uint8_t *data,
size_t data_length,
@@ -313,7 +311,7 @@ psa_status_t esp_ds_opaque_import_key(
}
const esp_ds_data_ctx_t *opaque_key = (const esp_ds_data_ctx_t *)data;
int ret = esp_ds_validate_opaque_key(opaque_key);
int ret = esp_rsa_ds_validate_opaque_key(opaque_key);
if (ret != PSA_SUCCESS) {
return ret;
}
@@ -323,7 +321,7 @@ psa_status_t esp_ds_opaque_import_key(
return PSA_SUCCESS;
}
size_t esp_ds_opaque_size_function(
size_t esp_rsa_ds_opaque_size_function(
psa_key_type_t key_type,
size_t key_bits)
{
@@ -334,14 +332,21 @@ size_t esp_ds_opaque_size_function(
return sizeof(esp_ds_data_ctx_t);
}
void esp_ds_opaque_set_session_timeout(int timeout_ms)
void esp_rsa_ds_opaque_set_session_timeout(int timeout_ms)
{
/* add additional offset of ESP_RSA_DS_TIMEOUT_BUFFER_MS ms to have enough time for deleting the TLS connection
* and free the previous ds context after exceeding timeout value
* (this offset also helps when timeout is set to 0)
*/
if (timeout_ms < 0) {
return;
}
if (timeout_ms > s_timeout_ms) {
s_timeout_ms = timeout_ms;
s_timeout_ms = timeout_ms + ESP_RSA_DS_TIMEOUT_BUFFER_MS;
}
}
psa_status_t esp_ds_opaque_asymmetric_decrypt(
psa_status_t esp_rsa_ds_opaque_asymmetric_decrypt(
const psa_key_attributes_t *attributes, const uint8_t *key,
size_t key_length, psa_algorithm_t alg, const uint8_t *input,
size_t input_length, const uint8_t *salt, size_t salt_length,
@@ -360,7 +365,7 @@ psa_status_t esp_ds_opaque_asymmetric_decrypt(
const esp_ds_data_ctx_t *opaque_key = (const esp_ds_data_ctx_t *)key;
if (esp_ds_validate_opaque_key(opaque_key) != PSA_SUCCESS) {
if (esp_rsa_ds_validate_opaque_key(opaque_key) != PSA_SUCCESS) {
return PSA_ERROR_INVALID_ARGUMENT;
}
@@ -369,18 +374,14 @@ psa_status_t esp_ds_opaque_asymmetric_decrypt(
return PSA_ERROR_INVALID_ARGUMENT;
}
esp_ds_padding_t padding = ESP_DS_PADDING_PKCS_V15;
esp_rsa_ds_padding_t padding = ESP_RSA_DS_PADDING_INVALID;
if (PSA_ALG_IS_RSA_OAEP(alg)) {
padding = ESP_DS_PADDING_OAEP;
padding = ESP_RSA_DS_PADDING_OAEP;
} else if (alg == PSA_ALG_RSA_PKCS1V15_CRYPT) {
padding = ESP_DS_PADDING_PKCS_V15;
} else {
ESP_LOGE(TAG, "Unsupported algorithm for decryption");
return PSA_ERROR_NOT_SUPPORTED;
padding = ESP_RSA_DS_PADDING_PKCS_V15;
}
if (xSemaphoreTake(s_ds_lock, s_timeout_ms / portTICK_PERIOD_MS) != pdTRUE) {
ESP_LOGE(TAG, "ds_lock could not be obtained in specified time");
return PSA_ERROR_GENERIC_ERROR;
}
@@ -388,8 +389,7 @@ psa_status_t esp_ds_opaque_asymmetric_decrypt(
size_t data_len = ilen / 4;
uint32_t *em_words = heap_caps_malloc_prefer(sizeof(uint32_t) * data_len, 1, MALLOC_CAP_32BIT | MALLOC_CAP_INTERNAL, MALLOC_CAP_DEFAULT | MALLOC_CAP_INTERNAL);
if (em_words == NULL) {
ESP_LOGE(TAG, "Could not allocate memory for internal DS operations");
esp_ds_release_ds_lock();
esp_rsa_ds_release_ds_lock();
return PSA_ERROR_INSUFFICIENT_MEMORY;
}
@@ -397,36 +397,33 @@ psa_status_t esp_ds_opaque_asymmetric_decrypt(
em_words[i] = SWAP_INT32(((uint32_t *)input)[(data_len) - (i + 1)]);
}
esp_ds_opaque_sign_hash_operation_t operation = {0};
esp_rsa_ds_opaque_sign_hash_operation_t operation = {0};
operation.alg = alg;
operation.esp_ds_opaque_key = opaque_key;
operation.esp_rsa_ds_opaque_key = opaque_key;
operation.sig_buffer = em_words;
esp_err_t err = esp_ds_start_sign((const void *)em_words,
opaque_key->esp_ds_data,
opaque_key->esp_rsa_ds_data,
(hmac_key_id_t) opaque_key->efuse_key_id,
&operation.esp_ds_ctx);
&operation.esp_rsa_ds_ctx);
if (err != ESP_OK) {
ESP_LOGE(TAG, "Error in esp_ds_start_sign for decryption, returned %X ", err);
heap_caps_free(em_words);
esp_ds_release_ds_lock();
esp_rsa_ds_release_ds_lock();
return PSA_ERROR_GENERIC_ERROR;
}
err = esp_ds_finish_sign((void *)em_words, operation.esp_ds_ctx);
err = esp_ds_finish_sign((void *)em_words, operation.esp_rsa_ds_ctx);
if (err != ESP_OK) {
ESP_LOGE(TAG, "Error in esp_ds_finish_sign for decryption, returned %X ", err);
heap_caps_free(em_words);
esp_ds_release_ds_lock();
esp_rsa_ds_release_ds_lock();
return PSA_ERROR_GENERIC_ERROR;
}
esp_ds_release_ds_lock();
esp_rsa_ds_release_ds_lock();
// Remove padding
uint32_t *out_tmp = heap_caps_malloc_prefer(sizeof(uint32_t) * data_len, 1, MALLOC_CAP_8BIT | MALLOC_CAP_INTERNAL, MALLOC_CAP_DEFAULT | MALLOC_CAP_INTERNAL);
if (out_tmp == NULL) {
ESP_LOGE(TAG, "Could not allocate memory for internal DS operations");
heap_caps_free(em_words);
return PSA_ERROR_INSUFFICIENT_MEMORY;
}
@@ -436,39 +433,38 @@ psa_status_t esp_ds_opaque_asymmetric_decrypt(
}
size_t unpadded_len = 0;
psa_status_t ret = 0;
if (padding == ESP_DS_PADDING_PKCS_V15) {
ret = esp_ds_pad_v15_unpad((unsigned char *)out_tmp, ilen, (unsigned char *)out_tmp, ilen, &unpadded_len);
psa_status_t ret = PSA_ERROR_NOT_SUPPORTED;
if (padding == ESP_RSA_DS_PADDING_PKCS_V15) {
ret = esp_rsa_ds_pad_v15_unpad((unsigned char *)out_tmp, ilen, (unsigned char *)out_tmp, ilen, &unpadded_len);
}
#if CONFIG_MBEDTLS_SSL_PROTO_TLS1_3
else if (padding == ESP_DS_PADDING_OAEP) {
ret = esp_ds_pad_oaep_unpad((unsigned char *)out_tmp, ilen, (unsigned char *)out_tmp, ilen, &unpadded_len, PSA_ALG_RSA_OAEP_GET_HASH(alg));
else if (padding == ESP_RSA_DS_PADDING_OAEP) {
ret = esp_rsa_ds_pad_oaep_unpad((unsigned char *)out_tmp, ilen, (unsigned char *)out_tmp, ilen, &unpadded_len, PSA_ALG_RSA_OAEP_GET_HASH(alg));
}
#endif /* CONFIG_MBEDTLS_SSL_PROTO_TLS1_3 */
else {
ESP_LOGE(TAG, "Unsupported padding scheme for decryption");
heap_caps_free(em_words);
heap_caps_free(out_tmp);
return PSA_ERROR_NOT_SUPPORTED;
ret = PSA_ERROR_NOT_SUPPORTED;
goto exit;
}
if (ret != PSA_SUCCESS) {
ESP_LOGE(TAG, "Error in unpadding, returned %d", ret);
heap_caps_free(em_words);
heap_caps_free(out_tmp);
return PSA_ERROR_INVALID_PADDING;
ret = PSA_ERROR_INVALID_PADDING;
goto exit;
}
if (output_size < unpadded_len) {
ESP_LOGE(TAG, "Output buffer too small for decrypted data, required size: %zu", unpadded_len);
heap_caps_free(em_words);
heap_caps_free(out_tmp);
return PSA_ERROR_BUFFER_TOO_SMALL;
ret = PSA_ERROR_BUFFER_TOO_SMALL;
goto exit;
}
memcpy(output, out_tmp, unpadded_len);
*output_length = unpadded_len;
ret = PSA_SUCCESS;
exit:
memset(em_words, 0, sizeof(uint32_t) * data_len);
memset(out_tmp, 0, sizeof(uint32_t) * data_len);
heap_caps_free(em_words);
heap_caps_free(out_tmp);
return PSA_SUCCESS;
return ret;
}
@@ -5,7 +5,7 @@
*/
#include <string.h>
#include "include/psa_crypto_driver_esp_ds_utilities.h"
#include "include/psa_crypto_driver_esp_rsa_ds_utilities.h"
#include "mbedtls/asn1.h"
#include "mbedtls/psa_util.h"
#include "esp_log.h"
@@ -41,7 +41,7 @@ static const oid_md_mapping_t oid_md_table[] = {
{ PSA_ALG_NONE, NULL, 0 }
};
static int esp_ds_get_oid_by_psa_alg(psa_algorithm_t md_alg, const char **oid, size_t *olen)
static int esp_rsa_ds_get_oid_by_psa_alg(psa_algorithm_t md_alg, const char **oid, size_t *olen)
{
for (size_t i = 0; oid_md_table[i].md_alg != PSA_ALG_NONE; i++) {
if (oid_md_table[i].md_alg == md_alg) {
@@ -53,7 +53,7 @@ static int esp_ds_get_oid_by_psa_alg(psa_algorithm_t md_alg, const char **oid, s
return PSA_ERROR_NOT_SUPPORTED;
}
psa_status_t esp_ds_pad_v15_encode(psa_algorithm_t alg, unsigned int hashlen,
psa_status_t esp_rsa_ds_pad_v15_encode(psa_algorithm_t alg, unsigned int hashlen,
const unsigned char *hash,
size_t dst_len,
unsigned char *dst)
@@ -65,7 +65,7 @@ psa_status_t esp_ds_pad_v15_encode(psa_algorithm_t alg, unsigned int hashlen,
/* Are we signing hashed or raw data? */
if (alg != PSA_ALG_NONE) {
if (esp_ds_get_oid_by_psa_alg(alg, &oid, &oid_size) != PSA_SUCCESS) {
if (esp_rsa_ds_get_oid_by_psa_alg(alg, &oid, &oid_size) != PSA_SUCCESS) {
return PSA_ERROR_INVALID_ARGUMENT;
}
@@ -161,7 +161,7 @@ psa_status_t esp_ds_pad_v15_encode(psa_algorithm_t alg, unsigned int hashlen,
return PSA_SUCCESS;
}
psa_status_t esp_ds_pad_v15_unpad(unsigned char *input,
psa_status_t esp_rsa_ds_pad_v15_unpad(unsigned char *input,
size_t ilen,
unsigned char *output,
size_t output_max_len,
@@ -227,7 +227,7 @@ psa_status_t esp_ds_pad_v15_unpad(unsigned char *input,
}
#if CONFIG_MBEDTLS_SSL_PROTO_TLS1_3
static psa_status_t esp_ds_mgf_mask(unsigned char *dst, size_t dlen, unsigned char *src,
static psa_status_t esp_rsa_ds_mgf_mask(unsigned char *dst, size_t dlen, unsigned char *src,
size_t slen, psa_algorithm_t hash_alg)
{
unsigned char counter[4];
@@ -286,7 +286,7 @@ exit:
return status;
}
static psa_status_t esp_ds_hash_mprime(const unsigned char *hash, size_t hlen,
static psa_status_t esp_rsa_ds_hash_mprime(const unsigned char *hash, size_t hlen,
const unsigned char *salt, size_t slen,
unsigned char *out, psa_algorithm_t hash_alg)
{
@@ -319,7 +319,7 @@ exit:
return status;
}
psa_status_t esp_ds_pad_v21_encode(psa_algorithm_t hash_alg,
psa_status_t esp_rsa_ds_pad_v21_encode(psa_algorithm_t hash_alg,
unsigned int hashlen,
const unsigned char *hash,
int saltlen,
@@ -386,7 +386,7 @@ psa_status_t esp_ds_pad_v21_encode(psa_algorithm_t hash_alg,
p += slen;
/* Generate H = Hash( M' ) */
ret = esp_ds_hash_mprime(hash, hashlen, salt, slen, p, hash_alg);
ret = esp_rsa_ds_hash_mprime(hash, hashlen, salt, slen, p, hash_alg);
if (ret != 0) {
return ret;
}
@@ -397,7 +397,7 @@ psa_status_t esp_ds_pad_v21_encode(psa_algorithm_t hash_alg,
}
/* maskedDB: Apply dbMask to DB */
ret = esp_ds_mgf_mask(sig + offset, olen - hlen - 1 - offset, p, hlen, hash_alg);
ret = esp_rsa_ds_mgf_mask(sig + offset, olen - hlen - 1 - offset, p, hlen, hash_alg);
if (ret != 0) {
return ret;
}
@@ -410,7 +410,7 @@ psa_status_t esp_ds_pad_v21_encode(psa_algorithm_t hash_alg,
return ret;
}
psa_status_t esp_ds_pad_oaep_unpad(unsigned char *input,
psa_status_t esp_rsa_ds_pad_oaep_unpad(unsigned char *input,
size_t ilen,
unsigned char *output,
size_t output_max_len,
@@ -425,9 +425,9 @@ psa_status_t esp_ds_pad_oaep_unpad(unsigned char *input,
bad |= (ilen < 2 * hlen + 2);
/* Apply MGF masks */
bad |= esp_ds_mgf_mask(input + 1, hlen, input + hlen + 1, ilen - hlen - 1, hash_alg) != PSA_SUCCESS;
bad |= esp_rsa_ds_mgf_mask(input + 1, hlen, input + hlen + 1, ilen - hlen - 1, hash_alg) != PSA_SUCCESS;
bad |= esp_ds_mgf_mask(input + hlen + 1, ilen - hlen - 1, input + 1, hlen, hash_alg) != PSA_SUCCESS;
bad |= esp_rsa_ds_mgf_mask(input + hlen + 1, ilen - hlen - 1, input + 1, hlen, hash_alg) != PSA_SUCCESS;
/* Check first byte (should be 0x00) */
bad |= input[0];
@@ -1,82 +0,0 @@
/*
* SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include "psa/crypto.h"
#include "psa_crypto_driver_esp_ds_contexts.h"
#ifdef __cplusplus
extern "C" {
#endif
#if defined(ESP_DS_DRIVER_ENABLED)
#ifndef PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT
#define PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT
#endif /* PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT */
#endif /* ESP_DS_DRIVER_ENABLED */
#define PSA_CRYPTO_ESP_DS_DRIVER_LOCATION ((psa_key_location_t) 0x800002)
#define PSA_KEY_LIFETIME_ESP_DS \
PSA_KEY_LIFETIME_FROM_PERSISTENCE_AND_LOCATION( \
PSA_KEY_PERSISTENCE_VOLATILE, \
PSA_CRYPTO_ESP_DS_DRIVER_LOCATION)
#ifdef SOC_DIG_SIGN_SUPPORTED
psa_status_t esp_ds_opaque_sign_hash_start(
esp_ds_opaque_sign_hash_operation_t *operation,
const psa_key_attributes_t *attributes,
const uint8_t *key_buffer,
size_t key_buffer_size,
psa_algorithm_t alg,
const uint8_t *hash,
size_t hash_length);
psa_status_t esp_ds_opaque_sign_hash_complete(
esp_ds_opaque_sign_hash_operation_t *operation,
uint8_t *signature, size_t signature_size,
size_t *signature_length);
psa_status_t esp_ds_opaque_sign_hash_abort(
esp_ds_opaque_sign_hash_operation_t *operation);
psa_status_t esp_ds_opaque_signature_sign_hash(
const psa_key_attributes_t *attributes,
const uint8_t *key_buffer,
size_t key_buffer_size,
psa_algorithm_t alg,
const uint8_t *hash,
size_t hash_length,
uint8_t *signature,
size_t signature_size,
size_t *signature_length
);
psa_status_t esp_ds_opaque_import_key(
const psa_key_attributes_t *attributes,
const uint8_t *data,
size_t data_length,
uint8_t *key_buffer,
size_t key_buffer_size,
size_t *key_buffer_length,
size_t *bits);
size_t esp_ds_opaque_size_function(
psa_key_type_t key_type,
size_t key_bits);
void esp_ds_opaque_set_session_timeout(int timeout_ms);
psa_status_t esp_ds_opaque_asymmetric_decrypt(
const psa_key_attributes_t *attributes, const uint8_t *key,
size_t key_length, psa_algorithm_t alg, const uint8_t *input,
size_t input_length, const uint8_t *salt, size_t salt_length,
uint8_t *output, size_t output_size, size_t *output_length);
#endif /* SOC_DIG_SIGN_SUPPORTED */
#ifdef __cplusplus
}
#endif
@@ -1,42 +0,0 @@
/*
* SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include "psa/crypto.h"
#ifdef SOC_DIG_SIGN_SUPPORTED
#include "esp_ds.h"
#endif /* SOC_DIG_SIGN_SUPPORTED */
#ifdef __cplusplus
extern "C" {
#endif
typedef enum {
ESP_DS_PADDING_PKCS_V15,
ESP_DS_PADDING_PSS,
ESP_DS_PADDING_OAEP,
} esp_ds_padding_t;
#ifdef SOC_DIG_SIGN_SUPPORTED
typedef struct {
esp_ds_data_t *esp_ds_data;
uint8_t efuse_key_id; /* efuse block id in which DS_KEY is stored e.g. 0,1*/
uint16_t rsa_length_bits; /* length of RSA private key in bits e.g. 2048 */
} esp_ds_data_ctx_t;
typedef struct {
const esp_ds_data_ctx_t *esp_ds_opaque_key; /*!< Pointer to the esp ds opaque key */
psa_algorithm_t alg; /*!< Algorithm used in the sign operation */
uint32_t *sig_buffer; /*!< Buffer to hold the signature */
size_t sig_buffer_size; /*!< Size of the signature buffer */
esp_ds_context_t *esp_ds_ctx; /*!< Pointer to the esp ds context */
esp_ds_data_t esp_ds_data;
} esp_ds_opaque_sign_hash_operation_t;
#endif /* SOC_DIG_SIGN_SUPPORTED */
#ifdef __cplusplus
}
#endif
@@ -0,0 +1,180 @@
/*
* SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include "sdkconfig.h"
#include "psa/crypto.h"
#if defined(SOC_DIG_SIGN_SUPPORTED) && defined(CONFIG_MBEDTLS_HARDWARE_RSA_DS_PERIPHERAL)
#include "psa_crypto_driver_esp_rsa_ds_contexts.h"
#ifdef __cplusplus
extern "C" {
#endif
#if defined(ESP_RSA_DS_DRIVER_ENABLED)
#ifndef PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT
#define PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT
#endif /* PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT */
#endif /* ESP_RSA_DS_DRIVER_ENABLED */
#define PSA_CRYPTO_ESP_RSA_DS_DRIVER_LOCATION ((psa_key_location_t) 0x800002)
#define PSA_KEY_LIFETIME_ESP_RSA_DS \
PSA_KEY_LIFETIME_FROM_PERSISTENCE_AND_LOCATION( \
PSA_KEY_PERSISTENCE_VOLATILE, \
PSA_CRYPTO_ESP_RSA_DS_DRIVER_LOCATION)
/**
* @brief Start the RSA DS opaque sign hash operation
*
* @param operation Operation context
* @param attributes Key attributes
* @param key_buffer Key buffer
* @param key_buffer_size Key buffer size
* @param alg Algorithm used in the sign operation
* @param hash Hash to sign
* @param hash_length Length of the hash
* @return Status of the start operation
* PSA_SUCCESS if the operation was started successfully
* Error code if the operation was not started successfully, check psa_status_t documentation for more details.
*/
psa_status_t esp_rsa_ds_opaque_sign_hash_start(
esp_rsa_ds_opaque_sign_hash_operation_t *operation,
const psa_key_attributes_t *attributes,
const uint8_t *key_buffer,
size_t key_buffer_size,
psa_algorithm_t alg,
const uint8_t *hash,
size_t hash_length);
/**
* @brief Complete the RSA DS opaque sign hash operation.
* The signature buffer should be pre-allocated with the size of the RSA key.
* The operation context should be initialised with the start operation.
* @param operation Operation context
* @param signature Signature buffer
* @param signature_size Size of the signature buffer
* @param signature_length Actual length of the signature
* @return Status of the complete operation
* PSA_SUCCESS if the operation was completed successfully
* Error code if the operation was not completed successfully, check psa_status_t documentation for more details.
*/
psa_status_t esp_rsa_ds_opaque_sign_hash_complete(
esp_rsa_ds_opaque_sign_hash_operation_t *operation,
uint8_t *signature, size_t signature_size,
size_t *signature_length);
/**
* @brief Abort the RSA DS opaque sign hash operation.
* The operation context should be initialised with the start operation.
* @param operation Operation context
* @return Status of the abort operation
* PSA_SUCCESS if the operation was aborted successfully
* Error code if the operation was not aborted successfully, check psa_status_t documentation for more details.
*/
psa_status_t esp_rsa_ds_opaque_sign_hash_abort(
esp_rsa_ds_opaque_sign_hash_operation_t *operation);
/**
* @brief Sign the hash using the RSA DS opaque key.
* This is one-shot function that combines the start and complete operations.
*
* @param attributes Key attributes
* @param key_buffer Key buffer
* @param key_buffer_size Key buffer size
* @param alg Algorithm used in the sign operation
* @param hash Hash to sign
* @param hash_length Length of the hash
* @param signature Signature buffer
* @param signature_size Size of the signature buffer
* @param signature_length Actual length of the signature
* @return Status of the sign operation
* PSA_SUCCESS if the operation was completed successfully
* Error code if the operation was not completed successfully, check psa_status_t documentation for more details.
*/
psa_status_t esp_rsa_ds_opaque_signature_sign_hash(
const psa_key_attributes_t *attributes,
const uint8_t *key_buffer,
size_t key_buffer_size,
psa_algorithm_t alg,
const uint8_t *hash,
size_t hash_length,
uint8_t *signature,
size_t signature_size,
size_t *signature_length
);
/**
* @brief Import the RSA DS opaque key
* The data should be of type esp_ds_data_ctx_t and should be
* already initialised with DS data and efuse key id.
*
* @param attributes Key attributes
* @param data Key data
* @param data_length Key data length
* @param key_buffer Key buffer
* @param key_buffer_size Key buffer size
* @param key_buffer_length Key buffer length
* @param bits Key bits
* @return Status of the import operation
* PSA_SUCCESS if the key was imported successfully
* Error code if the key was not imported successfully, check psa_status_t documentation for more details
*/
psa_status_t esp_rsa_ds_opaque_import_key(
const psa_key_attributes_t *attributes,
const uint8_t *data,
size_t data_length,
uint8_t *key_buffer,
size_t key_buffer_size,
size_t *key_buffer_length,
size_t *bits);
/**
* @brief Return the size of the RSA DS opaque key in bytes
*
* @param key_type Key type
* @param key_bits Key bits
* @return Size of the RSA DS opaque key in bytes
*/
size_t esp_rsa_ds_opaque_size_function(
psa_key_type_t key_type,
size_t key_bits);
/**
* @brief Set the timeout for the RSA DS session
*
* @param timeout_ms Timeout in milliseconds
*/
void esp_rsa_ds_opaque_set_session_timeout(int timeout_ms);
/**
* @brief Decrypt the input using the RSA DS opaque key.
*
* @param attributes Key attributes
* @param key Key buffer
* @param key_length Key buffer size
* @param alg Algorithm used in the decrypt operation
* @param input Input buffer
* @param input_length Length of the input buffer
* @param salt Salt buffer
* @param salt_length Length of the salt buffer
* @param output Output buffer
* @param output_size Size of the output buffer
* @param output_length Actual length of the output
* @return Status of the decrypt operation
* PSA_SUCCESS if the operation was completed successfully
* Error code if the operation was not completed successfully, check psa_status_t documentation for more details.
*/
psa_status_t esp_rsa_ds_opaque_asymmetric_decrypt(
const psa_key_attributes_t *attributes, const uint8_t *key,
size_t key_length, psa_algorithm_t alg, const uint8_t *input,
size_t input_length, const uint8_t *salt, size_t salt_length,
uint8_t *output, size_t output_size, size_t *output_length);
#endif /* SOC_DIG_SIGN_SUPPORTED && CONFIG_MBEDTLS_HARDWARE_RSA_DS_PERIPHERAL */
#ifdef __cplusplus
}
#endif
@@ -0,0 +1,55 @@
/*
* SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include "sdkconfig.h"
#include "soc/soc_caps.h"
#if defined(SOC_DIG_SIGN_SUPPORTED) && defined(CONFIG_MBEDTLS_HARDWARE_RSA_DS_PERIPHERAL)
#include "psa/crypto.h"
#include "esp_ds.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief RSA-DS padding options
*/
typedef enum {
ESP_RSA_DS_PADDING_PKCS_V15,
ESP_RSA_DS_PADDING_PSS,
ESP_RSA_DS_PADDING_OAEP,
ESP_RSA_DS_PADDING_INVALID = -1
} esp_rsa_ds_padding_t;
/**
* @brief ESP DS data context
* This context is used to store the ESP DS data.
*/
typedef struct {
esp_ds_data_t *esp_rsa_ds_data; /**< Pointer to the esp ds data */
uint8_t efuse_key_id; /**< efuse block id in which DS_KEY is stored e.g. 0,1*/
uint16_t rsa_length_bits; /**< length of RSA private key in bits e.g. 2048 */
} esp_ds_data_ctx_t;
#if !(__DOXYGEN__) // No need to document these structures, these are internal to the driver
/* The buffers are stored in the little-endian format */
typedef struct {
const esp_ds_data_ctx_t *esp_rsa_ds_opaque_key; /**< Pointer to the esp ds opaque key */
psa_algorithm_t alg; /**< Algorithm used in the sign operation */
uint32_t *sig_buffer; /**< Buffer to hold the signature */
size_t sig_buffer_size; /**< Size of the signature buffer */
esp_ds_context_t *esp_rsa_ds_ctx; /**< Pointer to the esp ds context */
esp_ds_data_t esp_rsa_ds_data; /**< RSA DS data */
} esp_rsa_ds_opaque_sign_hash_operation_t;
#endif /* !(__DOXYGEN__) */
#ifdef __cplusplus
}
#endif
#endif /* SOC_DIG_SIGN_SUPPORTED && CONFIG_MBEDTLS_HARDWARE_RSA_DS_PERIPHERAL */
@@ -10,6 +10,7 @@
#include "esp_types.h"
#include <stdbool.h>
#include "soc/soc_caps.h"
#include "sdkconfig.h"
#ifdef __cplusplus
extern "C" {
@@ -28,6 +29,9 @@ extern "C" {
* crypto_driver_contexts_primitives.h.
*/
/**
* @brief ESP SHA operation type
*/
typedef enum {
ESP_SHA_OPERATION_TYPE_SHA1,
ESP_SHA_OPERATION_TYPE_SHA256,
@@ -37,24 +41,33 @@ typedef enum {
} esp_sha_operation_type_t;
/**
* \brief ESP SHA1 state enumeration
* @brief ESP SHA1 state enumeration
*/
typedef enum {
ESP_SHA1_STATE_INIT,
ESP_SHA1_STATE_IN_PROCESS
} esp_sha1_state;
/**
* @brief ESP SHA256 state enumeration
*/
typedef enum {
ESP_SHA256_STATE_INIT,
ESP_SHA256_STATE_IN_PROCESS
} esp_sha256_state;
/**
* @brief ESP SHA512 state enumeration
*/
typedef enum {
ESP_SHA512_STATE_INIT,
ESP_SHA512_STATE_IN_PROCESS
} esp_sha512_state;
#if SOC_SHA_SUPPORT_PARALLEL_ENG
#if CONFIG_SOC_SHA_SUPPORT_PARALLEL_ENG
/**
* @brief ESP SHA mode enumeration
*/
typedef enum {
ESP_SHA_MODE_UNUSED,
ESP_SHA_MODE_HARDWARE,
@@ -63,61 +76,65 @@ typedef enum {
#endif /* SOC_SHA_SUPPORT_PARALLEL_ENG */
/**
* \brief ESP SHA1 context structure
* @brief ESP SHA1 context structure
*/
typedef struct {
uint32_t total[2]; /*!< The number of Bytes processed. */
uint32_t state[5]; /*!< The intermediate digest state. */
unsigned char buffer[64]; /*!< The data block being processed. */
bool first_block; /*!< First block flag for hardware initialization */
int sha_state; /*!< SHA operation state */
#if SOC_SHA_SUPPORT_PARALLEL_ENG
uint32_t total[2]; /**< The number of Bytes processed. */
uint32_t state[5]; /**< The intermediate digest state. */
unsigned char buffer[64]; /**< The data block being processed. */
bool first_block; /**< First block flag for hardware initialization */
int sha_state; /**< SHA operation state */
#if CONFIG_SOC_SHA_SUPPORT_PARALLEL_ENG
esp_sha_mode_t operation_mode; /*!< Hardware or Software mode */
#endif /* SOC_SHA_SUPPORT_PARALLEL_ENG */
} esp_sha1_context;
/**
* \brief ESP SHA256 context structure
* @brief ESP SHA256 context structure
*/
typedef struct {
unsigned char buffer[64]; /*!< The data block being processed. */
uint32_t total[2]; /*!< The number of Bytes processed. */
uint32_t state[8]; /*!< The intermediate digest state. */
bool first_block; /*!< First block flag for hardware initialization */
int sha_state; /*!< SHA operation state */
int mode; /*!< SHA2_224 or SHA2_256 */
#if SOC_SHA_SUPPORT_PARALLEL_ENG
unsigned char buffer[64]; /**< The data block being processed. */
uint32_t total[2]; /**< The number of Bytes processed. */
uint32_t state[8]; /**< The intermediate digest state. */
bool first_block; /**< First block flag for hardware initialization */
int sha_state; /**< SHA operation state */
int mode; /**< SHA2_224 or SHA2_256 */
#if CONFIG_SOC_SHA_SUPPORT_PARALLEL_ENG
esp_sha_mode_t operation_mode; /*!< Hardware or Software mode */
#endif /* SOC_SHA_SUPPORT_PARALLEL_ENG */
} esp_sha256_context;
/**
* \brief ESP SHA512 context structure
*
* @brief ESP SHA512 context structure
*/
typedef struct {
uint64_t total[2]; /*!< The number of Bytes processed. */
uint64_t state[8]; /*!< The intermediate digest state. */
unsigned char buffer[128]; /*!< The data block being processed. */
bool first_block;
int sha_state;
int mode;
uint32_t t_val; /*!< t_val for 512/t mode */
#if SOC_SHA_SUPPORT_PARALLEL_ENG
esp_sha_mode_t operation_mode; /*!< Hardware or Software mode */
#endif /* SOC_SHA_SUPPORT_PARALLEL_ENG */
uint64_t total[2]; /**< The number of Bytes processed. */
uint64_t state[8]; /**< The intermediate digest state. */
unsigned char buffer[128]; /**< The data block being processed. */
bool first_block; /**< First block flag for hardware initialization */
int sha_state; /**< SHA operation state */
int mode; /**< SHA2_224 or SHA2_256 */
uint32_t t_val; /**< t_val for 512/t mode */
#if CONFIG_SOC_SHA_SUPPORT_PARALLEL_ENG
esp_sha_mode_t operation_mode; /**< Hardware or Software mode */
#endif /* CONFIG_SOC_SHA_SUPPORT_PARALLEL_ENG */
} esp_sha512_context;
/**
* @brief ESP SHA context type
* This is void pointer to remove any dependency on the actual SHA context structure
* and allows the driver to be used with different SHA context structures.
*/
typedef void *esp_sha_context_t;
/**
* \brief ESP SHA driver operation context
* @brief ESP SHA driver operation context
*
* This structure contains the contexts for different SHA algorithms
* supported by the ESP hardware accelerator.
*/
typedef struct {
esp_sha_context_t sha_ctx;
esp_sha_operation_type_t sha_type;
esp_sha_context_t sha_ctx; /**< Pointer to the SHA context */
esp_sha_operation_type_t sha_type; /**< SHA operation type */
} esp_sha_hash_operation_t;
#ifdef __cplusplus
@@ -10,16 +10,12 @@
#include "esp_random.h"
#include "sdkconfig.h"
#include "soc/soc_caps.h"
#include "esp_efuse.h"
#include "hal/hmac_types.h"
#include "esp_efuse.h"
#ifndef ESP_EFUSE_KEY_PURPOSE_HMAC_DOWN_DIGITAL_SIGNATURE
#define ESP_EFUSE_KEY_PURPOSE_HMAC_DOWN_DIGITAL_SIGNATURE 0
#endif
#ifdef SOC_DIG_SIGN_SUPPORTED
#ifdef CONFIG_MBEDTLS_HARDWARE_RSA_DS_PERIPHERAL
#include "esp_ds.h"
#include "psa_crypto_driver_esp_ds.h"
#include "psa_crypto_driver_esp_rsa_ds.h"
esp_ds_data_ctx_t *esp_secure_cert_get_ds_ctx(void)
{
@@ -34,7 +30,7 @@ esp_ds_data_ctx_t *esp_secure_cert_get_ds_ctx(void)
// Mock RSA key parameters
ds_key->rsa_length_bits = 2048;
ds_key->efuse_key_id = 0;
ds_key->esp_ds_data = calloc(1, sizeof(esp_ds_data_t));
ds_key->esp_rsa_ds_data = calloc(1, sizeof(esp_ds_data_t));
// Fill in other necessary fields as per esp_ds_data_ctx_t definition
// For simplicity, we will leave them zeroed out
@@ -44,8 +40,8 @@ esp_ds_data_ctx_t *esp_secure_cert_get_ds_ctx(void)
void esp_secure_cert_free_ds_ctx(esp_ds_data_ctx_t *ds_key)
{
if (ds_key != NULL) {
if (ds_key->esp_ds_data != NULL) {
free(ds_key->esp_ds_data);
if (ds_key->esp_rsa_ds_data != NULL) {
free(ds_key->esp_rsa_ds_data);
}
free(ds_key);
}
@@ -67,7 +63,7 @@ TEST_CASE("ds sign test pkcs1_v15 PSA validation", "[ds_rsa_psa]")
psa_set_key_bits(&attributes, ds_key->rsa_length_bits);
psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_SIGN_HASH);
psa_set_key_algorithm(&attributes, alg);
psa_set_key_lifetime(&attributes, PSA_KEY_LIFETIME_ESP_DS);
psa_set_key_lifetime(&attributes, PSA_KEY_LIFETIME_ESP_RSA_DS);
status = psa_import_key(&attributes,
(const uint8_t *)ds_key,
sizeof(*ds_key),
@@ -83,15 +79,15 @@ TEST_CASE("ds sign test pkcs1_v15 PSA validation", "[ds_rsa_psa]")
TEST_ASSERT_EQUAL(PSA_ERROR_INVALID_ARGUMENT, status);
ds_key->rsa_length_bits = 2048; // Reset to valid RSA length
esp_ds_data_t *ds_data_backup = ds_key->esp_ds_data;
ds_key->esp_ds_data = NULL; // NULL esp_ds_data to trigger validation failure
esp_ds_data_t *ds_data_backup = ds_key->esp_rsa_ds_data;
ds_key->esp_rsa_ds_data = NULL; // NULL esp_rsa_ds_data to trigger validation failure
status = psa_import_key(&attributes,
(const uint8_t *)ds_key,
sizeof(*ds_key),
&keyt_id);
TEST_ASSERT_EQUAL(PSA_ERROR_INVALID_ARGUMENT, status);
ds_key->esp_ds_data = ds_data_backup; // Restore esp_ds_data
ds_key->esp_rsa_ds_data = ds_data_backup; // Restore esp_rsa_ds_data
esp_secure_cert_free_ds_ctx(ds_key);
}
@@ -112,7 +108,7 @@ TEST_CASE("ds sign test pkcs1_v15 PSA", "[ds_rsa_psa]")
psa_set_key_bits(&attributes, ds_key->rsa_length_bits);
psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_SIGN_HASH);
psa_set_key_algorithm(&attributes, alg);
psa_set_key_lifetime(&attributes, PSA_KEY_LIFETIME_ESP_DS);
psa_set_key_lifetime(&attributes, PSA_KEY_LIFETIME_ESP_RSA_DS);
status = psa_import_key(&attributes,
(const uint8_t *)ds_key,
sizeof(*ds_key),
@@ -139,6 +135,23 @@ TEST_CASE("ds sign test pkcs1_v15 PSA", "[ds_rsa_psa]")
// Free the DS context to prevent memory leak
esp_secure_cert_free_ds_ctx(ds_key);
// Because we have wrapped around the ds_start_sign and ds_finish_sign functions,
// we are not actually performing the real signing operation. That test is done in the
// crypto test_apps, so here we just check that the surrounding code works as expected.
// In this test, we have used v15 padding, so we expect the signature to be non-null
// and the hash to be part of the signature.
TEST_ASSERT_EQUAL(0, memcmp(hash, signature + (256 - hash_length), hash_length));
// Let's also ensure that signature has correct encoding
// Just before the hash start, it should have size of hash
TEST_ASSERT_EQUAL(hash_length, signature[256 - hash_length - 1]);
// One byte before should be MBEDTLS_ASN1_OCTET_STRING
TEST_ASSERT_EQUAL(0x04, signature[256 - hash_length - 2]);
// And the first byte should be 0x00, indicating that this is a valid PKCS#1 v1.5 signature
TEST_ASSERT_EQUAL(0x00, signature[0]);
}
const unsigned char message[] = {
@@ -162,7 +175,7 @@ TEST_CASE("ds sign test pkcs1_v21 PSA", "[ds_rsa_psa]")
psa_set_key_bits(&attributes, ds_key->rsa_length_bits);
psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_SIGN_HASH);
psa_set_key_algorithm(&attributes, alg);
psa_set_key_lifetime(&attributes, PSA_KEY_LIFETIME_ESP_DS);
psa_set_key_lifetime(&attributes, PSA_KEY_LIFETIME_ESP_RSA_DS);
status = psa_import_key(&attributes,
(const uint8_t *)ds_key,
sizeof(*ds_key),
@@ -227,7 +240,7 @@ TEST_CASE("ds decrypt test pkcs1_v21 PSA", "[ds_rsa]")
psa_set_key_bits(&attributes, ds_key->rsa_length_bits);
psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_DECRYPT);
psa_set_key_algorithm(&attributes, alg);
psa_set_key_lifetime(&attributes, PSA_KEY_LIFETIME_ESP_DS);
psa_set_key_lifetime(&attributes, PSA_KEY_LIFETIME_ESP_RSA_DS);
status = psa_import_key(&attributes,
(const uint8_t *)ds_key,
sizeof(*ds_key),
@@ -289,7 +302,7 @@ TEST_CASE("ds decrypt test pkcs1_v15 PSA", "[ds_rsa]")
psa_set_key_bits(&attributes, ds_key->rsa_length_bits);
psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_DECRYPT);
psa_set_key_algorithm(&attributes, alg);
psa_set_key_lifetime(&attributes, PSA_KEY_LIFETIME_ESP_DS);
psa_set_key_lifetime(&attributes, PSA_KEY_LIFETIME_ESP_RSA_DS);
status = psa_import_key(&attributes,
(const uint8_t *)ds_key,
sizeof(*ds_key),
@@ -342,17 +355,20 @@ int __wrap_esp_ds_finish_sign(void *sig, esp_ds_context_t *ctx)
// return __real_esp_ds_finish_sign(sig, ctx);
}
#endif /* SOC_DIG_SIGN_SUPPORTED */
#endif /* CONFIG_MBEDTLS_HARDWARE_RSA_DS_PERIPHERAL */
// Forward declaration for linker-wrapped function
extern esp_efuse_purpose_t __real_esp_efuse_get_key_purpose(esp_efuse_block_t block);
esp_efuse_purpose_t __wrap_esp_efuse_get_key_purpose(esp_efuse_block_t block)
{
#if CONFIG_MBEDTLS_HARDWARE_RSA_DS_PERIPHERAL
if (block == EFUSE_BLK_KEY0 + 0) {
printf("Mocked esp_efuse_get_key_purpose called for block %d\n", block);
return ESP_EFUSE_KEY_PURPOSE_HMAC_DOWN_DIGITAL_SIGNATURE;
} else {
} else
#endif /* CONFIG_MBEDTLS_HARDWARE_RSA_DS_PERIPHERAL */
{
printf("Mocked esp_efuse_get_key_purpose forwarding to real for block %d\n", block);
return __real_esp_efuse_get_key_purpose(block);
}
@@ -1 +1,2 @@
CONFIG_MBEDTLS_SSL_PROTO_TLS1_3=y
CONFIG_MBEDTLS_HARDWARE_RSA_DS_PERIPHERAL=y
+3
View File
@@ -293,6 +293,9 @@ INPUT = \
$(PROJECT_PATH)/components/mbedtls/esp_crt_bundle/include/esp_crt_bundle.h \
$(PROJECT_PATH)/components/mbedtls/port/psa_driver/include/psa_crypto_driver_esp_ecdsa_contexts.h \
$(PROJECT_PATH)/components/mbedtls/port/psa_driver/include/psa_crypto_driver_esp_hmac_opaque_contexts.h \
$(PROJECT_PATH)/components/mbedtls/port/psa_driver/include/psa_crypto_driver_esp_rsa_ds_contexts.h \
$(PROJECT_PATH)/components/mbedtls/port/psa_driver/include/psa_crypto_driver_esp_sha_contexts.h \
$(PROJECT_PATH)/components/mbedtls/port/psa_driver/include/psa_crypto_driver_esp_aes_contexts.h \
$(PROJECT_PATH)/components/nvs_flash/include/nvs_flash.h \
$(PROJECT_PATH)/components/nvs_flash/include/nvs.h \
$(PROJECT_PATH)/components/nvs_flash/include/nvs_bootloader.h \