mirror of
https://github.com/espressif/esp-idf.git
synced 2025-07-31 19:24:33 +02:00
Merge branch 'feature/support_ds_peripheral_rsa_decryption_v5.4' into 'release/v5.4'
feat(mbedtls): Add support for RSA decryption with DS peripheral (v5.4) See merge request espressif/esp-idf!40450
This commit is contained in:
@@ -39,6 +39,7 @@ static esp_err_t esp_set_atecc608a_pki_context(esp_tls_t *tls, const void *pki);
|
||||
#endif /* CONFIG_ESP_TLS_USE_SECURE_ELEMENT */
|
||||
|
||||
#if defined(CONFIG_ESP_TLS_USE_DS_PERIPHERAL)
|
||||
#include <pk_wrap.h>
|
||||
#include "rsa_sign_alt.h"
|
||||
static esp_err_t esp_mbedtls_init_pk_ctx_for_ds(const void *pki);
|
||||
#endif /* CONFIG_ESP_TLS_USE_DS_PERIPHERAL */
|
||||
@@ -381,6 +382,28 @@ void esp_mbedtls_cleanup(esp_tls_t *tls)
|
||||
tls->cacert_ptr = NULL;
|
||||
mbedtls_x509_crt_free(&tls->cacert);
|
||||
mbedtls_x509_crt_free(&tls->clientcert);
|
||||
|
||||
#ifdef CONFIG_ESP_TLS_USE_DS_PERIPHERAL
|
||||
if (mbedtls_pk_get_type(&tls->clientkey) == MBEDTLS_PK_RSA_ALT) {
|
||||
mbedtls_rsa_alt_context *rsa_alt = tls->clientkey.MBEDTLS_PRIVATE(pk_ctx);
|
||||
if (rsa_alt && rsa_alt->key != NULL) {
|
||||
mbedtls_rsa_free(rsa_alt->key);
|
||||
mbedtls_free(rsa_alt->key);
|
||||
rsa_alt->key = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
// Similar cleanup for server key
|
||||
if (mbedtls_pk_get_type(&tls->serverkey) == MBEDTLS_PK_RSA_ALT) {
|
||||
mbedtls_rsa_alt_context *rsa_alt = tls->serverkey.MBEDTLS_PRIVATE(pk_ctx);
|
||||
if (rsa_alt && rsa_alt->key != NULL) {
|
||||
mbedtls_rsa_free(rsa_alt->key);
|
||||
mbedtls_free(rsa_alt->key);
|
||||
rsa_alt->key = NULL;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
mbedtls_pk_free(&tls->clientkey);
|
||||
mbedtls_entropy_free(&tls->entropy);
|
||||
mbedtls_ssl_config_free(&tls->conf);
|
||||
@@ -1127,12 +1150,18 @@ static esp_err_t esp_mbedtls_init_pk_ctx_for_ds(const void *pki)
|
||||
{
|
||||
int ret = -1;
|
||||
/* initialize the mbedtls pk context with rsa context */
|
||||
mbedtls_rsa_context rsakey;
|
||||
mbedtls_rsa_init(&rsakey);
|
||||
if ((ret = mbedtls_pk_setup_rsa_alt(((const esp_tls_pki_t*)pki)->pk_key, &rsakey, NULL, esp_ds_rsa_sign,
|
||||
mbedtls_rsa_context *rsakey = calloc(1, sizeof(mbedtls_rsa_context));
|
||||
if (rsakey == NULL) {
|
||||
ESP_LOGE(TAG, "Failed to allocate memory for mbedtls_rsa_context");
|
||||
return ESP_ERR_NO_MEM;
|
||||
}
|
||||
mbedtls_rsa_init(rsakey);
|
||||
if ((ret = mbedtls_pk_setup_rsa_alt(((const esp_tls_pki_t*)pki)->pk_key, rsakey, NULL, esp_ds_rsa_sign,
|
||||
esp_ds_get_keylen )) != 0) {
|
||||
ESP_LOGE(TAG, "Error in mbedtls_pk_setup_rsa_alt, returned -0x%04X", -ret);
|
||||
mbedtls_print_error_msg(ret);
|
||||
mbedtls_rsa_free(rsakey);
|
||||
free(rsakey);
|
||||
ret = ESP_FAIL;
|
||||
goto exit;
|
||||
}
|
||||
@@ -1143,7 +1172,6 @@ static esp_err_t esp_mbedtls_init_pk_ctx_for_ds(const void *pki)
|
||||
}
|
||||
ESP_LOGD(TAG, "DS peripheral params initialized.");
|
||||
exit:
|
||||
mbedtls_rsa_free(&rsakey);
|
||||
return ret;
|
||||
}
|
||||
#endif /* CONFIG_ESP_TLS_USE_DS_PERIPHERAL */
|
||||
|
@@ -247,9 +247,11 @@ if(CONFIG_SOC_SHA_SUPPORTED)
|
||||
)
|
||||
endif()
|
||||
|
||||
# CONFIG_ESP_TLS_USE_DS_PERIPHERAL can be enabled only for the supported targets.
|
||||
if(CONFIG_ESP_TLS_USE_DS_PERIPHERAL)
|
||||
target_sources(mbedcrypto PRIVATE "${COMPONENT_DIR}/port/esp_ds/esp_rsa_sign_alt.c")
|
||||
if(CONFIG_SOC_DIG_SIGN_SUPPORTED)
|
||||
target_sources(mbedcrypto PRIVATE
|
||||
"${COMPONENT_DIR}/port/esp_ds/esp_rsa_sign_alt.c"
|
||||
"${COMPONENT_DIR}/port/esp_ds/esp_rsa_dec_alt.c"
|
||||
"${COMPONENT_DIR}/port/esp_ds/esp_ds_common.c")
|
||||
endif()
|
||||
|
||||
# Note: some mbedTLS hardware acceleration can be enabled/disabled by config.
|
||||
|
226
components/mbedtls/port/esp_ds/esp_ds_common.c
Normal file
226
components/mbedtls/port/esp_ds/esp_ds_common.c
Normal file
@@ -0,0 +1,226 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include "sdkconfig.h"
|
||||
#include "esp_ds.h"
|
||||
#include "esp_log.h"
|
||||
#include "esp_ds_common.h"
|
||||
#include "esp_memory_utils.h"
|
||||
#include "esp_ds/esp_ds_rsa.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/semphr.h"
|
||||
#include "mbedtls/rsa.h"
|
||||
#include <string.h>
|
||||
|
||||
#ifdef SOC_DIG_SIGN_SUPPORTED
|
||||
#include "rom/digital_signature.h"
|
||||
#else
|
||||
#error "Selected target does not support DS peripheral"
|
||||
#endif
|
||||
|
||||
#define FACTOR_KEYLEN_IN_BYTES 4
|
||||
|
||||
static const char *TAG = "ESP_DS_COMMON";
|
||||
|
||||
static hmac_key_id_t s_esp_ds_hmac_key_id = -1;
|
||||
static esp_ds_data_t *s_ds_data = NULL;
|
||||
static SemaphoreHandle_t s_ds_lock = NULL;
|
||||
static int s_timeout_ms = 0;
|
||||
|
||||
esp_ds_data_t *esp_ds_get_data_ctx(void)
|
||||
{
|
||||
return s_ds_data;
|
||||
}
|
||||
|
||||
hmac_key_id_t esp_ds_get_hmac_key_id(void)
|
||||
{
|
||||
return s_esp_ds_hmac_key_id;
|
||||
}
|
||||
|
||||
size_t esp_ds_get_keylen(void *ctx)
|
||||
{
|
||||
if (s_ds_data == NULL) {
|
||||
ESP_LOGE(TAG, "s_ds_data is NULL, cannot get key length");
|
||||
return 0;
|
||||
}
|
||||
/* calculating the rsa_length in bytes */
|
||||
return ((s_ds_data->rsa_length + 1) * FACTOR_KEYLEN_IN_BYTES);
|
||||
}
|
||||
|
||||
/* 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)
|
||||
{
|
||||
if ((s_ds_lock = xSemaphoreCreateMutex()) == NULL) {
|
||||
ESP_EARLY_LOGE(TAG, "mutex for the DS session lock could not be created");
|
||||
}
|
||||
}
|
||||
|
||||
void esp_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()) {
|
||||
/* Give back the semaphore (DS lock) */
|
||||
xSemaphoreGive(s_ds_lock);
|
||||
}
|
||||
}
|
||||
|
||||
void esp_ds_set_session_timeout(int timeout)
|
||||
{
|
||||
/* add additional offset of 1000 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 > s_timeout_ms) {
|
||||
s_timeout_ms = timeout + 1000;
|
||||
}
|
||||
}
|
||||
|
||||
esp_err_t esp_ds_init_data_ctx(esp_ds_data_ctx_t *ds_data)
|
||||
{
|
||||
if (ds_data == NULL || ds_data->esp_ds_data == NULL) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
/* mutex is given back when the DS context is freed after the TLS handshake is completed or in case of failure (at cleanup) */
|
||||
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 ESP_FAIL;
|
||||
}
|
||||
s_ds_data = ds_data->esp_ds_data;
|
||||
ESP_LOGD(TAG, "Using DS with key block %u, RSA length %u", ds_data->efuse_key_id, ds_data->rsa_length_bits);
|
||||
s_esp_ds_hmac_key_id = (hmac_key_id_t) ds_data->efuse_key_id;
|
||||
|
||||
const unsigned rsa_length_int = (ds_data->rsa_length_bits / 32) - 1;
|
||||
if (esp_ptr_byte_accessible(s_ds_data)) {
|
||||
/* calculate the rsa_length in terms of esp_digital_signature_length_t which is required for the internal DS API */
|
||||
s_ds_data->rsa_length = rsa_length_int;
|
||||
} else if (s_ds_data->rsa_length != rsa_length_int) {
|
||||
/*
|
||||
* Configuration data is most likely from DROM segment and it
|
||||
* is not properly formatted for all parameters consideration.
|
||||
* Moreover, we can not modify as it is read-only and hence
|
||||
* the error.
|
||||
*/
|
||||
ESP_LOGE(TAG, "RSA length mismatch %u, %u", s_ds_data->rsa_length, rsa_length_int);
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t esp_ds_deinit_data_ctx(void)
|
||||
{
|
||||
esp_ds_release_ds_lock();
|
||||
s_ds_data = NULL;
|
||||
s_esp_ds_hmac_key_id = -1;
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
int esp_ds_mgf_mask(unsigned char *dst, size_t dlen, unsigned char *src,
|
||||
size_t slen, mbedtls_md_type_t md_alg)
|
||||
{
|
||||
unsigned char counter[4];
|
||||
unsigned char *p;
|
||||
unsigned int hlen;
|
||||
size_t i, use_len;
|
||||
unsigned char mask[MBEDTLS_MD_MAX_SIZE];
|
||||
int ret = 0;
|
||||
const mbedtls_md_info_t *md_info;
|
||||
mbedtls_md_context_t md_ctx;
|
||||
|
||||
mbedtls_md_init(&md_ctx);
|
||||
md_info = mbedtls_md_info_from_type(md_alg);
|
||||
if (md_info == NULL) {
|
||||
return MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
|
||||
}
|
||||
|
||||
if ((ret = mbedtls_md_setup(&md_ctx, md_info, 0)) != 0) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
hlen = mbedtls_md_get_size(md_info);
|
||||
|
||||
memset(mask, 0, sizeof(mask));
|
||||
memset(counter, 0, 4);
|
||||
|
||||
/* Generate and apply dbMask */
|
||||
p = dst;
|
||||
|
||||
while (dlen > 0) {
|
||||
use_len = hlen;
|
||||
if (dlen < hlen) {
|
||||
use_len = dlen;
|
||||
}
|
||||
|
||||
if ((ret = mbedtls_md_starts(&md_ctx)) != 0) {
|
||||
goto exit;
|
||||
}
|
||||
if ((ret = mbedtls_md_update(&md_ctx, src, slen)) != 0) {
|
||||
goto exit;
|
||||
}
|
||||
if ((ret = mbedtls_md_update(&md_ctx, counter, 4)) != 0) {
|
||||
goto exit;
|
||||
}
|
||||
if ((ret = mbedtls_md_finish(&md_ctx, mask)) != 0) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
for (i = 0; i < use_len; ++i) {
|
||||
*p++ ^= mask[i];
|
||||
}
|
||||
|
||||
counter[3]++;
|
||||
|
||||
dlen -= use_len;
|
||||
}
|
||||
|
||||
exit:
|
||||
mbedtls_platform_zeroize(mask, sizeof(mask));
|
||||
mbedtls_md_free(&md_ctx);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int esp_ds_hash_mprime(const unsigned char *hash, size_t hlen,
|
||||
const unsigned char *salt, size_t slen,
|
||||
unsigned char *out, mbedtls_md_type_t md_alg)
|
||||
{
|
||||
const unsigned char zeros[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
|
||||
|
||||
mbedtls_md_context_t md_ctx;
|
||||
int ret = MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
|
||||
|
||||
const mbedtls_md_info_t *md_info = mbedtls_md_info_from_type(md_alg);
|
||||
if (md_info == NULL) {
|
||||
return MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
|
||||
}
|
||||
|
||||
mbedtls_md_init(&md_ctx);
|
||||
if ((ret = mbedtls_md_setup(&md_ctx, md_info, 0)) != 0) {
|
||||
goto exit;
|
||||
}
|
||||
if ((ret = mbedtls_md_starts(&md_ctx)) != 0) {
|
||||
goto exit;
|
||||
}
|
||||
if ((ret = mbedtls_md_update(&md_ctx, zeros, sizeof(zeros))) != 0) {
|
||||
goto exit;
|
||||
}
|
||||
if ((ret = mbedtls_md_update(&md_ctx, hash, hlen)) != 0) {
|
||||
goto exit;
|
||||
}
|
||||
if ((ret = mbedtls_md_update(&md_ctx, salt, slen)) != 0) {
|
||||
goto exit;
|
||||
}
|
||||
if ((ret = mbedtls_md_finish(&md_ctx, out)) != 0) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
exit:
|
||||
mbedtls_md_free(&md_ctx);
|
||||
|
||||
return ret;
|
||||
}
|
62
components/mbedtls/port/esp_ds/esp_ds_common.h
Normal file
62
components/mbedtls/port/esp_ds/esp_ds_common.h
Normal file
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "mbedtls/md.h"
|
||||
|
||||
#define FACTOR_KEYLEN_IN_BYTES 4
|
||||
#define SWAP_INT32(x) (((x) >> 24) | (((x) & 0x00FF0000) >> 8) | (((x) & 0x0000FF00) << 8) | ((x) << 24))
|
||||
|
||||
/**
|
||||
* @brief Get the data context for the digital signature.
|
||||
*
|
||||
* @return esp_ds_data_t* esp ds data context pointer.
|
||||
*/
|
||||
esp_ds_data_t *esp_ds_get_data_ctx(void);
|
||||
|
||||
/**
|
||||
* @brief Get the HMAC key ID used for digital signature operations.
|
||||
*
|
||||
* @return hmac_key_id_t HMAC key ID.
|
||||
*/
|
||||
hmac_key_id_t esp_ds_get_hmac_key_id(void);
|
||||
|
||||
/**
|
||||
* @brief Mask generation function (MGF) for TLS 1.3.
|
||||
*
|
||||
* @param[in] dst Pointer to the destination buffer.
|
||||
* @param[in] dlen Length of the destination buffer.
|
||||
* @param[in] src Pointer to the source buffer.
|
||||
* @param[in] slen Length of the salt value.
|
||||
* @param[in] md_alg The message digest algorithm type.
|
||||
* @return int Returns 0 on success, or a negative error code on failure.
|
||||
*/
|
||||
int esp_ds_mgf_mask(unsigned char *dst, size_t dlen, unsigned char *src,
|
||||
size_t slen, mbedtls_md_type_t md_alg);
|
||||
|
||||
/**
|
||||
* @brief Generates a hash using the M-Prime algorithm as specified in RFC 8446.
|
||||
*
|
||||
* @param hash Pointer to the input hash.
|
||||
* @param hlen Length of the input hash.
|
||||
* @param salt Pointer to the salt value.
|
||||
* @param slen Length of the salt value.
|
||||
* @param out Pointer to the output buffer where the hash will be stored.
|
||||
* @param md_alg The message digest algorithm type to use for hashing.
|
||||
* @return int Returns 0 on success, or a negative error code on failure.
|
||||
*/
|
||||
int esp_ds_hash_mprime(const unsigned char *hash, size_t hlen,
|
||||
const unsigned char *salt, size_t slen,
|
||||
unsigned char *out, mbedtls_md_type_t md_alg);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
293
components/mbedtls/port/esp_ds/esp_rsa_dec_alt.c
Normal file
293
components/mbedtls/port/esp_ds/esp_rsa_dec_alt.c
Normal file
@@ -0,0 +1,293 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
|
||||
#include <string.h>
|
||||
#include "sdkconfig.h"
|
||||
#include "esp_ds.h"
|
||||
#include "rsa_dec_alt.h"
|
||||
#include "mbedtls/rsa.h"
|
||||
#include "esp_ds_common.h"
|
||||
#include "esp_log.h"
|
||||
|
||||
static const char *TAG = "ESP_RSA_DEC_ALT";
|
||||
|
||||
#define MIN_V15_PADDING_LEN 11
|
||||
|
||||
static int esp_ds_rsaes_pkcs1_v15_unpadding(unsigned char *input,
|
||||
size_t ilen,
|
||||
unsigned char *output,
|
||||
size_t output_max_len,
|
||||
size_t *olen)
|
||||
{
|
||||
if (ilen < MIN_V15_PADDING_LEN) {
|
||||
return MBEDTLS_ERR_RSA_INVALID_PADDING;
|
||||
}
|
||||
|
||||
unsigned char bad = 0;
|
||||
size_t msg_len = 0;
|
||||
size_t msg_max_len = 0;
|
||||
unsigned char pad_done = 0;
|
||||
size_t pad_count = 0;
|
||||
|
||||
msg_max_len = (output_max_len > ilen - MIN_V15_PADDING_LEN) ? ilen - MIN_V15_PADDING_LEN : output_max_len;
|
||||
|
||||
/* Check the first byte (0x00) */
|
||||
bad |= input[0];
|
||||
|
||||
/* Check the padding type */
|
||||
bad |= input[1] ^ MBEDTLS_RSA_CRYPT;
|
||||
|
||||
/* Scan for separator (0x00) and count padding bytes in constant time */
|
||||
for (size_t i = 2; i < ilen; i++) {
|
||||
unsigned char found = (input[i] == 0x00);
|
||||
pad_done = pad_done | found;
|
||||
pad_count += (pad_done == 0) ? 1 : 0;
|
||||
}
|
||||
|
||||
/* Check if we found a separator and padding is long enough */
|
||||
bad |= (pad_done == 0); /* No separator found */
|
||||
bad |= (pad_count < 8); /* Padding too short (need at least 8 non-zero bytes) */
|
||||
|
||||
/* Calculate message length */
|
||||
msg_len = ilen - pad_count - 3;
|
||||
|
||||
/* Check if separator is not at the very end */
|
||||
bad |= (msg_len > output_max_len);
|
||||
if (bad) {
|
||||
msg_len = msg_max_len;
|
||||
}
|
||||
|
||||
/* Verify padding bytes are non-zero in constant time */
|
||||
for (size_t i = 2; i < ilen; i++) {
|
||||
unsigned char in_padding = (i < pad_count + 2);
|
||||
unsigned char is_zero = (input[i] == 0x00);
|
||||
bad |= in_padding & is_zero;
|
||||
}
|
||||
|
||||
if (bad) {
|
||||
return MBEDTLS_ERR_RSA_INVALID_PADDING;
|
||||
}
|
||||
|
||||
*olen = msg_len;
|
||||
if (*olen > 0) {
|
||||
memcpy(output, input + ilen - msg_len, msg_len);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int esp_ds_compute_hash(mbedtls_md_type_t md_alg,
|
||||
const unsigned char *input, size_t ilen,
|
||||
unsigned char *output)
|
||||
{
|
||||
const mbedtls_md_info_t *md_info = mbedtls_md_info_from_type(md_alg);
|
||||
if (md_info == NULL) {
|
||||
return MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
|
||||
}
|
||||
return mbedtls_md(md_info, input, ilen, output);
|
||||
}
|
||||
|
||||
static int esp_ds_rsaes_pkcs1_v21_unpadding(unsigned char *input,
|
||||
size_t ilen,
|
||||
unsigned char *output,
|
||||
size_t output_max_len,
|
||||
size_t *olen)
|
||||
{
|
||||
int ret;
|
||||
unsigned int hlen = mbedtls_md_get_size_from_type(MBEDTLS_MD_SHA256);
|
||||
unsigned char bad = 0;
|
||||
size_t pad_len = 0;
|
||||
size_t msg_len = 0;
|
||||
|
||||
/* Validate input length */
|
||||
bad |= (ilen < 2 * hlen + 2);
|
||||
|
||||
/* Apply MGF masks */
|
||||
ret = esp_ds_mgf_mask(input + 1, hlen, input + hlen + 1, ilen - hlen - 1, MBEDTLS_MD_SHA256);
|
||||
if (ret != 0) {
|
||||
ESP_LOGE(TAG, "Error in MGF mask, returned %d", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = esp_ds_mgf_mask(input + hlen + 1, ilen - hlen - 1, input + 1, hlen, MBEDTLS_MD_SHA256);
|
||||
if (ret != 0) {
|
||||
ESP_LOGE(TAG, "Error in MGF mask, returned %d", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Check first byte (should be 0x00) */
|
||||
bad |= input[0];
|
||||
|
||||
/* Skip the first byte and maskSeed */
|
||||
unsigned char *db = input + 1 + hlen;
|
||||
size_t db_len = ilen - hlen - 1;
|
||||
|
||||
/* Compute hash, label is NULL and label_len is 0 */
|
||||
unsigned char lhash[MBEDTLS_MD_MAX_SIZE];
|
||||
ret = esp_ds_compute_hash(MBEDTLS_MD_SHA256, NULL, 0, lhash);
|
||||
if (ret != 0) {
|
||||
ESP_LOGE(TAG, "Error in compute_hash, returned %d", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Verify hash portion of db against lhash */
|
||||
for (size_t i = 0; i < hlen && i < db_len; i++) {
|
||||
bad |= db[i] ^ lhash[i];
|
||||
}
|
||||
|
||||
/* Skip past lhash in DB */
|
||||
unsigned char *p = db + hlen;
|
||||
size_t remaining = db_len - hlen;
|
||||
|
||||
/* Get zero-padding len, following mbedTLS pattern
|
||||
* Always read till end of buffer (minus one, for the 01 byte) */
|
||||
unsigned char in_padding = 1;
|
||||
for (size_t i = 0; i < remaining - 1; i++) {
|
||||
unsigned char is_zero = (p[i] == 0);
|
||||
in_padding = in_padding & is_zero;
|
||||
pad_len += in_padding;
|
||||
}
|
||||
|
||||
p += pad_len;
|
||||
bad |= (*p != 0x01);
|
||||
p++;
|
||||
|
||||
/* Calculate message length */
|
||||
msg_len = remaining - pad_len - 1;
|
||||
|
||||
/* Check output buffer size */
|
||||
bad |= (output_max_len < msg_len);
|
||||
|
||||
if (bad) {
|
||||
return MBEDTLS_ERR_RSA_INVALID_PADDING;
|
||||
}
|
||||
|
||||
/* Copy message in constant time */
|
||||
*olen = msg_len;
|
||||
if (*olen > 0) {
|
||||
memcpy(output, p, msg_len);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int esp_ds_rsa_decrypt(void *ctx, size_t *olen,
|
||||
const unsigned char *input, unsigned char *output,
|
||||
size_t output_max_len)
|
||||
{
|
||||
int padding = MBEDTLS_RSA_PKCS_V15;
|
||||
|
||||
if (ctx != NULL) {
|
||||
mbedtls_rsa_context *rsa_ctx = (mbedtls_rsa_context *)ctx;
|
||||
if (rsa_ctx->MBEDTLS_PRIVATE(padding) == MBEDTLS_RSA_PKCS_V15) {
|
||||
padding = MBEDTLS_RSA_PKCS_V15;
|
||||
} else if (rsa_ctx->MBEDTLS_PRIVATE(padding) == MBEDTLS_RSA_PKCS_V21) {
|
||||
padding = MBEDTLS_RSA_PKCS_V21;
|
||||
} else {
|
||||
ESP_LOGE(TAG, "Unsupported padding type %d", rsa_ctx->MBEDTLS_PRIVATE(padding));
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
size_t ilen = esp_ds_get_keylen(ctx);
|
||||
if (ilen == 0) {
|
||||
ESP_LOGE(TAG, "Invalid RSA key length");
|
||||
return -1;
|
||||
}
|
||||
size_t data_len = ilen / 4;
|
||||
|
||||
uint32_t *output_tmp = NULL;
|
||||
|
||||
uint32_t *input_tmp = calloc(data_len, sizeof(uint32_t));
|
||||
if (input_tmp == NULL) {
|
||||
ESP_LOGE(TAG, "Could not allocate memory for internal DS operations");
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (unsigned int i = 0; i < (data_len); i++) {
|
||||
input_tmp[i] = SWAP_INT32(((uint32_t *)input)[(data_len) - (i + 1)]);
|
||||
}
|
||||
|
||||
esp_ds_data_t *s_ds_data = esp_ds_get_data_ctx();
|
||||
if (s_ds_data == NULL) {
|
||||
ESP_LOGE(TAG, "s_ds_data is NULL, cannot perform decryption");
|
||||
free(input_tmp);
|
||||
return -1;
|
||||
}
|
||||
hmac_key_id_t s_esp_ds_hmac_key_id = esp_ds_get_hmac_key_id();
|
||||
|
||||
esp_ds_context_t *esp_ds_ctx = NULL;
|
||||
esp_err_t ds_r = esp_ds_start_sign((const void *)input_tmp,
|
||||
s_ds_data,
|
||||
s_esp_ds_hmac_key_id,
|
||||
&esp_ds_ctx);
|
||||
|
||||
if (ds_r != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Error in esp_ds_start_sign, returned %d ", ds_r);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
ds_r = esp_ds_finish_sign((void *)input_tmp, esp_ds_ctx);
|
||||
if (ds_r != ESP_OK) {
|
||||
if (ds_r == ESP_ERR_HW_CRYPTO_DS_INVALID_DIGEST) {
|
||||
ESP_LOGE(TAG, "Invalid digest in DS data reported by esp_ds_finish_sign");
|
||||
} else {
|
||||
ESP_LOGE(TAG, "Error in esp_ds_finish_sign, returned %d ", ds_r);
|
||||
}
|
||||
goto exit;
|
||||
}
|
||||
|
||||
esp_ds_release_ds_lock();
|
||||
|
||||
output_tmp = calloc(data_len, sizeof(uint32_t));
|
||||
if (output_tmp == NULL) {
|
||||
ESP_LOGE(TAG, "Could not allocate memory for output_tmp");
|
||||
goto exit;
|
||||
}
|
||||
|
||||
for (unsigned int i = 0; i < (data_len); i++) {
|
||||
((uint32_t *)output_tmp)[i] = SWAP_INT32(((uint32_t *)input_tmp)[(data_len) - (i + 1)]);
|
||||
}
|
||||
|
||||
// Unpad the decrypted data
|
||||
if (padding == MBEDTLS_RSA_PKCS_V15) {
|
||||
if (esp_ds_rsaes_pkcs1_v15_unpadding((uint8_t *)output_tmp, ilen, (uint8_t *)output_tmp, ilen, olen) != 0) {
|
||||
ESP_LOGE(TAG, "Error in v15 unpadding");
|
||||
goto exit;
|
||||
}
|
||||
} else if (padding == MBEDTLS_RSA_PKCS_V21) {
|
||||
if (esp_ds_rsaes_pkcs1_v21_unpadding((uint8_t *)output_tmp, ilen, (uint8_t *)output_tmp, ilen, olen) != 0) {
|
||||
ESP_LOGE(TAG, "Error in v21 unpadding");
|
||||
goto exit;
|
||||
}
|
||||
} else {
|
||||
ESP_LOGE(TAG, "Unsupported padding type %d", padding);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
// Copy the decrypted data to output buffer
|
||||
if (output_max_len < *olen) {
|
||||
ESP_LOGE(TAG, "Output buffer is too small, output_max_len: %zu, olen: %zu", output_max_len, *olen);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
memcpy(output, output_tmp, *olen);
|
||||
free(output_tmp);
|
||||
free(input_tmp);
|
||||
return 0;
|
||||
exit:
|
||||
esp_ds_release_ds_lock();
|
||||
if (input_tmp) {
|
||||
free(input_tmp);
|
||||
}
|
||||
if (output_tmp) {
|
||||
free(output_tmp);
|
||||
}
|
||||
if (olen) {
|
||||
*olen = 0; // Set olen to 0 in case of error
|
||||
}
|
||||
return -1;
|
||||
}
|
@@ -7,6 +7,7 @@
|
||||
#include "esp_ds.h"
|
||||
#include "rsa_sign_alt.h"
|
||||
#include "esp_memory_utils.h"
|
||||
#include "sdkconfig.h"
|
||||
|
||||
#ifdef CONFIG_IDF_TARGET_ESP32S2
|
||||
#include "esp32s2/rom/digital_signature.h"
|
||||
@@ -30,85 +31,14 @@
|
||||
#include "esp_heap_caps.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/semphr.h"
|
||||
#include <mbedtls/build_info.h>
|
||||
static const char *TAG = "ESP_RSA_SIGN_ALT";
|
||||
#define SWAP_INT32(x) (((x) >> 24) | (((x) & 0x00FF0000) >> 8) | (((x) & 0x0000FF00) << 8) | ((x) << 24))
|
||||
|
||||
#include "mbedtls/build_info.h"
|
||||
#include "mbedtls/rsa.h"
|
||||
#include "mbedtls/oid.h"
|
||||
#include "mbedtls/platform_util.h"
|
||||
#include "esp_ds_common.h"
|
||||
#include <string.h>
|
||||
|
||||
static hmac_key_id_t s_esp_ds_hmac_key_id;
|
||||
static esp_ds_data_t *s_ds_data;
|
||||
static SemaphoreHandle_t s_ds_lock;
|
||||
static int s_timeout_ms = 0;
|
||||
|
||||
/* key length in bytes = (esp_digital_signature_length_t key + 1 ) * FACTOR_KEYLEN_IN_BYTES */
|
||||
#define FACTOR_KEYLEN_IN_BYTES 4
|
||||
|
||||
/* 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)
|
||||
{
|
||||
if ((s_ds_lock = xSemaphoreCreateMutex()) == NULL) {
|
||||
ESP_EARLY_LOGE(TAG, "mutex for the DS session lock could not be created");
|
||||
}
|
||||
}
|
||||
|
||||
void esp_ds_set_session_timeout(int timeout)
|
||||
{
|
||||
/* add additional offset of 1000 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 > s_timeout_ms) {
|
||||
s_timeout_ms = timeout + 1000;
|
||||
}
|
||||
}
|
||||
|
||||
esp_err_t esp_ds_init_data_ctx(esp_ds_data_ctx_t *ds_data)
|
||||
{
|
||||
if (ds_data == NULL || ds_data->esp_ds_data == NULL) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
/* mutex is given back when the DS context is freed after the TLS handshake is completed or in case of failure (at cleanup) */
|
||||
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 ESP_FAIL;
|
||||
}
|
||||
s_ds_data = ds_data->esp_ds_data;
|
||||
ESP_LOGD(TAG, "Using DS with key block %u, RSA length %u", ds_data->efuse_key_id, ds_data->rsa_length_bits);
|
||||
s_esp_ds_hmac_key_id = (hmac_key_id_t) ds_data->efuse_key_id;
|
||||
|
||||
const unsigned rsa_length_int = (ds_data->rsa_length_bits / 32) - 1;
|
||||
if (esp_ptr_byte_accessible(s_ds_data)) {
|
||||
/* calculate the rsa_length in terms of esp_digital_signature_length_t which is required for the internal DS API */
|
||||
s_ds_data->rsa_length = rsa_length_int;
|
||||
} else if (s_ds_data->rsa_length != rsa_length_int) {
|
||||
/*
|
||||
* Configuration data is most likely from DROM segment and it
|
||||
* is not properly formatted for all parameters consideration.
|
||||
* Moreover, we can not modify as it is read-only and hence
|
||||
* the error.
|
||||
*/
|
||||
ESP_LOGE(TAG, "RSA length mismatch %u, %u", s_ds_data->rsa_length, rsa_length_int);
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
void esp_ds_release_ds_lock(void)
|
||||
{
|
||||
if (xSemaphoreGetMutexHolder(s_ds_lock) == xTaskGetCurrentTaskHandle()) {
|
||||
/* Give back the semaphore (DS lock) */
|
||||
xSemaphoreGive(s_ds_lock);
|
||||
}
|
||||
}
|
||||
|
||||
size_t esp_ds_get_keylen(void *ctx)
|
||||
{
|
||||
/* calculating the rsa_length in bytes */
|
||||
return ((s_ds_data->rsa_length + 1) * FACTOR_KEYLEN_IN_BYTES);
|
||||
}
|
||||
static const char *TAG = "ESP_RSA_SIGN_ALT";
|
||||
|
||||
static int rsa_rsassa_pkcs1_v15_encode( mbedtls_md_type_t md_alg,
|
||||
unsigned int hashlen,
|
||||
@@ -223,6 +153,120 @@ static int rsa_rsassa_pkcs1_v15_encode( mbedtls_md_type_t md_alg,
|
||||
return ( 0 );
|
||||
}
|
||||
|
||||
#ifdef CONFIG_MBEDTLS_SSL_PROTO_TLS1_3
|
||||
static int rsa_rsassa_pss_pkcs1_v21_encode( int (*f_rng)(void *, unsigned char *, size_t), void *p_rng,
|
||||
mbedtls_md_type_t md_alg,
|
||||
unsigned int hashlen,
|
||||
const unsigned char *hash,
|
||||
int saltlen,
|
||||
unsigned char *sig, size_t dst_len)
|
||||
{
|
||||
size_t olen;
|
||||
unsigned char *p = sig;
|
||||
unsigned char *salt = NULL;
|
||||
size_t slen, min_slen, hlen, offset = 0;
|
||||
int ret = MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
|
||||
size_t msb;
|
||||
|
||||
if ((md_alg != MBEDTLS_MD_NONE || hashlen != 0) && hash == NULL) {
|
||||
return MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
|
||||
}
|
||||
|
||||
if (f_rng == NULL) {
|
||||
return MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
|
||||
}
|
||||
|
||||
olen = dst_len;
|
||||
|
||||
if (md_alg != MBEDTLS_MD_NONE) {
|
||||
/* Gather length of hash to sign */
|
||||
size_t exp_hashlen = mbedtls_md_get_size_from_type(md_alg);
|
||||
if (exp_hashlen == 0) {
|
||||
return MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
|
||||
}
|
||||
|
||||
if (hashlen != exp_hashlen) {
|
||||
return MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
|
||||
}
|
||||
}
|
||||
|
||||
hlen = mbedtls_md_get_size_from_type(md_alg);
|
||||
if (hlen == 0) {
|
||||
return MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
|
||||
}
|
||||
|
||||
if (saltlen == MBEDTLS_RSA_SALT_LEN_ANY) {
|
||||
/* Calculate the largest possible salt length, up to the hash size.
|
||||
* Normally this is the hash length, which is the maximum salt length
|
||||
* according to FIPS 185-4 <20>5.5 (e) and common practice. If there is not
|
||||
* enough room, use the maximum salt length that fits. The constraint is
|
||||
* that the hash length plus the salt length plus 2 bytes must be at most
|
||||
* the key length. This complies with FIPS 186-4 <20>5.5 (e) and RFC 8017
|
||||
* (PKCS#1 v2.2) <20>9.1.1 step 3. */
|
||||
min_slen = hlen - 2;
|
||||
if (olen < hlen + min_slen + 2) {
|
||||
return MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
|
||||
} else if (olen >= hlen + hlen + 2) {
|
||||
slen = hlen;
|
||||
} else {
|
||||
slen = olen - hlen - 2;
|
||||
}
|
||||
} else if ((saltlen < 0) || (saltlen + hlen + 2 > olen)) {
|
||||
return MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
|
||||
} else {
|
||||
slen = (size_t) saltlen;
|
||||
}
|
||||
|
||||
memset(sig, 0, olen);
|
||||
|
||||
/* Note: EMSA-PSS encoding is over the length of N - 1 bits */
|
||||
msb = dst_len * 8 - 1;
|
||||
p += olen - hlen - slen - 2;
|
||||
*p++ = 0x01;
|
||||
|
||||
|
||||
/* Generate salt of length slen in place in the encoded message */
|
||||
salt = p;
|
||||
if ((ret = f_rng(p_rng, salt, slen)) != 0) {
|
||||
return MBEDTLS_ERR_RSA_RNG_FAILED;
|
||||
}
|
||||
p += slen;
|
||||
|
||||
/* Generate H = Hash( M' ) */
|
||||
ret = esp_ds_hash_mprime(hash, hashlen, salt, slen, p, md_alg);
|
||||
if (ret != 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Compensate for boundary condition when applying mask */
|
||||
if (msb % 8 == 0) {
|
||||
offset = 1;
|
||||
}
|
||||
|
||||
/* maskedDB: Apply dbMask to DB */
|
||||
ret = esp_ds_mgf_mask(sig + offset, olen - hlen - 1 - offset, p, hlen, md_alg);
|
||||
if (ret != 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
msb = dst_len * 8 - 1;
|
||||
sig[0] &= 0xFF >> (olen * 8 - msb);
|
||||
|
||||
p += hlen;
|
||||
*p++ = 0xBC;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int rsa_rsassa_pkcs1_v21_encode(int (*f_rng)(void *, unsigned char *, size_t), void *p_rng,
|
||||
mbedtls_md_type_t md_alg,
|
||||
unsigned int hashlen,
|
||||
const unsigned char *hash,
|
||||
size_t dst_len,
|
||||
unsigned char *dst )
|
||||
{
|
||||
return rsa_rsassa_pss_pkcs1_v21_encode(f_rng, p_rng, md_alg, hashlen, hash, MBEDTLS_RSA_SALT_LEN_ANY, dst, dst_len);
|
||||
}
|
||||
#endif /* CONFIG_MBEDTLS_SSL_PROTO_TLS1_3 */
|
||||
|
||||
int esp_ds_rsa_sign( void *ctx,
|
||||
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng,
|
||||
@@ -232,7 +276,42 @@ int esp_ds_rsa_sign( void *ctx,
|
||||
esp_ds_context_t *esp_ds_ctx;
|
||||
esp_err_t ds_r;
|
||||
int ret = -1;
|
||||
uint32_t *signature = heap_caps_malloc_prefer((s_ds_data->rsa_length + 1) * FACTOR_KEYLEN_IN_BYTES, 2, MALLOC_CAP_32BIT | MALLOC_CAP_INTERNAL, MALLOC_CAP_DEFAULT | MALLOC_CAP_INTERNAL);
|
||||
|
||||
/* This check is done to keep the compatibility with the previous versions of the API
|
||||
* which allows NULL ctx. If ctx is NULL, then the default padding
|
||||
* MBEDTLS_RSA_PKCS_V15 is used.
|
||||
*/
|
||||
int padding = MBEDTLS_RSA_PKCS_V15;
|
||||
if (ctx != NULL) {
|
||||
mbedtls_rsa_context *rsa_ctx = (mbedtls_rsa_context *)ctx;
|
||||
padding = rsa_ctx->MBEDTLS_PRIVATE(padding);
|
||||
}
|
||||
esp_ds_data_t *s_ds_data = esp_ds_get_data_ctx();
|
||||
if (s_ds_data == NULL) {
|
||||
ESP_LOGE(TAG, "Digital signature data context is NULL");
|
||||
return -1;
|
||||
}
|
||||
const size_t data_len = s_ds_data->rsa_length + 1;
|
||||
const size_t sig_len = data_len * FACTOR_KEYLEN_IN_BYTES;
|
||||
|
||||
if (padding == MBEDTLS_RSA_PKCS_V21) {
|
||||
#ifdef CONFIG_MBEDTLS_SSL_PROTO_TLS1_3
|
||||
if ((ret = (rsa_rsassa_pkcs1_v21_encode(f_rng, p_rng ,md_alg, hashlen, hash, sig_len, sig ))) != 0) {
|
||||
ESP_LOGE(TAG, "Error in pkcs1_v21 encoding, returned %d", ret);
|
||||
return -1;
|
||||
}
|
||||
#else /* CONFIG_MBEDTLS_SSL_PROTO_TLS1_3 */
|
||||
ESP_LOGE(TAG, "RSA PKCS#1 v2.1 padding is not supported. Please enable CONFIG_MBEDTLS_SSL_PROTO_TLS1_3");
|
||||
return -1;
|
||||
#endif /* CONFIG_MBEDTLS_SSL_PROTO_TLS1_3 */
|
||||
} else {
|
||||
if ((ret = (rsa_rsassa_pkcs1_v15_encode(md_alg, hashlen, hash, sig_len, sig ))) != 0) {
|
||||
ESP_LOGE(TAG, "Error in pkcs1_v15 encoding, returned %d", ret);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t *signature = heap_caps_malloc_prefer(sig_len, 2, MALLOC_CAP_32BIT | MALLOC_CAP_INTERNAL, MALLOC_CAP_DEFAULT | MALLOC_CAP_INTERNAL);
|
||||
if (signature == NULL) {
|
||||
ESP_LOGE(TAG, "Could not allocate memory for internal DS operations");
|
||||
return -1;
|
||||
@@ -248,6 +327,8 @@ int esp_ds_rsa_sign( void *ctx,
|
||||
signature[i] = SWAP_INT32(((uint32_t *)sig)[(s_ds_data->rsa_length + 1) - (i + 1)]);
|
||||
}
|
||||
|
||||
hmac_key_id_t s_esp_ds_hmac_key_id = esp_ds_get_hmac_key_id();
|
||||
|
||||
ds_r = esp_ds_start_sign((const void *)signature,
|
||||
s_ds_data,
|
||||
s_esp_ds_hmac_key_id,
|
||||
|
104
components/mbedtls/port/include/esp_ds/esp_ds_rsa.h
Normal file
104
components/mbedtls/port/include/esp_ds/esp_ds_rsa.h
Normal file
@@ -0,0 +1,104 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "esp_ds.h"
|
||||
#include "mbedtls/md.h"
|
||||
|
||||
/**
|
||||
* @brief ESP-DS data context
|
||||
*
|
||||
* @note This structure includes encrypted private key parameters such as ciphertext_c, initialization vector, efuse_key_id, RSA key length, which are obtained when DS peripheral is configured.
|
||||
*/
|
||||
|
||||
/* Context for encrypted private key data required for DS */
|
||||
typedef struct esp_ds_data_ctx {
|
||||
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;
|
||||
|
||||
/**
|
||||
* @brief Initializes internal DS data context
|
||||
*
|
||||
* This function allocates and initializes internal ds data context which is used for Digital Signature operation.
|
||||
*
|
||||
* @in ds_data ds_data context containing encrypted private key parameters
|
||||
* @return
|
||||
* - ESP_OK In case of success
|
||||
* - ESP_ERR_NO_MEM In case internal context could not be allocated.
|
||||
* - ESP_ERR_INVALID_ARG in case input parametrers are NULL
|
||||
*
|
||||
*/
|
||||
esp_err_t esp_ds_init_data_ctx(esp_ds_data_ctx_t *ds_data);
|
||||
|
||||
/**
|
||||
* @brief Deinitializes internal DS data context
|
||||
*
|
||||
* This function deinitializes internal ds data context which is used for Digital Signature operation.
|
||||
*
|
||||
* @return esp_err_t
|
||||
* - ESP_OK In case of success
|
||||
* - ESP_ERR_INVALID_STATE In case internal context is not initialized
|
||||
*/
|
||||
esp_err_t esp_ds_deinit_data_ctx(void);
|
||||
|
||||
/**
|
||||
*
|
||||
* @brief Release the ds lock acquired for the DS operation (then the DS peripheral can be used for other TLS connection)
|
||||
*
|
||||
*/
|
||||
void esp_ds_release_ds_lock(void);
|
||||
|
||||
/**
|
||||
*
|
||||
* @brief Alternate implementation for mbedtls_rsa_rsassa_pkcs1_v15_sign, Internally makes use
|
||||
* of DS module to perform hardware accelerated RSA sign operation
|
||||
*/
|
||||
int esp_ds_rsa_sign( void *ctx,
|
||||
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng,
|
||||
mbedtls_md_type_t md_alg, unsigned int hashlen,
|
||||
const unsigned char *hash, unsigned char *sig );
|
||||
|
||||
/*
|
||||
* @brief Get RSA key length in bytes from internal DS context
|
||||
*
|
||||
* @return RSA key length in bytes
|
||||
*/
|
||||
size_t esp_ds_get_keylen(void *ctx);
|
||||
|
||||
/*
|
||||
* @brief Set timeout (equal to TLS session timeout), so that DS module usage can be synchronized in case of multiple TLS connections using DS module,
|
||||
*/
|
||||
void esp_ds_set_session_timeout(int timeout);
|
||||
|
||||
/**
|
||||
* @brief Alternate implementation for mbedtls_rsa_decrypt, Internally makes use
|
||||
* of DS module to perform hardware accelerated RSA decrypt operation
|
||||
*
|
||||
* @param ctx Context for the RSA operation. It should be a pointer to an mbedtls_rsa_context structure.
|
||||
* The RSA context should have the correct padding type set (either MBEDTLS_RSA_PKCS_V15 or MBEDTLS_RSA_PKCS_V21).
|
||||
* If ctx is NULL, the default padding type (MBEDTLS_RSA_PKCS_V15) will be used.
|
||||
* @param olen Pointer to the output length variable, which will be set to the length of the decrypted data.
|
||||
* @param input The input data to be decrypted. It should be a pointer to an array of unsigned char.
|
||||
* @param output The buffer to hold the decrypted output. It should be a pointer to an array of unsigned char.
|
||||
* @param output_max_len The maximum length of the output buffer. It should be greater than or equal to the expected length of the decrypted data.
|
||||
* @return int
|
||||
* - 0 on success
|
||||
* - -1 on failure
|
||||
*/
|
||||
int esp_ds_rsa_decrypt(void *ctx, size_t *olen,
|
||||
const unsigned char *input, unsigned char *output,
|
||||
size_t output_max_len);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -36,7 +36,7 @@ typedef struct esp_ds_data_ctx {
|
||||
*
|
||||
* @in ds_data ds_data context containing encrypted private key parameters
|
||||
* @return
|
||||
* - ESP_OK In case of succees
|
||||
* - ESP_OK In case of success
|
||||
* - ESP_ERR_NO_MEM In case internal context could not be allocated.
|
||||
* - ESP_ERR_INVALID_ARG in case input parametrers are NULL
|
||||
*
|
||||
@@ -55,10 +55,10 @@ void esp_ds_release_ds_lock(void);
|
||||
* @brief Alternate implementation for mbedtls_rsa_rsassa_pkcs1_v15_sign, Internally makes use
|
||||
* of DS module to perform hardware accelerated RSA sign operation
|
||||
*/
|
||||
int esp_ds_rsa_sign( void *ctx,
|
||||
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng,
|
||||
mbedtls_md_type_t md_alg, unsigned int hashlen,
|
||||
const unsigned char *hash, unsigned char *sig );
|
||||
int esp_ds_rsa_sign(void *ctx,
|
||||
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng,
|
||||
mbedtls_md_type_t md_alg, unsigned int hashlen,
|
||||
const unsigned char *hash, unsigned char *sig);
|
||||
|
||||
/*
|
||||
* @brief Get RSA key length in bytes from internal DS context
|
||||
|
21
components/mbedtls/port/include/rsa_dec_alt.h
Normal file
21
components/mbedtls/port/include/rsa_dec_alt.h
Normal file
@@ -0,0 +1,21 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifdef __cpluscplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "sdkconfig.h"
|
||||
|
||||
#if defined(CONFIG_SOC_DIG_SIGN_SUPPORTED)
|
||||
#include "esp_ds/esp_ds_rsa.h"
|
||||
#endif
|
||||
|
||||
#ifdef __cpluscplus
|
||||
}
|
||||
#endif
|
@@ -1,28 +1,21 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2020-2022 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2020-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef _RSA_SIGN_ALT_H_
|
||||
#define _RSA_SIGN_ALT_H_
|
||||
|
||||
#ifdef __cpluscplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ESP_TLS_USE_DS_PERIPHERAL
|
||||
#include "esp_ds/esp_rsa_sign_alt.h"
|
||||
#else
|
||||
|
||||
#error "DS configuration flags not activated, please enable required menuconfig flags"
|
||||
#include "sdkconfig.h"
|
||||
|
||||
#if defined(CONFIG_SOC_DIG_SIGN_SUPPORTED)
|
||||
#include "esp_ds/esp_ds_rsa.h"
|
||||
#endif
|
||||
|
||||
#ifdef __cpluscplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
@@ -4,7 +4,6 @@ set(TEST_CRTS "crts/server_cert_chain.pem"
|
||||
"crts/bad_md_crt.pem"
|
||||
"crts/wrong_sig_crt_esp32_com.pem"
|
||||
"crts/correct_sig_crt_esp32_com.pem")
|
||||
|
||||
idf_component_register(SRC_DIRS "."
|
||||
PRIV_INCLUDE_DIRS "."
|
||||
PRIV_REQUIRES cmock test_utils mbedtls esp_timer unity spi_flash esp_psram
|
||||
@@ -16,3 +15,6 @@ target_compile_definitions(${mbedtls} INTERFACE "-DMBEDTLS_DEPRECATED_WARNING")
|
||||
target_compile_definitions(mbedtls PUBLIC "-DMBEDTLS_DEPRECATED_WARNING")
|
||||
target_compile_definitions(mbedcrypto PUBLIC "-DMBEDTLS_DEPRECATED_WARNING")
|
||||
target_compile_definitions(mbedx509 PUBLIC "-DMBEDTLS_DEPRECATED_WARNING")
|
||||
|
||||
# Add linker wrap option to override esp_ds_finish_sign
|
||||
target_link_options(${COMPONENT_LIB} INTERFACE "-Wl,--wrap=esp_ds_finish_sign,--wrap=esp_ds_start_sign")
|
||||
|
259
components/mbedtls/test_apps/main/test_ds_sign_and_decrypt.c
Normal file
259
components/mbedtls/test_apps/main/test_ds_sign_and_decrypt.c
Normal file
@@ -0,0 +1,259 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include "unity.h"
|
||||
#include "mbedtls/rsa.h"
|
||||
#include "esp_random.h"
|
||||
#include "sdkconfig.h"
|
||||
|
||||
#ifdef CONFIG_HEAP_TRACING
|
||||
#include <esp_heap_trace.h>
|
||||
#define NUM_RECORDS 100
|
||||
static heap_trace_record_t trace_record[NUM_RECORDS]; // This buffer must be in internal RAM
|
||||
#endif
|
||||
|
||||
#ifdef SOC_DIG_SIGN_SUPPORTED
|
||||
#include "soc/soc_caps.h"
|
||||
#include "esp_ds.h"
|
||||
#include "esp_ds/esp_ds_rsa.h"
|
||||
|
||||
int mbedtls_esp_random(void *ctx, unsigned char *output, size_t len)
|
||||
{
|
||||
if (len == 0 || output == NULL) {
|
||||
return -1;
|
||||
}
|
||||
esp_fill_random(output, len);
|
||||
return 0;
|
||||
}
|
||||
|
||||
TEST_CASE("ds sign test pkcs1_v15", "[ds_rsa]")
|
||||
{
|
||||
mbedtls_rsa_context rsa_ctx;
|
||||
rsa_ctx.MBEDTLS_PRIVATE(padding) = MBEDTLS_RSA_PKCS_V15;
|
||||
unsigned char hash[32] = {0};
|
||||
mbedtls_esp_random(NULL, hash, sizeof(hash)); // Fill hash with random data
|
||||
unsigned int hashlen = sizeof(hash);
|
||||
unsigned char signature[256] = {0};
|
||||
|
||||
// esp_ds is not initialized, so we expect an error
|
||||
int err = esp_ds_rsa_sign(&rsa_ctx, mbedtls_esp_random, NULL, MBEDTLS_MD_SHA256, hashlen, hash, signature);
|
||||
TEST_ASSERT_EQUAL(-1, err);
|
||||
|
||||
// Initialize the esp_ds context
|
||||
esp_ds_data_ctx_t ctx;
|
||||
esp_ds_data_t ds_data;
|
||||
ds_data.rsa_length = ESP_DS_RSA_2048; // Example length
|
||||
ctx.esp_ds_data = &ds_data;
|
||||
ctx.efuse_key_id = 1; // Example efuse key ID
|
||||
ctx.rsa_length_bits = 2048; // Example RSA length in bits
|
||||
|
||||
err = esp_ds_init_data_ctx(&ctx);
|
||||
TEST_ASSERT_EQUAL(ESP_OK, err);
|
||||
|
||||
// Now we can call esp_ds_rsa_sign again
|
||||
err = esp_ds_rsa_sign(&rsa_ctx, mbedtls_esp_random, NULL, MBEDTLS_MD_SHA256, hashlen, hash, signature);
|
||||
TEST_ASSERT_EQUAL(0, err);
|
||||
TEST_ASSERT_NOT_NULL(signature);
|
||||
|
||||
err = esp_ds_deinit_data_ctx();
|
||||
TEST_ASSERT_EQUAL(ESP_OK, err);
|
||||
|
||||
// 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 - hashlen), hashlen));
|
||||
|
||||
// Let's also ensure that signature has correct encoding
|
||||
// Just before the hash start, it should have size of hash
|
||||
TEST_ASSERT_EQUAL(hashlen, signature[256 - hashlen - 1]);
|
||||
|
||||
// One byte before should be MBEDTLS_ASN1_OCTET_STRING
|
||||
TEST_ASSERT_EQUAL(0x04, signature[256 - hashlen - 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]);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_MBEDTLS_SSL_PROTO_TLS1_3
|
||||
TEST_CASE("ds sign test pkcs1_v21", "[ds_rsa]")
|
||||
{
|
||||
mbedtls_rsa_context rsa_ctx;
|
||||
rsa_ctx.MBEDTLS_PRIVATE(padding) = MBEDTLS_RSA_PKCS_V21;
|
||||
unsigned char hash[32] = {0};
|
||||
mbedtls_esp_random(NULL, hash, sizeof(hash)); // Fill hash with random data
|
||||
unsigned int hashlen = sizeof(hash);
|
||||
unsigned char signature[256] = {0};
|
||||
|
||||
// esp_ds is not initialized, so we expect an error
|
||||
int err = esp_ds_rsa_sign(&rsa_ctx, mbedtls_esp_random, NULL, MBEDTLS_MD_SHA256, hashlen, hash, signature);
|
||||
TEST_ASSERT_EQUAL(-1, err);
|
||||
|
||||
// Initialize the esp_ds context
|
||||
esp_ds_data_ctx_t ctx;
|
||||
esp_ds_data_t ds_data;
|
||||
ds_data.rsa_length = ESP_DS_RSA_2048; // Example length
|
||||
ctx.esp_ds_data = &ds_data;
|
||||
ctx.efuse_key_id = 1; // Example efuse key ID
|
||||
ctx.rsa_length_bits = 2048; // Example RSA length in bits
|
||||
|
||||
err = esp_ds_init_data_ctx(&ctx);
|
||||
TEST_ASSERT_EQUAL(ESP_OK, err);
|
||||
|
||||
// Now we can call esp_ds_rsa_sign again
|
||||
err = esp_ds_rsa_sign(&rsa_ctx, mbedtls_esp_random, NULL, MBEDTLS_MD_SHA256, hashlen, hash, signature);
|
||||
TEST_ASSERT_EQUAL(0, err);
|
||||
TEST_ASSERT_NOT_NULL(signature);
|
||||
|
||||
err = esp_ds_deinit_data_ctx();
|
||||
TEST_ASSERT_EQUAL(ESP_OK, err);
|
||||
}
|
||||
#endif // CONFIG_MBEDTLS_SSL_PROTO_TLS1_3
|
||||
|
||||
/* Generated external data for OAEP padding */
|
||||
const unsigned char oaep_padded_v21[] = {
|
||||
0x00, 0xb6, 0xd9, 0xe6, 0x62, 0xa5, 0xa0, 0xf7, 0xc7, 0xfe, 0xb9, 0x33, 0xdd, 0xdd, 0x67, 0xd7,
|
||||
0x35, 0xa5, 0x9d, 0xf7, 0x21, 0x55, 0xf9, 0x60, 0xa8, 0x38, 0x86, 0xb2, 0x73, 0x90, 0xf5, 0x40,
|
||||
0x06, 0x85, 0x51, 0x60, 0x10, 0x01, 0x91, 0x24, 0x47, 0x2e, 0x86, 0x16, 0xa6, 0xbc, 0x35, 0x5b,
|
||||
0xe4, 0xca, 0x74, 0x9c, 0xe2, 0xe0, 0x2b, 0x2d, 0x63, 0x56, 0x0f, 0x71, 0xe0, 0x8e, 0x1c, 0xa5,
|
||||
0x58, 0x72, 0x30, 0x2f, 0x93, 0xf7, 0xd9, 0x0f, 0x16, 0xed, 0x86, 0xd3, 0xbf, 0x42, 0x12, 0x0a,
|
||||
0xaa, 0x3b, 0x16, 0x43, 0x84, 0x0d, 0x6d, 0xc8, 0xf9, 0x22, 0xc7, 0x25, 0xf6, 0x61, 0xb4, 0xb8,
|
||||
0xd7, 0x07, 0x76, 0x1a, 0xfb, 0x01, 0x01, 0xd7, 0xd2, 0x9b, 0xc1, 0xec, 0x34, 0x53, 0x14, 0x78,
|
||||
0xc4, 0x10, 0xf5, 0xf1, 0x28, 0xf6, 0x30, 0x32, 0xe7, 0x8c, 0x27, 0x62, 0x17, 0xf0, 0x47, 0x10,
|
||||
0x87, 0xfa, 0xe6, 0x02, 0x90, 0x45, 0xf9, 0x20, 0x79, 0x42, 0xf9, 0x2a, 0x42, 0x06, 0xae, 0x37,
|
||||
0xf4, 0xae, 0x12, 0x6b, 0x9c, 0x7b, 0x7e, 0xed, 0x85, 0xdf, 0xdd, 0x27, 0x27, 0xf5, 0xac, 0xb6,
|
||||
0x9c, 0x7a, 0xd9, 0x1f, 0x45, 0xd8, 0xb3, 0xed, 0x73, 0xd7, 0x9e, 0xab, 0x68, 0xb8, 0x25, 0xeb,
|
||||
0xc5, 0xcc, 0x8a, 0x04, 0x03, 0xd3, 0xd8, 0x60, 0xcc, 0xab, 0xe9, 0xd1, 0xb1, 0x18, 0x28, 0x84,
|
||||
0xf9, 0x52, 0xd6, 0xe2, 0x3c, 0x2a, 0x19, 0x5c, 0xd8, 0x73, 0xff, 0x71, 0x94, 0xd6, 0x8b, 0x5f,
|
||||
0x69, 0x09, 0x2f, 0xd2, 0xb0, 0x23, 0xda, 0x1a, 0xe4, 0x47, 0x2d, 0xb6, 0xbf, 0x08, 0xbd, 0x5d,
|
||||
0x37, 0x9c, 0x81, 0xdd, 0x54, 0x42, 0xad, 0xf7, 0x65, 0xb2, 0x8e, 0xf7, 0x70, 0x7d, 0x62, 0x0a,
|
||||
0x3a, 0x1c, 0xf5, 0xe8, 0x9f, 0x17, 0x22, 0x66, 0x3d, 0xc5, 0xab, 0xf6, 0x51, 0xe9, 0x84, 0x73,
|
||||
};
|
||||
|
||||
const unsigned char message[] = {
|
||||
0x62, 0x1c, 0xaa, 0x4a, 0xae, 0xf8, 0x1f, 0x4b, 0x59, 0x70, 0xee, 0xcb, 0x0c, 0x91, 0x35, 0xc9,
|
||||
0x4a, 0xe2, 0x85, 0xf4, 0xfc, 0x21, 0x18, 0x3e, 0xa6, 0xed, 0xa6, 0x71, 0xdb, 0xfe, 0x2b, 0x95,
|
||||
0x67, 0x45, 0xb7,
|
||||
};
|
||||
const size_t message_len = 35;
|
||||
|
||||
TEST_CASE("ds decrypt test pkcs1_v21", "[ds_rsa]")
|
||||
{
|
||||
#ifdef CONFIG_HEAP_TRACING
|
||||
heap_trace_init_standalone(trace_record, NUM_RECORDS);
|
||||
heap_trace_start(HEAP_TRACE_LEAKS);
|
||||
#endif
|
||||
mbedtls_rsa_context rsa_ctx;
|
||||
rsa_ctx.MBEDTLS_PRIVATE(padding) = MBEDTLS_RSA_PKCS_V21;
|
||||
// Initialize the esp_ds context
|
||||
esp_ds_data_ctx_t ctx;
|
||||
esp_ds_data_t ds_data;
|
||||
ds_data.rsa_length = ESP_DS_RSA_2048; // Example length
|
||||
ctx.esp_ds_data = &ds_data;
|
||||
ctx.efuse_key_id = 1; // Example efuse key ID
|
||||
ctx.rsa_length_bits = 2048; // Example RSA length in bits
|
||||
|
||||
unsigned char decrypted[256] = {0};
|
||||
size_t decrypted_len = 0;
|
||||
|
||||
// esp_ds is not initialized, so we expect an error
|
||||
int err = esp_ds_rsa_decrypt(&rsa_ctx, &decrypted_len, oaep_padded_v21, decrypted, sizeof(decrypted));
|
||||
TEST_ASSERT_EQUAL(-1, err);
|
||||
|
||||
err = esp_ds_init_data_ctx(&ctx);
|
||||
TEST_ASSERT_EQUAL(ESP_OK, err);
|
||||
|
||||
err = esp_ds_rsa_decrypt(&rsa_ctx, &decrypted_len, oaep_padded_v21, decrypted, sizeof(decrypted));
|
||||
TEST_ASSERT_EQUAL(0, err);
|
||||
TEST_ASSERT_NOT_NULL(decrypted);
|
||||
|
||||
err = esp_ds_deinit_data_ctx();
|
||||
TEST_ASSERT_EQUAL(ESP_OK, err);
|
||||
|
||||
TEST_ASSERT_EQUAL(decrypted_len, message_len);
|
||||
TEST_ASSERT_EQUAL_MEMORY(decrypted, message, message_len);
|
||||
#ifdef CONFIG_HEAP_TRACING
|
||||
heap_trace_stop();
|
||||
heap_trace_dump();
|
||||
#endif
|
||||
}
|
||||
|
||||
const unsigned char v15_padded[] = {
|
||||
0x00, 0x02, 0xdf, 0x36, 0xfc, 0x41, 0x57, 0x40, 0x87, 0x3f, 0x88, 0xa7, 0x7f, 0x7a, 0x33, 0xbe,
|
||||
0x2f, 0xf7, 0xdd, 0x8a, 0xb6, 0x6a, 0xb4, 0x6a, 0x96, 0xdb, 0x63, 0xbf, 0x50, 0xd8, 0x08, 0x5b,
|
||||
0x07, 0x9e, 0xdf, 0x4c, 0x1e, 0xb2, 0x6c, 0x83, 0x22, 0xff, 0x21, 0xc8, 0x99, 0xe1, 0x6c, 0x3d,
|
||||
0x31, 0x82, 0x8e, 0xb6, 0xb3, 0x3f, 0x77, 0xc6, 0x7d, 0xb1, 0x05, 0x97, 0xd0, 0x96, 0x49, 0x78,
|
||||
0x62, 0xd5, 0x7b, 0x5b, 0x49, 0x8c, 0xb0, 0x4e, 0x5f, 0xf2, 0x92, 0xc2, 0x9f, 0xd4, 0x77, 0x0a,
|
||||
0x77, 0x94, 0x9f, 0x80, 0xff, 0xde, 0x6a, 0xe7, 0x62, 0x36, 0x9f, 0x73, 0x78, 0xb3, 0xc0, 0x2f,
|
||||
0xd8, 0xf9, 0x06, 0x60, 0x78, 0xbc, 0x50, 0x06, 0x0d, 0x33, 0x6c, 0x5f, 0xcc, 0x4d, 0x40, 0x4e,
|
||||
0x12, 0x53, 0x39, 0x3b, 0x24, 0x4f, 0x9c, 0x14, 0x20, 0xbd, 0x71, 0x1d, 0xdc, 0xc5, 0xbc, 0x88,
|
||||
0xd1, 0x87, 0x4a, 0xac, 0x21, 0xb6, 0x06, 0x9d, 0x56, 0xe5, 0xb7, 0x05, 0x61, 0x32, 0x30, 0x97,
|
||||
0x7d, 0x72, 0x2f, 0x45, 0xf0, 0xc6, 0x55, 0x01, 0x87, 0x78, 0xbc, 0xa4, 0x9b, 0x4f, 0xe1, 0xc5,
|
||||
0x59, 0x8a, 0xaa, 0x3c, 0xd1, 0x0a, 0xe3, 0xbe, 0x0b, 0xde, 0x21, 0xa8, 0x3b, 0x89, 0x9f, 0x0a,
|
||||
0x30, 0x22, 0x64, 0x4e, 0x90, 0x71, 0x52, 0x27, 0x23, 0x7b, 0xe7, 0x0b, 0x07, 0xa9, 0x7e, 0x15,
|
||||
0xb1, 0xfe, 0x0e, 0x0e, 0x1b, 0x8e, 0xc3, 0xf0, 0x26, 0x66, 0xfb, 0xdf, 0x78, 0xf8, 0x03, 0xd5,
|
||||
0xf5, 0x90, 0x08, 0x04, 0x7c, 0x9f, 0x11, 0xa5, 0x5e, 0x5b, 0x2b, 0x01, 0x00, 0x62, 0x1c, 0xaa,
|
||||
0x4a, 0xae, 0xf8, 0x1f, 0x4b, 0x59, 0x70, 0xee, 0xcb, 0x0c, 0x91, 0x35, 0xc9, 0x4a, 0xe2, 0x85,
|
||||
0xf4, 0xfc, 0x21, 0x18, 0x3e, 0xa6, 0xed, 0xa6, 0x71, 0xdb, 0xfe, 0x2b, 0x95, 0x67, 0x45, 0xb7,
|
||||
};
|
||||
|
||||
TEST_CASE("ds decrypt test pkcs1_v15", "[ds_rsa]")
|
||||
{
|
||||
mbedtls_rsa_context rsa_ctx;
|
||||
rsa_ctx.MBEDTLS_PRIVATE(padding) = MBEDTLS_RSA_PKCS_V15;
|
||||
// Initialize the esp_ds context
|
||||
esp_ds_data_ctx_t ctx;
|
||||
esp_ds_data_t ds_data;
|
||||
ds_data.rsa_length = ESP_DS_RSA_2048; // Example length
|
||||
ctx.esp_ds_data = &ds_data;
|
||||
ctx.efuse_key_id = 1; // Example efuse key ID
|
||||
ctx.rsa_length_bits = 2048; // Example RSA length in bits
|
||||
|
||||
int err = esp_ds_init_data_ctx(&ctx);
|
||||
TEST_ASSERT_EQUAL(ESP_OK, err);
|
||||
|
||||
unsigned char decrypted[256] = {0};
|
||||
size_t decrypted_len = 0;
|
||||
err = esp_ds_rsa_decrypt(&rsa_ctx, &decrypted_len, v15_padded, decrypted, sizeof(decrypted));
|
||||
TEST_ASSERT_EQUAL(0, err);
|
||||
TEST_ASSERT_NOT_NULL(decrypted);
|
||||
|
||||
err = esp_ds_deinit_data_ctx();
|
||||
TEST_ASSERT_EQUAL(ESP_OK, err);
|
||||
|
||||
TEST_ASSERT_EQUAL(decrypted_len, message_len);
|
||||
TEST_ASSERT_EQUAL_MEMORY(decrypted, message, message_len);
|
||||
}
|
||||
|
||||
int __wrap_esp_ds_start_sign(const void *message, const esp_ds_data_t *data, hmac_key_id_t key_id, esp_ds_context_t **esp_ds_ctx)
|
||||
{
|
||||
// This function will be called instead of the original esp_ds_start_sign
|
||||
if (message == NULL || data == NULL || esp_ds_ctx == NULL) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
*esp_ds_ctx = malloc(sizeof(void *));
|
||||
if (*esp_ds_ctx == NULL) {
|
||||
return ESP_ERR_NO_MEM;
|
||||
}
|
||||
|
||||
// Simulate successful start sign
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
// Test implementation using linker wrap
|
||||
int __wrap_esp_ds_finish_sign(void *sig, esp_ds_context_t *ctx)
|
||||
{
|
||||
// This function will be called instead of the original esp_ds_finish_sign
|
||||
free(ctx);
|
||||
return 0;
|
||||
|
||||
// Or we can call the real implementation if needed:
|
||||
// return __real_esp_ds_finish_sign(sig, ctx);
|
||||
}
|
||||
#endif /* SOC_DIG_SIGN_SUPPORTED */
|
@@ -90,3 +90,16 @@ def test_mbedtls_ecdsa_sign(dut: Dut) -> None:
|
||||
)
|
||||
def test_mbedtls_rom_impl_esp32c2(dut: Dut) -> None:
|
||||
dut.run_all_single_board_cases()
|
||||
|
||||
|
||||
@pytest.mark.esp32s3
|
||||
@pytest.mark.generic
|
||||
@pytest.mark.parametrize(
|
||||
'config',
|
||||
[
|
||||
'ds_rsa',
|
||||
],
|
||||
indirect=True,
|
||||
)
|
||||
def test_mbedtls_ds_rsa(dut: Dut) -> None:
|
||||
dut.run_all_single_board_cases(group='ds_rsa')
|
||||
|
1
components/mbedtls/test_apps/sdkconfig.ci.ds_rsa
Normal file
1
components/mbedtls/test_apps/sdkconfig.ci.ds_rsa
Normal file
@@ -0,0 +1 @@
|
||||
CONFIG_MBEDTLS_SSL_PROTO_TLS1_3=y
|
Reference in New Issue
Block a user