mirror of
https://github.com/espressif/esp-idf.git
synced 2026-09-22 13:01:16 +03:00
fix(esp-tls): fixes DS peripheral use case with tf-psa-crypto 1.1
This commit is contained in:
@@ -495,36 +495,17 @@ void esp_mbedtls_cleanup(esp_tls_t *tls)
|
|||||||
|
|
||||||
/* For opaque keys (DS peripheral, hardware ECDSA), mbedtls_pk_free() does
|
/* For opaque keys (DS peripheral, hardware ECDSA), mbedtls_pk_free() does
|
||||||
* not destroy the PSA key — ownership is external. Destroy it manually
|
* not destroy the PSA key — ownership is external. Destroy it manually
|
||||||
* before calling mbedtls_pk_free(). */
|
* before calling mbedtls_pk_free(). mbedtls_pk_wrap_psa() sets the pk_info
|
||||||
#ifdef CONFIG_ESP_TLS_USE_DS_PERIPHERAL
|
* to mbedtls_{rsa,ecdsa}_opaque_info, both of which have type
|
||||||
if (mbedtls_pk_get_type(&tls->clientkey) == MBEDTLS_PK_RSASSA_PSS) {
|
* MBEDTLS_PK_OPAQUE — so a single check covers both DS and ECDSA paths.
|
||||||
|
* clientkey and serverkey share storage via union, so one branch suffices. */
|
||||||
|
#if defined(CONFIG_ESP_TLS_USE_DS_PERIPHERAL) || defined(CONFIG_MBEDTLS_HARDWARE_ECDSA_SIGN)
|
||||||
|
if (mbedtls_pk_get_type(&tls->clientkey) == MBEDTLS_PK_OPAQUE) {
|
||||||
if (tls->clientkey.MBEDTLS_PRIVATE(priv_id) != PSA_KEY_ID_NULL) {
|
if (tls->clientkey.MBEDTLS_PRIVATE(priv_id) != PSA_KEY_ID_NULL) {
|
||||||
psa_destroy_key(tls->clientkey.MBEDTLS_PRIVATE(priv_id));
|
psa_destroy_key(tls->clientkey.MBEDTLS_PRIVATE(priv_id));
|
||||||
tls->clientkey.MBEDTLS_PRIVATE(priv_id) = PSA_KEY_ID_NULL;
|
tls->clientkey.MBEDTLS_PRIVATE(priv_id) = PSA_KEY_ID_NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (mbedtls_pk_get_type(&tls->serverkey) == MBEDTLS_PK_RSASSA_PSS) {
|
|
||||||
if (tls->serverkey.MBEDTLS_PRIVATE(priv_id) != PSA_KEY_ID_NULL) {
|
|
||||||
psa_destroy_key(tls->serverkey.MBEDTLS_PRIVATE(priv_id));
|
|
||||||
tls->serverkey.MBEDTLS_PRIVATE(priv_id) = PSA_KEY_ID_NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef CONFIG_MBEDTLS_HARDWARE_ECDSA_SIGN
|
|
||||||
if (mbedtls_pk_get_type(&tls->clientkey) == MBEDTLS_PK_ECDSA) {
|
|
||||||
ESP_LOGD(TAG, "Cleaning up client key");
|
|
||||||
if (tls->clientkey.MBEDTLS_PRIVATE(priv_id) != PSA_KEY_ID_NULL) {
|
|
||||||
psa_destroy_key(tls->clientkey.MBEDTLS_PRIVATE(priv_id));
|
|
||||||
tls->clientkey.MBEDTLS_PRIVATE(priv_id) = PSA_KEY_ID_NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (mbedtls_pk_get_type(&tls->serverkey) == MBEDTLS_PK_ECDSA) {
|
|
||||||
if (tls->serverkey.MBEDTLS_PRIVATE(priv_id) != PSA_KEY_ID_NULL) {
|
|
||||||
psa_destroy_key(tls->serverkey.MBEDTLS_PRIVATE(priv_id));
|
|
||||||
tls->serverkey.MBEDTLS_PRIVATE(priv_id) = PSA_KEY_ID_NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
mbedtls_pk_free(&tls->clientkey);
|
mbedtls_pk_free(&tls->clientkey);
|
||||||
@@ -624,6 +605,7 @@ static esp_err_t set_pki_context(esp_tls_t *tls, const esp_tls_pki_t *pki)
|
|||||||
|
|
||||||
// Import opaque key reference
|
// Import opaque key reference
|
||||||
psa_status_t status = psa_import_key(&key_attr, (uint8_t*) &opaque_key, sizeof(opaque_key), &priv_key_id);
|
psa_status_t status = psa_import_key(&key_attr, (uint8_t*) &opaque_key, sizeof(opaque_key), &priv_key_id);
|
||||||
|
psa_reset_key_attributes(&key_attr);
|
||||||
if (status != PSA_SUCCESS) {
|
if (status != PSA_SUCCESS) {
|
||||||
ESP_LOGE(TAG, "Failed to import opaque key reference");
|
ESP_LOGE(TAG, "Failed to import opaque key reference");
|
||||||
return ESP_ERR_MBEDTLS_PK_PARSE_KEY_FAILED;
|
return ESP_ERR_MBEDTLS_PK_PARSE_KEY_FAILED;
|
||||||
@@ -632,10 +614,9 @@ static esp_err_t set_pki_context(esp_tls_t *tls, const esp_tls_pki_t *pki)
|
|||||||
ret = mbedtls_pk_wrap_psa(pki->pk_key, priv_key_id);
|
ret = mbedtls_pk_wrap_psa(pki->pk_key, priv_key_id);
|
||||||
if (ret != 0) {
|
if (ret != 0) {
|
||||||
ESP_LOGE(TAG, "Failed to wrap opaque key reference");
|
ESP_LOGE(TAG, "Failed to wrap opaque key reference");
|
||||||
|
psa_destroy_key(priv_key_id);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
psa_reset_key_attributes(&key_attr);
|
|
||||||
} else
|
} else
|
||||||
#endif
|
#endif
|
||||||
if (pki->privkey_pem_buf != NULL) {
|
if (pki->privkey_pem_buf != NULL) {
|
||||||
@@ -1384,46 +1365,73 @@ static esp_err_t esp_set_atecc608a_pki_context(esp_tls_t *tls, const void *pki)
|
|||||||
#endif /* CONFIG_ESP_TLS_USE_SECURE_ELEMENT */
|
#endif /* CONFIG_ESP_TLS_USE_SECURE_ELEMENT */
|
||||||
|
|
||||||
#ifdef CONFIG_ESP_TLS_USE_DS_PERIPHERAL
|
#ifdef CONFIG_ESP_TLS_USE_DS_PERIPHERAL
|
||||||
|
/*
|
||||||
|
* tf-psa-crypto 1.1 made mbedtls_pk_wrap_psa() call psa_export_public_key() on
|
||||||
|
* the imported PSA key. The DS peripheral cannot expose any key material
|
||||||
|
* (private or public), so the export fails with PK_INVALID_ALG. Copy the
|
||||||
|
* already-parsed raw public key from the device certificate so wrap_psa()'s
|
||||||
|
* export step short-circuits (pk.c:145-148, returns early when pub_raw_len>0).
|
||||||
|
*/
|
||||||
|
static esp_err_t inject_rsa_pubkey_from_cert(mbedtls_pk_context *dst, const mbedtls_x509_crt *cert)
|
||||||
|
{
|
||||||
|
const mbedtls_pk_context *src = &cert->pk;
|
||||||
|
size_t src_len = src->MBEDTLS_PRIVATE(pub_raw_len);
|
||||||
|
if (src_len == 0 || src_len > sizeof(dst->MBEDTLS_PRIVATE(pub_raw))) {
|
||||||
|
ESP_LOGE(TAG, "Invalid cert pubkey length: %zu", src_len);
|
||||||
|
return ESP_ERR_INVALID_STATE;
|
||||||
|
}
|
||||||
|
memcpy(dst->MBEDTLS_PRIVATE(pub_raw), src->MBEDTLS_PRIVATE(pub_raw), src_len);
|
||||||
|
dst->MBEDTLS_PRIVATE(pub_raw_len) = src_len;
|
||||||
|
dst->MBEDTLS_PRIVATE(bits) = src->MBEDTLS_PRIVATE(bits);
|
||||||
|
dst->MBEDTLS_PRIVATE(psa_type) = PSA_KEY_TYPE_RSA_PUBLIC_KEY;
|
||||||
|
return ESP_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static psa_status_t import_ds_key(const esp_ds_data_ctx_t *ds_data, psa_key_id_t *out_key_id)
|
||||||
|
{
|
||||||
|
esp_rsa_ds_opaque_key_t rsa_ds_opaque_key = {0};
|
||||||
|
rsa_ds_opaque_key.ds_data_ctx = (esp_ds_data_ctx_t *)ds_data;
|
||||||
|
|
||||||
|
psa_key_attributes_t attrs = PSA_KEY_ATTRIBUTES_INIT;
|
||||||
|
psa_set_key_type(&attrs, PSA_KEY_TYPE_RSA_KEY_PAIR);
|
||||||
|
psa_set_key_bits(&attrs, ds_data->rsa_length_bits);
|
||||||
|
psa_set_key_usage_flags(&attrs, PSA_KEY_USAGE_SIGN_HASH);
|
||||||
|
psa_set_key_algorithm(&attrs, PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_ANY_HASH));
|
||||||
|
#ifdef CONFIG_MBEDTLS_SSL_PROTO_TLS1_3
|
||||||
|
psa_set_key_enrollment_algorithm(&attrs, PSA_ALG_RSA_PSS(PSA_ALG_ANY_HASH));
|
||||||
|
#endif
|
||||||
|
psa_set_key_lifetime(&attrs, PSA_KEY_LIFETIME_ESP_RSA_DS_VOLATILE);
|
||||||
|
|
||||||
|
psa_status_t status = psa_import_key(&attrs,
|
||||||
|
(const uint8_t *)&rsa_ds_opaque_key,
|
||||||
|
sizeof(rsa_ds_opaque_key),
|
||||||
|
out_key_id);
|
||||||
|
psa_reset_key_attributes(&attrs);
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
static esp_err_t esp_mbedtls_init_pk_ctx_for_ds(const void *pki)
|
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;
|
const esp_tls_pki_t *pki_l = (const esp_tls_pki_t *)pki;
|
||||||
if (ds_data == NULL) {
|
if (pki_l->esp_ds_data == NULL || pki_l->pk_key == NULL || pki_l->public_cert == NULL) {
|
||||||
ESP_LOGE(TAG, "DS data context is NULL");
|
ESP_LOGE(TAG, "DS pki context missing required fields");
|
||||||
return ESP_ERR_INVALID_ARG;
|
|
||||||
}
|
|
||||||
|
|
||||||
esp_tls_pki_t *pki_l = (esp_tls_pki_t *) pki;
|
|
||||||
if (pki_l->pk_key == NULL) {
|
|
||||||
ESP_LOGE(TAG, "PK key context is NULL");
|
|
||||||
return ESP_ERR_INVALID_ARG;
|
return ESP_ERR_INVALID_ARG;
|
||||||
}
|
}
|
||||||
|
|
||||||
psa_key_id_t ds_key_id = 0;
|
psa_key_id_t ds_key_id = 0;
|
||||||
psa_status_t status = PSA_ERROR_GENERIC_ERROR;
|
psa_status_t status = import_ds_key(pki_l->esp_ds_data, &ds_key_id);
|
||||||
|
|
||||||
esp_rsa_ds_opaque_key_t rsa_ds_opaque_key = {0};
|
|
||||||
rsa_ds_opaque_key.ds_data_ctx = ds_data;
|
|
||||||
|
|
||||||
psa_key_attributes_t ds_key_attributes = PSA_KEY_ATTRIBUTES_INIT;
|
|
||||||
psa_algorithm_t alg = PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_ANY_HASH);
|
|
||||||
#ifdef CONFIG_MBEDTLS_SSL_PROTO_TLS1_3
|
|
||||||
psa_set_key_enrollment_algorithm(&ds_key_attributes, PSA_ALG_RSA_PSS(PSA_ALG_ANY_HASH));
|
|
||||||
#endif /* CONFIG_MBEDTLS_SSL_PROTO_TLS1_3 */
|
|
||||||
|
|
||||||
psa_set_key_type(&ds_key_attributes, PSA_KEY_TYPE_RSA_KEY_PAIR);
|
|
||||||
psa_set_key_bits(&ds_key_attributes, rsa_ds_opaque_key.ds_data_ctx->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_RSA_DS_VOLATILE);
|
|
||||||
status = psa_import_key(&ds_key_attributes,
|
|
||||||
(const uint8_t *)&rsa_ds_opaque_key,
|
|
||||||
sizeof(rsa_ds_opaque_key),
|
|
||||||
&ds_key_id);
|
|
||||||
psa_reset_key_attributes(&ds_key_attributes);
|
|
||||||
if (status != PSA_SUCCESS) {
|
if (status != PSA_SUCCESS) {
|
||||||
ESP_LOGE(TAG, "Failed to import DS key to PSA, status = %d", status);
|
ESP_LOGE(TAG, "Failed to import DS key to PSA, status = %d", status);
|
||||||
return ESP_ERR_INVALID_STATE;
|
return ESP_ERR_INVALID_STATE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Pre-populate pub_raw so wrap_psa() does not attempt to export it. */
|
||||||
|
esp_err_t esp_ret = inject_rsa_pubkey_from_cert(pki_l->pk_key, pki_l->public_cert);
|
||||||
|
if (esp_ret != ESP_OK) {
|
||||||
|
psa_destroy_key(ds_key_id);
|
||||||
|
return esp_ret;
|
||||||
|
}
|
||||||
|
|
||||||
int ret = mbedtls_pk_wrap_psa(pki_l->pk_key, ds_key_id);
|
int ret = mbedtls_pk_wrap_psa(pki_l->pk_key, ds_key_id);
|
||||||
if (ret != 0) {
|
if (ret != 0) {
|
||||||
ESP_LOGE(TAG, "mbedtls_pk_wrap_psa failed with -0x%04X", -ret);
|
ESP_LOGE(TAG, "mbedtls_pk_wrap_psa failed with -0x%04X", -ret);
|
||||||
|
|||||||
Reference in New Issue
Block a user