mirror of
https://github.com/Mbed-TLS/mbedtls.git
synced 2026-07-30 16:26:33 +08:00
Add async TLS 1.3 key exchange and AEAD record support
Signed-off-by: Cal Abel <crabel@mac.com>
This commit is contained in:
parent
c7948dfd41
commit
43e1bed40c
@ -789,6 +789,7 @@ struct mbedtls_ssl_handshake_params {
|
||||
size_t xxdh_psa_peerkey_len;
|
||||
#if defined(MBEDTLS_SSL_ECP_RESTARTABLE_ENABLED)
|
||||
psa_key_agreement_iop_t xxdh_psa_iop;
|
||||
uint8_t xxdh_psa_iop_active;
|
||||
#endif
|
||||
#endif /* MBEDTLS_KEY_EXCHANGE_SOME_XXDH_PSA_ANY_ENABLED */
|
||||
|
||||
@ -1763,6 +1764,16 @@ int mbedtls_ssl_get_key_exchange_md_tls1_2(mbedtls_ssl_context *ssl,
|
||||
#endif
|
||||
|
||||
void mbedtls_ssl_transform_init(mbedtls_ssl_transform *transform);
|
||||
#if defined(MBEDTLS_ASYNC_HARDWARE_AEAD)
|
||||
MBEDTLS_CHECK_RETURN_CRITICAL
|
||||
int mbedtls_ssl_configure_async_aead_transform(
|
||||
mbedtls_ssl_transform *transform,
|
||||
psa_key_type_t key_type,
|
||||
psa_algorithm_t alg,
|
||||
const unsigned char *key_enc,
|
||||
const unsigned char *key_dec,
|
||||
size_t key_len);
|
||||
#endif
|
||||
MBEDTLS_CHECK_RETURN_CRITICAL
|
||||
int mbedtls_ssl_encrypt_buf(mbedtls_ssl_context *ssl,
|
||||
mbedtls_ssl_transform *transform,
|
||||
|
||||
@ -98,6 +98,61 @@ static int samd_mbedtls_ssl_transform_has_aead(
|
||||
sizeof(transform->samd_aead_key_enc) &&
|
||||
transform->ivlen == 12;
|
||||
}
|
||||
|
||||
int mbedtls_ssl_configure_async_aead_transform(
|
||||
mbedtls_ssl_transform *transform,
|
||||
psa_key_type_t key_type,
|
||||
psa_algorithm_t alg,
|
||||
const unsigned char *key_enc,
|
||||
const unsigned char *key_dec,
|
||||
size_t key_len)
|
||||
{
|
||||
unsigned char async_algorithm = 0;
|
||||
|
||||
if (transform == NULL || key_enc == NULL || key_dec == NULL ||
|
||||
key_len == 0 || key_len > sizeof(transform->samd_aead_key_enc) ||
|
||||
transform->ivlen != 12 || transform->taglen != 16) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (key_type == PSA_KEY_TYPE_AES && alg == PSA_ALG_GCM) {
|
||||
if (key_len == 16) {
|
||||
async_algorithm = MBEDTLS_ASYNC_HARDWARE_TLS_AEAD_AES_128_GCM;
|
||||
} else if (key_len == 32) {
|
||||
async_algorithm = MBEDTLS_ASYNC_HARDWARE_TLS_AEAD_AES_256_GCM;
|
||||
}
|
||||
} else if (key_type == PSA_KEY_TYPE_CHACHA20 &&
|
||||
alg == PSA_ALG_CHACHA20_POLY1305 && key_len == 32) {
|
||||
async_algorithm = MBEDTLS_ASYNC_HARDWARE_TLS_AEAD_CHACHA20_POLY1305;
|
||||
}
|
||||
|
||||
if (async_algorithm == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_SSL_PROTO_TLS1_3)
|
||||
if (transform->tls_version == MBEDTLS_SSL_VERSION_TLS1_3) {
|
||||
if (transform->fixed_ivlen != 12) {
|
||||
return 0;
|
||||
}
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
if (transform->fixed_ivlen != 4 &&
|
||||
!(key_type == PSA_KEY_TYPE_CHACHA20 &&
|
||||
alg == PSA_ALG_CHACHA20_POLY1305 &&
|
||||
transform->fixed_ivlen == 12)) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
memcpy(transform->samd_aead_key_enc, key_enc, key_len);
|
||||
memcpy(transform->samd_aead_key_dec, key_dec, key_len);
|
||||
transform->samd_aead_key_len = key_len;
|
||||
transform->samd_aead_algorithm = async_algorithm;
|
||||
transform->samd_aead_keys_configured = 1;
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_SSL_SOME_SUITES_USE_MAC)
|
||||
@ -4881,7 +4936,9 @@ static int ssl_get_next_record(mbedtls_ssl_context *ssl)
|
||||
if (ssl->transform_in != NULL &&
|
||||
ssl->transform_in->samd_aead_pending != 0) {
|
||||
const size_t header_len = mbedtls_ssl_in_hdr_len(ssl);
|
||||
const size_t explicit_iv_len = sizeof(rec.ctr);
|
||||
const size_t explicit_iv_len =
|
||||
ssl_transform_aead_dynamic_iv_is_explicit(ssl->transform_in) ?
|
||||
sizeof(rec.ctr) : 0;
|
||||
const size_t record_len = MBEDTLS_GET_UINT16_BE(ssl->in_len, 0);
|
||||
|
||||
if (record_len < explicit_iv_len + ssl->transform_in->taglen) {
|
||||
|
||||
@ -1012,6 +1012,12 @@ int mbedtls_ssl_tls13_populate_transform(
|
||||
|
||||
transform->psa_alg = alg;
|
||||
|
||||
#if defined(MBEDTLS_ASYNC_HARDWARE_AEAD)
|
||||
int async_aead_configured = mbedtls_ssl_configure_async_aead_transform(
|
||||
transform, key_type, alg, key_enc, key_dec, PSA_BITS_TO_BYTES(key_bits));
|
||||
(void) async_aead_configured;
|
||||
#endif
|
||||
|
||||
if (alg != MBEDTLS_SSL_NULL_CIPHER) {
|
||||
psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_ENCRYPT);
|
||||
psa_set_key_algorithm(&attributes, alg);
|
||||
@ -1440,11 +1446,16 @@ static int ssl_tls13_key_schedule_stage_handshake(mbedtls_ssl_context *ssl)
|
||||
/* Compute ECDH shared secret. */
|
||||
psa_status_t status = PSA_ERROR_GENERIC_ERROR;
|
||||
psa_key_attributes_t key_attributes = PSA_KEY_ATTRIBUTES_INIT;
|
||||
mbedtls_svc_key_id_t shared_secret_key = MBEDTLS_SVC_KEY_ID_INIT;
|
||||
psa_status_t shared_secret_key_destruction_status =
|
||||
PSA_ERROR_GENERIC_ERROR;
|
||||
|
||||
status = psa_get_key_attributes(handshake->xxdh_psa_privkey,
|
||||
&key_attributes);
|
||||
if (status != PSA_SUCCESS) {
|
||||
ret = PSA_TO_MBEDTLS_ERR(status);
|
||||
MBEDTLS_SSL_DEBUG_RET(1, "psa_get_key_attributes", ret);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
shared_secret_len = PSA_BITS_TO_BYTES(
|
||||
@ -1454,6 +1465,70 @@ static int ssl_tls13_key_schedule_stage_handshake(mbedtls_ssl_context *ssl)
|
||||
return MBEDTLS_ERR_SSL_ALLOC_FAILED;
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_ASYNC_HARDWARE_ECDH) && \
|
||||
defined(MBEDTLS_SSL_ECP_RESTARTABLE_ENABLED)
|
||||
if (handshake->xxdh_psa_iop_active == 0) {
|
||||
psa_key_attributes_t secret_attributes =
|
||||
psa_key_attributes_init();
|
||||
psa_set_key_usage_flags(&secret_attributes,
|
||||
PSA_KEY_USAGE_EXPORT);
|
||||
psa_set_key_type(&secret_attributes, PSA_KEY_TYPE_RAW_DATA);
|
||||
psa_set_key_bits(&secret_attributes,
|
||||
PSA_BYTES_TO_BITS(shared_secret_len));
|
||||
|
||||
status = psa_key_agreement_iop_setup(
|
||||
&handshake->xxdh_psa_iop,
|
||||
handshake->xxdh_psa_privkey,
|
||||
handshake->xxdh_psa_peerkey,
|
||||
handshake->xxdh_psa_peerkey_len,
|
||||
alg,
|
||||
&secret_attributes);
|
||||
if (status != PSA_SUCCESS) {
|
||||
(void) psa_key_agreement_iop_abort(
|
||||
&handshake->xxdh_psa_iop);
|
||||
ret = PSA_TO_MBEDTLS_ERR(status);
|
||||
MBEDTLS_SSL_DEBUG_RET(1, "psa_key_agreement_iop_setup",
|
||||
ret);
|
||||
goto cleanup;
|
||||
}
|
||||
handshake->xxdh_psa_iop_active = 1;
|
||||
}
|
||||
|
||||
status = psa_key_agreement_iop_complete(
|
||||
&handshake->xxdh_psa_iop,
|
||||
&shared_secret_key);
|
||||
if (status == PSA_OPERATION_INCOMPLETE) {
|
||||
mbedtls_free(shared_secret);
|
||||
return MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS;
|
||||
}
|
||||
|
||||
(void) psa_key_agreement_iop_abort(&handshake->xxdh_psa_iop);
|
||||
handshake->xxdh_psa_iop_active = 0;
|
||||
|
||||
if (status != PSA_SUCCESS) {
|
||||
ret = PSA_TO_MBEDTLS_ERR(status);
|
||||
MBEDTLS_SSL_DEBUG_RET(1, "psa_key_agreement_iop_complete",
|
||||
ret);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
status = psa_export_key(shared_secret_key,
|
||||
shared_secret,
|
||||
shared_secret_len,
|
||||
&shared_secret_len);
|
||||
shared_secret_key_destruction_status =
|
||||
psa_destroy_key(shared_secret_key);
|
||||
if (status != PSA_SUCCESS) {
|
||||
ret = PSA_TO_MBEDTLS_ERR(status);
|
||||
MBEDTLS_SSL_DEBUG_RET(1, "psa_export_key", ret);
|
||||
goto cleanup;
|
||||
}
|
||||
if (shared_secret_key_destruction_status != PSA_SUCCESS) {
|
||||
ret = PSA_TO_MBEDTLS_ERR(shared_secret_key_destruction_status);
|
||||
MBEDTLS_SSL_DEBUG_RET(1, "psa_destroy_key", ret);
|
||||
goto cleanup;
|
||||
}
|
||||
#else
|
||||
status = psa_raw_key_agreement(
|
||||
alg, handshake->xxdh_psa_privkey,
|
||||
handshake->xxdh_psa_peerkey, handshake->xxdh_psa_peerkey_len,
|
||||
@ -1463,6 +1538,7 @@ static int ssl_tls13_key_schedule_stage_handshake(mbedtls_ssl_context *ssl)
|
||||
MBEDTLS_SSL_DEBUG_RET(1, "psa_raw_key_agreement", ret);
|
||||
goto cleanup;
|
||||
}
|
||||
#endif
|
||||
|
||||
status = psa_destroy_key(handshake->xxdh_psa_privkey);
|
||||
if (status != PSA_SUCCESS) {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user