mirror of
https://github.com/Mbed-TLS/mbedtls.git
synced 2025-07-29 11:41:15 +03:00
Merge remote-tracking branch 'development' into pk_import_into_psa-implement_import
Conflicts: * tests/suites/test_suite_pk.function: consecutive changes to the depends_on line of pk_sign_verify and its argument list.
This commit is contained in:
@ -334,7 +334,7 @@ static void aesce_setkey_enc(unsigned char *rk,
|
||||
* - Section 5, Nr = Nk + 6
|
||||
* - Section 5.2, the length of round keys is Nb*(Nr+1)
|
||||
*/
|
||||
const uint32_t key_len_in_words = key_bit_length / 32; /* Nk */
|
||||
const size_t key_len_in_words = key_bit_length / 32; /* Nk */
|
||||
const size_t round_key_len_in_words = 4; /* Nb */
|
||||
const size_t rounds_needed = key_len_in_words + 6; /* Nr */
|
||||
const size_t round_keys_len_in_words =
|
||||
|
@ -65,7 +65,8 @@ static int local_err_translation(psa_status_t status)
|
||||
#define H_TREE_HEIGHT_MAX 10
|
||||
#define MERKLE_TREE_NODE_AM(type) ((size_t) 1 << (MBEDTLS_LMS_H_TREE_HEIGHT(type) + 1u))
|
||||
#define MERKLE_TREE_LEAF_NODE_AM(type) ((size_t) 1 << MBEDTLS_LMS_H_TREE_HEIGHT(type))
|
||||
#define MERKLE_TREE_INTERNAL_NODE_AM(type) ((size_t) 1 << MBEDTLS_LMS_H_TREE_HEIGHT(type))
|
||||
#define MERKLE_TREE_INTERNAL_NODE_AM(type) ((unsigned int) \
|
||||
(1u << MBEDTLS_LMS_H_TREE_HEIGHT(type)))
|
||||
|
||||
#define D_CONST_LEN (2)
|
||||
static const unsigned char D_LEAF_CONSTANT_BYTES[D_CONST_LEN] = { 0x82, 0x82 };
|
||||
|
@ -683,6 +683,18 @@ static const oid_cipher_alg_t oid_cipher_alg[] =
|
||||
OID_DESCRIPTOR(MBEDTLS_OID_DES_EDE3_CBC, "des-ede3-cbc", "DES-EDE3-CBC"),
|
||||
MBEDTLS_CIPHER_DES_EDE3_CBC,
|
||||
},
|
||||
{
|
||||
OID_DESCRIPTOR(MBEDTLS_OID_AES_128_CBC, "aes128-cbc", "AES128-CBC"),
|
||||
MBEDTLS_CIPHER_AES_128_CBC,
|
||||
},
|
||||
{
|
||||
OID_DESCRIPTOR(MBEDTLS_OID_AES_192_CBC, "aes192-cbc", "AES192-CBC"),
|
||||
MBEDTLS_CIPHER_AES_192_CBC,
|
||||
},
|
||||
{
|
||||
OID_DESCRIPTOR(MBEDTLS_OID_AES_256_CBC, "aes256-cbc", "AES256-CBC"),
|
||||
MBEDTLS_CIPHER_AES_256_CBC,
|
||||
},
|
||||
{
|
||||
NULL_OID_DESCRIPTOR,
|
||||
MBEDTLS_CIPHER_NONE,
|
||||
|
@ -240,6 +240,29 @@ exit:
|
||||
}
|
||||
#endif /* MBEDTLS_AES_C */
|
||||
|
||||
#if defined(MBEDTLS_DES_C) || defined(MBEDTLS_AES_C)
|
||||
static int pem_check_pkcs_padding(unsigned char *input, size_t input_len, size_t *data_len)
|
||||
{
|
||||
/* input_len > 0 is guaranteed by mbedtls_pem_read_buffer(). */
|
||||
size_t pad_len = input[input_len - 1];
|
||||
size_t i;
|
||||
|
||||
if (pad_len > input_len) {
|
||||
return MBEDTLS_ERR_PEM_PASSWORD_MISMATCH;
|
||||
}
|
||||
|
||||
*data_len = input_len - pad_len;
|
||||
|
||||
for (i = *data_len; i < input_len; i++) {
|
||||
if (input[i] != pad_len) {
|
||||
return MBEDTLS_ERR_PEM_PASSWORD_MISMATCH;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif /* MBEDTLS_DES_C || MBEDTLS_AES_C */
|
||||
|
||||
#endif /* PEM_RFC1421 */
|
||||
|
||||
int mbedtls_pem_read_buffer(mbedtls_pem_context *ctx, const char *header, const char *footer,
|
||||
@ -389,6 +412,10 @@ int mbedtls_pem_read_buffer(mbedtls_pem_context *ctx, const char *header, const
|
||||
return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PEM_INVALID_DATA, ret);
|
||||
}
|
||||
|
||||
if (len == 0) {
|
||||
return MBEDTLS_ERR_PEM_BAD_INPUT_DATA;
|
||||
}
|
||||
|
||||
if ((buf = mbedtls_calloc(1, len)) == NULL) {
|
||||
return MBEDTLS_ERR_PEM_ALLOC_FAILED;
|
||||
}
|
||||
@ -426,20 +453,20 @@ int mbedtls_pem_read_buffer(mbedtls_pem_context *ctx, const char *header, const
|
||||
#endif /* MBEDTLS_AES_C */
|
||||
|
||||
if (ret != 0) {
|
||||
mbedtls_free(buf);
|
||||
mbedtls_zeroize_and_free(buf, len);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* The result will be ASN.1 starting with a SEQUENCE tag, with 1 to 3
|
||||
* length bytes (allow 4 to be sure) in all known use cases.
|
||||
*
|
||||
* Use that as a heuristic to try to detect password mismatches.
|
||||
*/
|
||||
if (len <= 2 || buf[0] != 0x30 || buf[1] > 0x83) {
|
||||
/* Check PKCS padding and update data length based on padding info.
|
||||
* This can be used to detect invalid padding data and password
|
||||
* mismatches. */
|
||||
size_t unpadded_len;
|
||||
ret = pem_check_pkcs_padding(buf, len, &unpadded_len);
|
||||
if (ret != 0) {
|
||||
mbedtls_zeroize_and_free(buf, len);
|
||||
return MBEDTLS_ERR_PEM_PASSWORD_MISMATCH;
|
||||
return ret;
|
||||
}
|
||||
len = unpadded_len;
|
||||
#else
|
||||
mbedtls_zeroize_and_free(buf, len);
|
||||
return MBEDTLS_ERR_PEM_FEATURE_UNAVAILABLE;
|
||||
|
@ -383,7 +383,7 @@ static psa_algorithm_t psa_algorithm_for_rsa(const mbedtls_rsa_context *rsa,
|
||||
{
|
||||
if (mbedtls_rsa_get_padding_mode(rsa) == MBEDTLS_RSA_PKCS_V21) {
|
||||
if (want_crypt) {
|
||||
mbedtls_md_type_t md_type = mbedtls_rsa_get_md_alg(rsa);
|
||||
mbedtls_md_type_t md_type = (mbedtls_md_type_t) mbedtls_rsa_get_md_alg(rsa);
|
||||
return PSA_ALG_RSA_OAEP(mbedtls_md_psa_alg_from_type(md_type));
|
||||
} else {
|
||||
return PSA_ALG_RSA_PSS_ANY_SALT(PSA_ALG_ANY_HASH);
|
||||
|
@ -58,7 +58,7 @@ static int rsa_can_do(mbedtls_pk_type_t type)
|
||||
static size_t rsa_get_bitlen(mbedtls_pk_context *pk)
|
||||
{
|
||||
const mbedtls_rsa_context *rsa = (const mbedtls_rsa_context *) pk->pk_ctx;
|
||||
return 8 * mbedtls_rsa_get_len(rsa);
|
||||
return mbedtls_rsa_get_bitlen(rsa);
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_USE_PSA_CRYPTO)
|
||||
@ -74,8 +74,7 @@ static int rsa_verify_wrap(mbedtls_pk_context *pk, mbedtls_md_type_t md_alg,
|
||||
int key_len;
|
||||
unsigned char buf[MBEDTLS_PK_RSA_PUB_DER_MAX_BYTES];
|
||||
unsigned char *p = buf + sizeof(buf);
|
||||
psa_algorithm_t psa_alg_md =
|
||||
PSA_ALG_RSA_PKCS1V15_SIGN(mbedtls_md_psa_alg_from_type(md_alg));
|
||||
psa_algorithm_t psa_alg_md;
|
||||
size_t rsa_len = mbedtls_rsa_get_len(rsa);
|
||||
|
||||
#if SIZE_MAX > UINT_MAX
|
||||
@ -84,6 +83,12 @@ static int rsa_verify_wrap(mbedtls_pk_context *pk, mbedtls_md_type_t md_alg,
|
||||
}
|
||||
#endif
|
||||
|
||||
if (mbedtls_rsa_get_padding_mode(rsa) == MBEDTLS_RSA_PKCS_V21) {
|
||||
psa_alg_md = PSA_ALG_RSA_PSS(mbedtls_md_psa_alg_from_type(md_alg));
|
||||
} else {
|
||||
psa_alg_md = PSA_ALG_RSA_PKCS1V15_SIGN(mbedtls_md_psa_alg_from_type(md_alg));
|
||||
}
|
||||
|
||||
if (sig_len < rsa_len) {
|
||||
return MBEDTLS_ERR_RSA_VERIFY_FAILED;
|
||||
}
|
||||
@ -235,10 +240,14 @@ static int rsa_sign_wrap(mbedtls_pk_context *pk, mbedtls_md_type_t md_alg,
|
||||
if (psa_md_alg == 0) {
|
||||
return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
|
||||
}
|
||||
psa_algorithm_t psa_alg;
|
||||
if (mbedtls_rsa_get_padding_mode(mbedtls_pk_rsa(*pk)) == MBEDTLS_RSA_PKCS_V21) {
|
||||
psa_alg = PSA_ALG_RSA_PSS(psa_md_alg);
|
||||
} else {
|
||||
psa_alg = PSA_ALG_RSA_PKCS1V15_SIGN(psa_md_alg);
|
||||
}
|
||||
|
||||
return mbedtls_pk_psa_rsa_sign_ext(PSA_ALG_RSA_PKCS1V15_SIGN(
|
||||
psa_md_alg),
|
||||
pk->pk_ctx, hash, hash_len,
|
||||
return mbedtls_pk_psa_rsa_sign_ext(psa_alg, pk->pk_ctx, hash, hash_len,
|
||||
sig, sig_size, sig_len);
|
||||
}
|
||||
#else /* MBEDTLS_USE_PSA_CRYPTO */
|
||||
@ -276,6 +285,7 @@ static int rsa_decrypt_wrap(mbedtls_pk_context *pk,
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
|
||||
mbedtls_svc_key_id_t key_id = MBEDTLS_SVC_KEY_ID_INIT;
|
||||
psa_algorithm_t psa_md_alg, decrypt_alg;
|
||||
psa_status_t status;
|
||||
int key_len;
|
||||
unsigned char buf[MBEDTLS_PK_RSA_PRV_DER_MAX_BYTES];
|
||||
@ -284,12 +294,6 @@ static int rsa_decrypt_wrap(mbedtls_pk_context *pk,
|
||||
((void) f_rng);
|
||||
((void) p_rng);
|
||||
|
||||
#if !defined(MBEDTLS_RSA_ALT)
|
||||
if (rsa->padding != MBEDTLS_RSA_PKCS_V15) {
|
||||
return MBEDTLS_ERR_RSA_INVALID_PADDING;
|
||||
}
|
||||
#endif /* !MBEDTLS_RSA_ALT */
|
||||
|
||||
if (ilen != mbedtls_rsa_get_len(rsa)) {
|
||||
return MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
|
||||
}
|
||||
@ -301,7 +305,13 @@ static int rsa_decrypt_wrap(mbedtls_pk_context *pk,
|
||||
|
||||
psa_set_key_type(&attributes, PSA_KEY_TYPE_RSA_KEY_PAIR);
|
||||
psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_DECRYPT);
|
||||
psa_set_key_algorithm(&attributes, PSA_ALG_RSA_PKCS1V15_CRYPT);
|
||||
if (mbedtls_rsa_get_padding_mode(rsa) == MBEDTLS_RSA_PKCS_V21) {
|
||||
psa_md_alg = mbedtls_md_psa_alg_from_type(mbedtls_rsa_get_md_alg(rsa));
|
||||
decrypt_alg = PSA_ALG_RSA_OAEP(psa_md_alg);
|
||||
} else {
|
||||
decrypt_alg = PSA_ALG_RSA_PKCS1V15_CRYPT;
|
||||
}
|
||||
psa_set_key_algorithm(&attributes, decrypt_alg);
|
||||
|
||||
status = psa_import_key(&attributes,
|
||||
buf + sizeof(buf) - key_len, key_len,
|
||||
@ -311,7 +321,7 @@ static int rsa_decrypt_wrap(mbedtls_pk_context *pk,
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
status = psa_asymmetric_decrypt(key_id, PSA_ALG_RSA_PKCS1V15_CRYPT,
|
||||
status = psa_asymmetric_decrypt(key_id, decrypt_alg,
|
||||
input, ilen,
|
||||
NULL, 0,
|
||||
output, osize, olen);
|
||||
@ -358,6 +368,7 @@ static int rsa_encrypt_wrap(mbedtls_pk_context *pk,
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
|
||||
mbedtls_svc_key_id_t key_id = MBEDTLS_SVC_KEY_ID_INIT;
|
||||
psa_algorithm_t psa_md_alg;
|
||||
psa_status_t status;
|
||||
int key_len;
|
||||
unsigned char buf[MBEDTLS_PK_RSA_PUB_DER_MAX_BYTES];
|
||||
@ -366,12 +377,6 @@ static int rsa_encrypt_wrap(mbedtls_pk_context *pk,
|
||||
((void) f_rng);
|
||||
((void) p_rng);
|
||||
|
||||
#if !defined(MBEDTLS_RSA_ALT)
|
||||
if (rsa->padding != MBEDTLS_RSA_PKCS_V15) {
|
||||
return MBEDTLS_ERR_RSA_INVALID_PADDING;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (mbedtls_rsa_get_len(rsa) > osize) {
|
||||
return MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE;
|
||||
}
|
||||
@ -382,7 +387,12 @@ static int rsa_encrypt_wrap(mbedtls_pk_context *pk,
|
||||
}
|
||||
|
||||
psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_ENCRYPT);
|
||||
psa_set_key_algorithm(&attributes, PSA_ALG_RSA_PKCS1V15_CRYPT);
|
||||
if (mbedtls_rsa_get_padding_mode(rsa) == MBEDTLS_RSA_PKCS_V21) {
|
||||
psa_md_alg = mbedtls_md_psa_alg_from_type(mbedtls_rsa_get_md_alg(rsa));
|
||||
psa_set_key_algorithm(&attributes, PSA_ALG_RSA_OAEP(psa_md_alg));
|
||||
} else {
|
||||
psa_set_key_algorithm(&attributes, PSA_ALG_RSA_PKCS1V15_CRYPT);
|
||||
}
|
||||
psa_set_key_type(&attributes, PSA_KEY_TYPE_RSA_PUBLIC_KEY);
|
||||
|
||||
status = psa_import_key(&attributes,
|
||||
|
@ -1089,6 +1089,14 @@ psa_status_t psa_destroy_key(mbedtls_svc_key_id_t key)
|
||||
return status;
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_THREADING_C)
|
||||
/* We cannot unlock between setting the state to PENDING_DELETION
|
||||
* and destroying the key in storage, as otherwise another thread
|
||||
* could load the key into a new slot and the key will not be
|
||||
* fully destroyed. */
|
||||
PSA_THREADING_CHK_GOTO_EXIT(mbedtls_mutex_lock(
|
||||
&mbedtls_threading_key_slot_mutex));
|
||||
#endif
|
||||
/* Set the key slot containing the key description's state to
|
||||
* PENDING_DELETION. This stops new operations from registering
|
||||
* to read the slot. Current readers can safely continue to access
|
||||
@ -1097,7 +1105,12 @@ psa_status_t psa_destroy_key(mbedtls_svc_key_id_t key)
|
||||
* If the key is persistent, we can now delete the copy of the key
|
||||
* from memory. If the key is opaque, we require the driver to
|
||||
* deal with the deletion. */
|
||||
slot->state = PSA_SLOT_PENDING_DELETION;
|
||||
status = psa_key_slot_state_transition(slot, PSA_SLOT_FULL,
|
||||
PSA_SLOT_PENDING_DELETION);
|
||||
|
||||
if (status != PSA_SUCCESS) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if (PSA_KEY_LIFETIME_IS_READ_ONLY(slot->attr.lifetime)) {
|
||||
/* Refuse the destruction of a read-only key (which may or may not work
|
||||
@ -1152,11 +1165,6 @@ psa_status_t psa_destroy_key(mbedtls_svc_key_id_t key)
|
||||
if (overall_status == PSA_SUCCESS) {
|
||||
overall_status = status;
|
||||
}
|
||||
|
||||
/* TODO: other slots may have a copy of the same key. We should
|
||||
* invalidate them.
|
||||
* https://github.com/ARMmbed/mbed-crypto/issues/214
|
||||
*/
|
||||
}
|
||||
#endif /* defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) */
|
||||
|
||||
@ -1182,6 +1190,14 @@ exit:
|
||||
if (status != PSA_SUCCESS) {
|
||||
overall_status = status;
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_THREADING_C)
|
||||
/* Don't overwrite existing errors if the unlock fails. */
|
||||
status = overall_status;
|
||||
PSA_THREADING_CHK_RET(mbedtls_mutex_unlock(
|
||||
&mbedtls_threading_key_slot_mutex));
|
||||
#endif
|
||||
|
||||
return overall_status;
|
||||
}
|
||||
|
||||
@ -1663,7 +1679,15 @@ static psa_status_t psa_start_key_creation(
|
||||
return status;
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_THREADING_C)
|
||||
PSA_THREADING_CHK_RET(mbedtls_mutex_lock(
|
||||
&mbedtls_threading_key_slot_mutex));
|
||||
#endif
|
||||
status = psa_reserve_free_key_slot(&volatile_key_id, p_slot);
|
||||
#if defined(MBEDTLS_THREADING_C)
|
||||
PSA_THREADING_CHK_RET(mbedtls_mutex_unlock(
|
||||
&mbedtls_threading_key_slot_mutex));
|
||||
#endif
|
||||
if (status != PSA_SUCCESS) {
|
||||
return status;
|
||||
}
|
||||
@ -1783,6 +1807,11 @@ static psa_status_t psa_finish_key_creation(
|
||||
(void) slot;
|
||||
(void) driver;
|
||||
|
||||
#if defined(MBEDTLS_THREADING_C)
|
||||
PSA_THREADING_CHK_RET(mbedtls_mutex_lock(
|
||||
&mbedtls_threading_key_slot_mutex));
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_PSA_CRYPTO_STORAGE_C)
|
||||
if (!PSA_KEY_LIFETIME_IS_VOLATILE(slot->attr.lifetime)) {
|
||||
#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
|
||||
@ -1822,6 +1851,11 @@ static psa_status_t psa_finish_key_creation(
|
||||
status = psa_save_se_persistent_data(driver);
|
||||
if (status != PSA_SUCCESS) {
|
||||
psa_destroy_persistent_key(slot->attr.id);
|
||||
|
||||
#if defined(MBEDTLS_THREADING_C)
|
||||
PSA_THREADING_CHK_RET(mbedtls_mutex_unlock(
|
||||
&mbedtls_threading_key_slot_mutex));
|
||||
#endif
|
||||
return status;
|
||||
}
|
||||
status = psa_crypto_stop_transaction();
|
||||
@ -1837,6 +1871,10 @@ static psa_status_t psa_finish_key_creation(
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_THREADING_C)
|
||||
PSA_THREADING_CHK_RET(mbedtls_mutex_unlock(
|
||||
&mbedtls_threading_key_slot_mutex));
|
||||
#endif
|
||||
return status;
|
||||
}
|
||||
|
||||
@ -1861,6 +1899,13 @@ static void psa_fail_key_creation(psa_key_slot_t *slot,
|
||||
return;
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_THREADING_C)
|
||||
/* If the lock operation fails we still wipe the slot.
|
||||
* Operations will no longer work after a failed lock,
|
||||
* but we still need to wipe the slot of confidential data. */
|
||||
mbedtls_mutex_lock(&mbedtls_threading_key_slot_mutex);
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
|
||||
/* TODO: If the key has already been created in the secure
|
||||
* element, and the failure happened later (when saving metadata
|
||||
@ -1879,6 +1924,10 @@ static void psa_fail_key_creation(psa_key_slot_t *slot,
|
||||
#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
|
||||
|
||||
psa_wipe_key_slot(slot);
|
||||
|
||||
#if defined(MBEDTLS_THREADING_C)
|
||||
mbedtls_mutex_unlock(&mbedtls_threading_key_slot_mutex);
|
||||
#endif
|
||||
}
|
||||
|
||||
/** Validate optional attributes during key creation.
|
||||
|
@ -521,44 +521,78 @@ psa_status_t psa_open_key(mbedtls_svc_key_id_t key, psa_key_handle_t *handle)
|
||||
|
||||
psa_status_t psa_close_key(psa_key_handle_t handle)
|
||||
{
|
||||
psa_status_t status;
|
||||
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
|
||||
psa_key_slot_t *slot;
|
||||
|
||||
if (psa_key_handle_is_null(handle)) {
|
||||
return PSA_SUCCESS;
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_THREADING_C)
|
||||
/* We need to set status as success, otherwise CORRUPTION_DETECTED
|
||||
* would be returned if the lock fails. */
|
||||
status = PSA_SUCCESS;
|
||||
PSA_THREADING_CHK_RET(mbedtls_mutex_lock(
|
||||
&mbedtls_threading_key_slot_mutex));
|
||||
#endif
|
||||
status = psa_get_and_lock_key_slot_in_memory(handle, &slot);
|
||||
if (status != PSA_SUCCESS) {
|
||||
if (status == PSA_ERROR_DOES_NOT_EXIST) {
|
||||
status = PSA_ERROR_INVALID_HANDLE;
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_THREADING_C)
|
||||
PSA_THREADING_CHK_RET(mbedtls_mutex_unlock(
|
||||
&mbedtls_threading_key_slot_mutex));
|
||||
#endif
|
||||
return status;
|
||||
}
|
||||
|
||||
if (slot->registered_readers == 1) {
|
||||
return psa_wipe_key_slot(slot);
|
||||
status = psa_wipe_key_slot(slot);
|
||||
} else {
|
||||
return psa_unregister_read(slot);
|
||||
status = psa_unregister_read(slot);
|
||||
}
|
||||
#if defined(MBEDTLS_THREADING_C)
|
||||
PSA_THREADING_CHK_RET(mbedtls_mutex_unlock(
|
||||
&mbedtls_threading_key_slot_mutex));
|
||||
#endif
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
psa_status_t psa_purge_key(mbedtls_svc_key_id_t key)
|
||||
{
|
||||
psa_status_t status;
|
||||
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
|
||||
psa_key_slot_t *slot;
|
||||
|
||||
#if defined(MBEDTLS_THREADING_C)
|
||||
/* We need to set status as success, otherwise CORRUPTION_DETECTED
|
||||
* would be returned if the lock fails. */
|
||||
status = PSA_SUCCESS;
|
||||
PSA_THREADING_CHK_RET(mbedtls_mutex_lock(
|
||||
&mbedtls_threading_key_slot_mutex));
|
||||
#endif
|
||||
status = psa_get_and_lock_key_slot_in_memory(key, &slot);
|
||||
if (status != PSA_SUCCESS) {
|
||||
#if defined(MBEDTLS_THREADING_C)
|
||||
PSA_THREADING_CHK_RET(mbedtls_mutex_unlock(
|
||||
&mbedtls_threading_key_slot_mutex));
|
||||
#endif
|
||||
return status;
|
||||
}
|
||||
|
||||
if ((!PSA_KEY_LIFETIME_IS_VOLATILE(slot->attr.lifetime)) &&
|
||||
(slot->registered_readers == 1)) {
|
||||
return psa_wipe_key_slot(slot);
|
||||
status = psa_wipe_key_slot(slot);
|
||||
} else {
|
||||
return psa_unregister_read(slot);
|
||||
status = psa_unregister_read(slot);
|
||||
}
|
||||
#if defined(MBEDTLS_THREADING_C)
|
||||
PSA_THREADING_CHK_RET(mbedtls_mutex_unlock(
|
||||
&mbedtls_threading_key_slot_mutex));
|
||||
#endif
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
void mbedtls_psa_get_stats(mbedtls_psa_stats_t *stats)
|
||||
|
@ -92,6 +92,8 @@ psa_status_t psa_get_and_lock_key_slot(mbedtls_svc_key_id_t key,
|
||||
psa_status_t psa_initialize_key_slots(void);
|
||||
|
||||
/** Delete all data from key slots in memory.
|
||||
* This function is not thread safe, it wipes every key slot regardless of
|
||||
* state and reader count. It should only be called when no slot is in use.
|
||||
*
|
||||
* This does not affect persistent storage. */
|
||||
void psa_wipe_all_key_slots(void);
|
||||
@ -105,6 +107,9 @@ void psa_wipe_all_key_slots(void);
|
||||
* It is the responsibility of the caller to change the slot's state to
|
||||
* PSA_SLOT_EMPTY/FULL once key creation has finished.
|
||||
*
|
||||
* If multi-threading is enabled, the caller must hold the
|
||||
* global key slot mutex.
|
||||
*
|
||||
* \param[out] volatile_key_id On success, volatile key identifier
|
||||
* associated to the returned slot.
|
||||
* \param[out] p_slot On success, a pointer to the slot.
|
||||
|
@ -108,8 +108,9 @@ int mbedtls_rsa_parse_key(mbedtls_rsa_context *rsa, const unsigned char *key, si
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* mbedtls_asn1_get_tag() already ensures that len is valid (i.e. p+len <= end)*/
|
||||
end = p + len;
|
||||
if (end != p + len) {
|
||||
return MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
|
||||
}
|
||||
|
||||
if ((ret = mbedtls_asn1_get_int(&p, end, &version)) != 0) {
|
||||
return ret;
|
||||
@ -241,8 +242,9 @@ int mbedtls_rsa_parse_pubkey(mbedtls_rsa_context *rsa, const unsigned char *key,
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* mbedtls_asn1_get_tag() already ensures that len is valid (i.e. p+len <= end)*/
|
||||
end = p + len;
|
||||
if (end != p + len) {
|
||||
return MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
|
||||
}
|
||||
|
||||
/* Import N */
|
||||
if ((ret = mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_INTEGER)) != 0) {
|
||||
@ -1014,6 +1016,14 @@ int mbedtls_rsa_get_md_alg(const mbedtls_rsa_context *ctx)
|
||||
return ctx->hash_id;
|
||||
}
|
||||
|
||||
/*
|
||||
* Get length in bits of RSA modulus
|
||||
*/
|
||||
size_t mbedtls_rsa_get_bitlen(const mbedtls_rsa_context *ctx)
|
||||
{
|
||||
return mbedtls_mpi_bitlen(&ctx->N);
|
||||
}
|
||||
|
||||
/*
|
||||
* Get length in bytes of RSA modulus
|
||||
*/
|
||||
|
@ -26,33 +26,35 @@
|
||||
|
||||
#define XOR_BYTE 0x6
|
||||
|
||||
typedef struct mbedtls_sha3_family_functions {
|
||||
mbedtls_sha3_id id;
|
||||
|
||||
uint16_t r;
|
||||
uint16_t olen;
|
||||
}
|
||||
mbedtls_sha3_family_functions;
|
||||
|
||||
/*
|
||||
* List of supported SHA-3 families
|
||||
/* Precomputed masks for the iota transform.
|
||||
*
|
||||
* Each round uses a 64-bit mask value. In each mask values, only
|
||||
* bits whose position is of the form 2^k-1 can be set, thus only
|
||||
* 7 of 64 bits of the mask need to be known for each mask value.
|
||||
*
|
||||
* We use a compressed encoding of the mask where bits 63, 31 and 15
|
||||
* are moved to bits 4-6. This allows us to make each mask value
|
||||
* 1 byte rather than 8 bytes, saving 7*24 = 168 bytes of data (with
|
||||
* perhaps a little variation due to alignment). Decompressing this
|
||||
* requires a little code, but much less than the savings on the table.
|
||||
*
|
||||
* The impact on performance depends on the platform and compiler.
|
||||
* There's a bit more computation, but less memory bandwidth. A quick
|
||||
* benchmark on x86_64 shows a 7% speed improvement with GCC and a
|
||||
* 5% speed penalty with Clang, compared to the naive uint64_t[24] table.
|
||||
* YMMV.
|
||||
*/
|
||||
static const mbedtls_sha3_family_functions sha3_families[] = {
|
||||
{ MBEDTLS_SHA3_224, 1152, 224 },
|
||||
{ MBEDTLS_SHA3_256, 1088, 256 },
|
||||
{ MBEDTLS_SHA3_384, 832, 384 },
|
||||
{ MBEDTLS_SHA3_512, 576, 512 },
|
||||
{ MBEDTLS_SHA3_NONE, 0, 0 }
|
||||
};
|
||||
|
||||
static const uint64_t rc[24] = {
|
||||
0x0000000000000001, 0x0000000000008082, 0x800000000000808a, 0x8000000080008000,
|
||||
0x000000000000808b, 0x0000000080000001, 0x8000000080008081, 0x8000000000008009,
|
||||
0x000000000000008a, 0x0000000000000088, 0x0000000080008009, 0x000000008000000a,
|
||||
0x000000008000808b, 0x800000000000008b, 0x8000000000008089, 0x8000000000008003,
|
||||
0x8000000000008002, 0x8000000000000080, 0x000000000000800a, 0x800000008000000a,
|
||||
0x8000000080008081, 0x8000000000008080, 0x0000000080000001, 0x8000000080008008,
|
||||
/* Helper macro to set the values of the higher bits in unused low positions */
|
||||
#define H(b63, b31, b15) (b63 << 6 | b31 << 5 | b15 << 4)
|
||||
static const uint8_t iota_r_packed[24] = {
|
||||
H(0, 0, 0) | 0x01, H(0, 0, 1) | 0x82, H(1, 0, 1) | 0x8a, H(1, 1, 1) | 0x00,
|
||||
H(0, 0, 1) | 0x8b, H(0, 1, 0) | 0x01, H(1, 1, 1) | 0x81, H(1, 0, 1) | 0x09,
|
||||
H(0, 0, 0) | 0x8a, H(0, 0, 0) | 0x88, H(0, 1, 1) | 0x09, H(0, 1, 0) | 0x0a,
|
||||
H(0, 1, 1) | 0x8b, H(1, 0, 0) | 0x8b, H(1, 0, 1) | 0x89, H(1, 0, 1) | 0x03,
|
||||
H(1, 0, 1) | 0x02, H(1, 0, 0) | 0x80, H(0, 0, 1) | 0x0a, H(1, 1, 0) | 0x0a,
|
||||
H(1, 1, 1) | 0x81, H(1, 0, 1) | 0x80, H(0, 1, 0) | 0x01, H(1, 1, 1) | 0x08,
|
||||
};
|
||||
#undef H
|
||||
|
||||
static const uint8_t rho[24] = {
|
||||
1, 62, 28, 27, 36, 44, 6, 55, 20,
|
||||
@ -151,7 +153,11 @@ static void keccak_f1600(mbedtls_sha3_context *ctx)
|
||||
s[24] ^= (~lane[0]) & lane[1];
|
||||
|
||||
/* Iota */
|
||||
s[0] ^= rc[round];
|
||||
/* Decompress the round masks (see definition of rc) */
|
||||
s[0] ^= ((iota_r_packed[round] & 0x40ull) << 57 |
|
||||
(iota_r_packed[round] & 0x20ull) << 26 |
|
||||
(iota_r_packed[round] & 0x10ull) << 11 |
|
||||
(iota_r_packed[round] & 0x8f));
|
||||
}
|
||||
}
|
||||
|
||||
@ -180,21 +186,27 @@ void mbedtls_sha3_clone(mbedtls_sha3_context *dst,
|
||||
*/
|
||||
int mbedtls_sha3_starts(mbedtls_sha3_context *ctx, mbedtls_sha3_id id)
|
||||
{
|
||||
const mbedtls_sha3_family_functions *p = NULL;
|
||||
|
||||
for (p = sha3_families; p->id != MBEDTLS_SHA3_NONE; p++) {
|
||||
if (p->id == id) {
|
||||
switch (id) {
|
||||
case MBEDTLS_SHA3_224:
|
||||
ctx->olen = 224 / 8;
|
||||
ctx->max_block_size = 1152 / 8;
|
||||
break;
|
||||
}
|
||||
case MBEDTLS_SHA3_256:
|
||||
ctx->olen = 256 / 8;
|
||||
ctx->max_block_size = 1088 / 8;
|
||||
break;
|
||||
case MBEDTLS_SHA3_384:
|
||||
ctx->olen = 384 / 8;
|
||||
ctx->max_block_size = 832 / 8;
|
||||
break;
|
||||
case MBEDTLS_SHA3_512:
|
||||
ctx->olen = 512 / 8;
|
||||
ctx->max_block_size = 576 / 8;
|
||||
break;
|
||||
default:
|
||||
return MBEDTLS_ERR_SHA3_BAD_INPUT_DATA;
|
||||
}
|
||||
|
||||
if (p->id == MBEDTLS_SHA3_NONE) {
|
||||
return MBEDTLS_ERR_SHA3_BAD_INPUT_DATA;
|
||||
}
|
||||
|
||||
ctx->olen = p->olen / 8;
|
||||
ctx->max_block_size = p->r / 8;
|
||||
|
||||
memset(ctx->state, 0, sizeof(ctx->state));
|
||||
ctx->index = 0;
|
||||
|
||||
|
@ -731,14 +731,23 @@ struct mbedtls_ssl_handshake_params {
|
||||
uint8_t key_exchange_mode; /*!< Selected key exchange mode */
|
||||
|
||||
/** Number of HelloRetryRequest messages received/sent from/to the server. */
|
||||
int hello_retry_request_count;
|
||||
uint8_t hello_retry_request_count;
|
||||
|
||||
#if defined(MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE)
|
||||
/**
|
||||
* Number of dummy change_cipher_spec (CCS) record sent. Used to send only
|
||||
* one CCS per handshake without having to complicate the handshake state
|
||||
* transitions.
|
||||
*/
|
||||
uint8_t ccs_count;
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_SSL_SRV_C)
|
||||
/** selected_group of key_share extension in HelloRetryRequest message. */
|
||||
uint16_t hrr_selected_group;
|
||||
#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_PSK_ENABLED)
|
||||
uint8_t tls13_kex_modes; /*!< Key exchange modes supported by the client */
|
||||
#endif
|
||||
/** selected_group of key_share extension in HelloRetryRequest message. */
|
||||
uint16_t hrr_selected_group;
|
||||
#if defined(MBEDTLS_SSL_SESSION_TICKETS)
|
||||
uint16_t new_session_tickets_count; /*!< number of session tickets */
|
||||
#endif
|
||||
@ -2136,6 +2145,38 @@ int mbedtls_ssl_tls13_write_early_data_ext(mbedtls_ssl_context *ssl,
|
||||
unsigned char *buf,
|
||||
const unsigned char *end,
|
||||
size_t *out_len);
|
||||
|
||||
#if defined(MBEDTLS_SSL_CLI_C)
|
||||
/*
|
||||
* The client has not sent the first ClientHello yet, it is unknown if the
|
||||
* client will send an early data indication extension or not.
|
||||
*/
|
||||
#define MBEDTLS_SSL_EARLY_DATA_STATUS_UNKNOWN 0
|
||||
|
||||
/*
|
||||
* The client has sent an early data indication extension in its first
|
||||
* ClientHello, it has not received the response (ServerHello or
|
||||
* HelloRetryRequest) from the server yet. The transform to protect early data
|
||||
* is not set and early data cannot be sent yet.
|
||||
*/
|
||||
#define MBEDTLS_SSL_EARLY_DATA_STATUS_SENT 4
|
||||
|
||||
/*
|
||||
* The client has sent an early data indication extension in its first
|
||||
* ClientHello, it has not received the response (ServerHello or
|
||||
* HelloRetryRequest) from the server yet. The transform to protect early data
|
||||
* has been set and early data can be written now.
|
||||
*/
|
||||
#define MBEDTLS_SSL_EARLY_DATA_STATUS_CAN_WRITE 5
|
||||
|
||||
/*
|
||||
* The client has sent an early data indication extension in its first
|
||||
* ClientHello, the server has accepted them and the client has received the
|
||||
* server Finished message. It cannot send early data to the server anymore.
|
||||
*/
|
||||
#define MBEDTLS_SSL_EARLY_DATA_STATUS_SERVER_FINISHED_RECEIVED 6
|
||||
#endif /* MBEDTLS_SSL_CLI_C */
|
||||
|
||||
#endif /* MBEDTLS_SSL_EARLY_DATA */
|
||||
|
||||
#endif /* MBEDTLS_SSL_PROTO_TLS1_3 */
|
||||
|
@ -1100,7 +1100,7 @@ static int ssl_handshake_init(mbedtls_ssl_context *ssl)
|
||||
|
||||
#if defined(MBEDTLS_SSL_EARLY_DATA)
|
||||
#if defined(MBEDTLS_SSL_CLI_C)
|
||||
ssl->early_data_status = MBEDTLS_SSL_EARLY_DATA_STATUS_NOT_SENT;
|
||||
ssl->early_data_status = MBEDTLS_SSL_EARLY_DATA_STATUS_UNKNOWN;
|
||||
#endif
|
||||
#if defined(MBEDTLS_SSL_SRV_C)
|
||||
ssl->discard_early_data_record = MBEDTLS_SSL_EARLY_DATA_NO_DISCARD;
|
||||
|
@ -1180,26 +1180,21 @@ int mbedtls_ssl_tls13_write_client_hello_exts(mbedtls_ssl_context *ssl,
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_SSL_EARLY_DATA)
|
||||
if (mbedtls_ssl_conf_tls13_is_some_psk_enabled(ssl) &&
|
||||
ssl_tls13_early_data_has_valid_ticket(ssl) &&
|
||||
ssl->conf->early_data_enabled == MBEDTLS_SSL_EARLY_DATA_ENABLED &&
|
||||
ssl->handshake->hello_retry_request_count == 0) {
|
||||
if (ssl->handshake->hello_retry_request_count == 0) {
|
||||
if (mbedtls_ssl_conf_tls13_is_some_psk_enabled(ssl) &&
|
||||
ssl_tls13_early_data_has_valid_ticket(ssl) &&
|
||||
ssl->conf->early_data_enabled == MBEDTLS_SSL_EARLY_DATA_ENABLED) {
|
||||
ret = mbedtls_ssl_tls13_write_early_data_ext(
|
||||
ssl, 0, p, end, &ext_len);
|
||||
if (ret != 0) {
|
||||
return ret;
|
||||
}
|
||||
p += ext_len;
|
||||
|
||||
ret = mbedtls_ssl_tls13_write_early_data_ext(
|
||||
ssl, 0, p, end, &ext_len);
|
||||
if (ret != 0) {
|
||||
return ret;
|
||||
ssl->early_data_status = MBEDTLS_SSL_EARLY_DATA_STATUS_SENT;
|
||||
} else {
|
||||
ssl->early_data_status = MBEDTLS_SSL_EARLY_DATA_STATUS_NOT_SENT;
|
||||
}
|
||||
p += ext_len;
|
||||
|
||||
/* Initializes the status to `rejected`. It will be updated to
|
||||
* `accepted` if the EncryptedExtension message contain an early data
|
||||
* indication extension.
|
||||
*/
|
||||
ssl->early_data_status = MBEDTLS_SSL_EARLY_DATA_STATUS_REJECTED;
|
||||
} else {
|
||||
MBEDTLS_SSL_DEBUG_MSG(2, ("<= skip write early_data extension"));
|
||||
ssl->early_data_status = MBEDTLS_SSL_EARLY_DATA_STATUS_NOT_SENT;
|
||||
}
|
||||
#endif /* MBEDTLS_SSL_EARLY_DATA */
|
||||
|
||||
@ -1236,7 +1231,7 @@ int mbedtls_ssl_tls13_finalize_client_hello(mbedtls_ssl_context *ssl)
|
||||
size_t psk_len;
|
||||
const mbedtls_ssl_ciphersuite_t *ciphersuite_info;
|
||||
|
||||
if (ssl->early_data_status == MBEDTLS_SSL_EARLY_DATA_STATUS_REJECTED) {
|
||||
if (ssl->early_data_status == MBEDTLS_SSL_EARLY_DATA_STATUS_SENT) {
|
||||
MBEDTLS_SSL_DEBUG_MSG(
|
||||
1, ("Set hs psk for early data when writing the first psk"));
|
||||
|
||||
@ -1299,6 +1294,7 @@ int mbedtls_ssl_tls13_finalize_client_hello(mbedtls_ssl_context *ssl)
|
||||
1, ("Switch to early data keys for outbound traffic"));
|
||||
mbedtls_ssl_set_outbound_transform(
|
||||
ssl, ssl->handshake->transform_earlydata);
|
||||
ssl->early_data_status = MBEDTLS_SSL_EARLY_DATA_STATUS_CAN_WRITE;
|
||||
#endif
|
||||
}
|
||||
#endif /* MBEDTLS_SSL_EARLY_DATA */
|
||||
@ -1971,6 +1967,13 @@ static int ssl_tls13_postprocess_hrr(mbedtls_ssl_context *ssl)
|
||||
}
|
||||
|
||||
ssl->session_negotiate->ciphersuite = ssl->handshake->ciphersuite_info->id;
|
||||
|
||||
#if defined(MBEDTLS_SSL_EARLY_DATA)
|
||||
if (ssl->early_data_status != MBEDTLS_SSL_EARLY_DATA_STATUS_NOT_SENT) {
|
||||
ssl->early_data_status = MBEDTLS_SSL_EARLY_DATA_STATUS_REJECTED;
|
||||
}
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -2230,6 +2233,8 @@ static int ssl_tls13_process_encrypted_extensions(mbedtls_ssl_context *ssl)
|
||||
}
|
||||
|
||||
ssl->early_data_status = MBEDTLS_SSL_EARLY_DATA_STATUS_ACCEPTED;
|
||||
} else if (ssl->early_data_status != MBEDTLS_SSL_EARLY_DATA_STATUS_NOT_SENT) {
|
||||
ssl->early_data_status = MBEDTLS_SSL_EARLY_DATA_STATUS_REJECTED;
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -2567,9 +2572,8 @@ static int ssl_tls13_process_server_finished(mbedtls_ssl_context *ssl)
|
||||
|
||||
#if defined(MBEDTLS_SSL_EARLY_DATA)
|
||||
if (ssl->early_data_status == MBEDTLS_SSL_EARLY_DATA_STATUS_ACCEPTED) {
|
||||
ssl->early_data_status = MBEDTLS_SSL_EARLY_DATA_STATUS_SERVER_FINISHED_RECEIVED;
|
||||
mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_END_OF_EARLY_DATA);
|
||||
} else if (ssl->early_data_status == MBEDTLS_SSL_EARLY_DATA_STATUS_REJECTED) {
|
||||
mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_CLIENT_CERTIFICATE);
|
||||
} else
|
||||
#endif /* MBEDTLS_SSL_EARLY_DATA */
|
||||
{
|
||||
@ -3059,18 +3063,25 @@ int mbedtls_ssl_tls13_handshake_client_step(mbedtls_ssl_context *ssl)
|
||||
*/
|
||||
#if defined(MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE)
|
||||
case MBEDTLS_SSL_CLIENT_CCS_BEFORE_2ND_CLIENT_HELLO:
|
||||
ret = mbedtls_ssl_tls13_write_change_cipher_spec(ssl);
|
||||
if (ret == 0) {
|
||||
mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_CLIENT_HELLO);
|
||||
ret = 0;
|
||||
if (ssl->handshake->ccs_count == 0) {
|
||||
ret = mbedtls_ssl_tls13_write_change_cipher_spec(ssl);
|
||||
if (ret != 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_CLIENT_HELLO);
|
||||
break;
|
||||
|
||||
case MBEDTLS_SSL_CLIENT_CCS_AFTER_SERVER_FINISHED:
|
||||
ret = mbedtls_ssl_tls13_write_change_cipher_spec(ssl);
|
||||
if (ret == 0) {
|
||||
mbedtls_ssl_handshake_set_state(
|
||||
ssl, MBEDTLS_SSL_CLIENT_CERTIFICATE);
|
||||
ret = 0;
|
||||
if (ssl->handshake->ccs_count == 0) {
|
||||
ret = mbedtls_ssl_tls13_write_change_cipher_spec(ssl);
|
||||
if (ret != 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_CLIENT_CERTIFICATE);
|
||||
break;
|
||||
|
||||
#if defined(MBEDTLS_SSL_EARLY_DATA)
|
||||
@ -3083,6 +3094,7 @@ int mbedtls_ssl_tls13_handshake_client_step(mbedtls_ssl_context *ssl)
|
||||
1, ("Switch to early data keys for outbound traffic"));
|
||||
mbedtls_ssl_set_outbound_transform(
|
||||
ssl, ssl->handshake->transform_earlydata);
|
||||
ssl->early_data_status = MBEDTLS_SSL_EARLY_DATA_STATUS_CAN_WRITE;
|
||||
}
|
||||
break;
|
||||
#endif /* MBEDTLS_SSL_EARLY_DATA */
|
||||
|
@ -1390,6 +1390,8 @@ int mbedtls_ssl_tls13_write_change_cipher_spec(mbedtls_ssl_context *ssl)
|
||||
/* Dispatch message */
|
||||
MBEDTLS_SSL_PROC_CHK(mbedtls_ssl_write_record(ssl, 0));
|
||||
|
||||
ssl->handshake->ccs_count++;
|
||||
|
||||
cleanup:
|
||||
|
||||
MBEDTLS_SSL_DEBUG_MSG(2, ("<= write change cipher spec"));
|
||||
|
@ -3482,10 +3482,14 @@ int mbedtls_ssl_tls13_handshake_server_step(mbedtls_ssl_context *ssl)
|
||||
break;
|
||||
|
||||
case MBEDTLS_SSL_SERVER_CCS_AFTER_SERVER_HELLO:
|
||||
ret = mbedtls_ssl_tls13_write_change_cipher_spec(ssl);
|
||||
if (ret == 0) {
|
||||
mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_ENCRYPTED_EXTENSIONS);
|
||||
ret = 0;
|
||||
if (ssl->handshake->ccs_count == 0) {
|
||||
ret = mbedtls_ssl_tls13_write_change_cipher_spec(ssl);
|
||||
if (ret != 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_ENCRYPTED_EXTENSIONS);
|
||||
break;
|
||||
#endif /* MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE */
|
||||
|
||||
|
Reference in New Issue
Block a user