From 523b1d27836e1fccee474bafc67dc6698aa22a87 Mon Sep 17 00:00:00 2001 From: Ronald Cron Date: Fri, 23 Feb 2024 07:43:45 +0100 Subject: [PATCH 01/19] tests: ssl: Add max_early_data_size option Signed-off-by: Ronald Cron --- include/test/ssl_helpers.h | 1 + src/test_helpers/ssl_helpers.c | 8 ++++++++ 2 files changed, 9 insertions(+) diff --git a/include/test/ssl_helpers.h b/include/test/ssl_helpers.h index 5b071f75a..71259d66f 100644 --- a/include/test/ssl_helpers.h +++ b/include/test/ssl_helpers.h @@ -114,6 +114,7 @@ typedef struct mbedtls_test_handshake_test_options { void (*cli_log_fun)(void *, int, const char *, int, const char *); int resize_buffers; int early_data; + int max_early_data_size; #if defined(MBEDTLS_SSL_CACHE_C) mbedtls_ssl_cache_context *cache; #endif diff --git a/src/test_helpers/ssl_helpers.c b/src/test_helpers/ssl_helpers.c index 7a28bd879..bf29b474a 100644 --- a/src/test_helpers/ssl_helpers.c +++ b/src/test_helpers/ssl_helpers.c @@ -68,6 +68,7 @@ void mbedtls_test_init_handshake_options( opts->legacy_renegotiation = MBEDTLS_SSL_LEGACY_NO_RENEGOTIATION; opts->resize_buffers = 1; opts->early_data = MBEDTLS_SSL_EARLY_DATA_DISABLED; + opts->max_early_data_size = -1; #if defined(MBEDTLS_SSL_CACHE_C) TEST_CALLOC(opts->cache, 1); mbedtls_ssl_cache_init(opts->cache); @@ -815,6 +816,13 @@ int mbedtls_test_ssl_endpoint_init( #if defined(MBEDTLS_SSL_EARLY_DATA) mbedtls_ssl_conf_early_data(&(ep->conf), options->early_data); +#if defined(MBEDTLS_SSL_SRV_C) + if (endpoint_type == MBEDTLS_SSL_IS_SERVER && + (options->max_early_data_size >= 0)) { + mbedtls_ssl_conf_max_early_data_size(&(ep->conf), + options->max_early_data_size); + } +#endif #endif #if defined(MBEDTLS_SSL_CACHE_C) && defined(MBEDTLS_SSL_SRV_C) From 002f8094e83053d4e04b24caa7133f9c7db365c5 Mon Sep 17 00:00:00 2001 From: Ryan Everett Date: Tue, 12 Mar 2024 16:34:02 +0000 Subject: [PATCH 02/19] Add key_destroyable parameter to mbedtls_test_psa_exercise_key This will allow us to use this smoke test to ensure that key slot content reads are only performed when we are registered to read a full slot. We will destroy the key on another thread while the key is being exercised, and fail the test if an unexpected error code is hit. Future commits will incrementally implement this new parameter. All current usages of this function have this parameter set to 0, in which case the new behaviour must be the same as the old behaviour Signed-off-by: Ryan Everett --- include/test/psa_exercise_key.h | 18 +++++++++++++----- src/psa_exercise_key.c | 29 +++++++++++++++++------------ 2 files changed, 30 insertions(+), 17 deletions(-) diff --git a/include/test/psa_exercise_key.h b/include/test/psa_exercise_key.h index 44f5c08aa..fa57d8872 100644 --- a/include/test/psa_exercise_key.h +++ b/include/test/psa_exercise_key.h @@ -209,18 +209,26 @@ int mbedtls_test_psa_exported_key_sanity_check( * ``` * if( ! exercise_key( ... ) ) goto exit; * ``` + * To use this function for multi-threaded tests where the key + * may be destroyed at any point: call this function with key_destroyable set + * to 1, while another thread calls psa_destroy_key on the same key; + * this will test whether destroying the key in use leads to any corruption. * - * \param key The key to exercise. It should be capable of performing - * \p alg. - * \param usage The usage flags to assume. - * \param alg The algorithm to exercise. + * \param key The key to exercise. It should be capable of performing + * \p alg. + * \param usage The usage flags to assume. + * \param alg The algorithm to exercise. + * \param key_destroyable If set to 1, a failure due to the key not existing + * or the key being destroyed mid-operation will only + * be reported if the error code is unexpected. * * \retval 0 The key failed the smoke tests. * \retval 1 The key passed the smoke tests. */ int mbedtls_test_psa_exercise_key(mbedtls_svc_key_id_t key, psa_key_usage_t usage, - psa_algorithm_t alg); + psa_algorithm_t alg, + int key_destroyable); psa_key_usage_t mbedtls_test_psa_usage_to_exercise(psa_key_type_t type, psa_algorithm_t alg); diff --git a/src/psa_exercise_key.c b/src/psa_exercise_key.c index 7b81052c8..e5cce7939 100644 --- a/src/psa_exercise_key.c +++ b/src/psa_exercise_key.c @@ -948,38 +948,43 @@ exit: int mbedtls_test_psa_exercise_key(mbedtls_svc_key_id_t key, psa_key_usage_t usage, - psa_algorithm_t alg) + psa_algorithm_t alg, + int key_destroyable) { int ok = 0; - if (!check_key_attributes_sanity(key)) { + if (!check_key_attributes_sanity(key, key_destroyable)) { return 0; } if (alg == 0) { ok = 1; /* If no algorithm, do nothing (used for raw data "keys"). */ } else if (PSA_ALG_IS_MAC(alg)) { - ok = exercise_mac_key(key, usage, alg); + ok = exercise_mac_key(key, usage, alg, key_destroyable); } else if (PSA_ALG_IS_CIPHER(alg)) { - ok = exercise_cipher_key(key, usage, alg); + ok = exercise_cipher_key(key, usage, alg, key_destroyable); } else if (PSA_ALG_IS_AEAD(alg)) { - ok = exercise_aead_key(key, usage, alg); + ok = exercise_aead_key(key, usage, alg, key_destroyable); } else if (PSA_ALG_IS_SIGN(alg)) { - ok = exercise_signature_key(key, usage, alg); + ok = exercise_signature_key(key, usage, alg, key_destroyable); } else if (PSA_ALG_IS_ASYMMETRIC_ENCRYPTION(alg)) { - ok = exercise_asymmetric_encryption_key(key, usage, alg); + ok = exercise_asymmetric_encryption_key(key, usage, alg, + key_destroyable); } else if (PSA_ALG_IS_KEY_DERIVATION(alg)) { - ok = exercise_key_derivation_key(key, usage, alg); + ok = exercise_key_derivation_key(key, usage, alg, key_destroyable); } else if (PSA_ALG_IS_RAW_KEY_AGREEMENT(alg)) { - ok = exercise_raw_key_agreement_key(key, usage, alg); + ok = exercise_raw_key_agreement_key(key, usage, alg, key_destroyable); } else if (PSA_ALG_IS_KEY_AGREEMENT(alg)) { - ok = exercise_key_agreement_key(key, usage, alg); + ok = exercise_key_agreement_key(key, usage, alg, key_destroyable); } else { TEST_FAIL("No code to exercise this category of algorithm"); } - ok = ok && exercise_export_key(key, usage); - ok = ok && exercise_export_public_key(key); + ok = ok && exercise_export_key(key, + usage, + key_destroyable); + ok = ok && exercise_export_public_key(key, + key_destroyable); exit: return ok; From 233382e2d9a7020540afb71334945dd49b9374ad Mon Sep 17 00:00:00 2001 From: Ryan Everett Date: Tue, 12 Mar 2024 16:00:08 +0000 Subject: [PATCH 03/19] Add key_destroyable parameter to check_key_attributes_sanity This function is currently only used in the exercise_key smoke test. Signed-off-by: Ryan Everett --- src/psa_exercise_key.c | 37 +++++++++++++++++++++++-------------- 1 file changed, 23 insertions(+), 14 deletions(-) diff --git a/src/psa_exercise_key.c b/src/psa_exercise_key.c index e5cce7939..30f21da90 100644 --- a/src/psa_exercise_key.c +++ b/src/psa_exercise_key.c @@ -38,7 +38,8 @@ static int lifetime_is_dynamic_secure_element(psa_key_lifetime_t lifetime) } #endif -static int check_key_attributes_sanity(mbedtls_svc_key_id_t key) +static int check_key_attributes_sanity(mbedtls_svc_key_id_t key, + int key_destroyable) { int ok = 0; psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; @@ -46,8 +47,13 @@ static int check_key_attributes_sanity(mbedtls_svc_key_id_t key) mbedtls_svc_key_id_t id; psa_key_type_t type; size_t bits; - - PSA_ASSERT(psa_get_key_attributes(key, &attributes)); + psa_status_t status = psa_get_key_attributes(key, &attributes); + if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) { + /* The key has been destroyed. */ + psa_reset_key_attributes(&attributes); + return 1; + } + PSA_ASSERT(status); lifetime = psa_get_key_lifetime(&attributes); id = psa_get_key_id(&attributes); type = psa_get_key_type(&attributes); @@ -66,17 +72,20 @@ static int check_key_attributes_sanity(mbedtls_svc_key_id_t key) (MBEDTLS_SVC_KEY_ID_GET_KEY_ID(id) <= PSA_KEY_ID_USER_MAX)); } #if defined(MBEDTLS_PSA_CRYPTO_SE_C) - /* randomly-generated 64-bit constant, should never appear in test data */ - psa_key_slot_number_t slot_number = 0xec94d4a5058a1a21; - psa_status_t status = psa_get_key_slot_number(&attributes, &slot_number); - if (lifetime_is_dynamic_secure_element(lifetime)) { - /* Mbed TLS currently always exposes the slot number to - * applications. This is not mandated by the PSA specification - * and may change in future versions. */ - TEST_EQUAL(status, 0); - TEST_ASSERT(slot_number != 0xec94d4a5058a1a21); - } else { - TEST_EQUAL(status, PSA_ERROR_INVALID_ARGUMENT); + /* MBEDTLS_PSA_CRYPTO_SE_C does not support thread safety. */ + if (key_destroyable == 0) { + /* randomly-generated 64-bit constant, should never appear in test data */ + psa_key_slot_number_t slot_number = 0xec94d4a5058a1a21; + status = psa_get_key_slot_number(&attributes, &slot_number); + if (lifetime_is_dynamic_secure_element(lifetime)) { + /* Mbed TLS currently always exposes the slot number to + * applications. This is not mandated by the PSA specification + * and may change in future versions. */ + TEST_EQUAL(status, 0); + TEST_ASSERT(slot_number != 0xec94d4a5058a1a21); + } else { + TEST_EQUAL(status, PSA_ERROR_INVALID_ARGUMENT); + } } #endif From c13895a304111a822d3c2bcb4ad093f50948e7ac Mon Sep 17 00:00:00 2001 From: Ryan Everett Date: Tue, 12 Mar 2024 16:02:23 +0000 Subject: [PATCH 04/19] Add key_destroyable parameter to exercise_mac_key If the key has been destroyed (and the new parameter is 1) then we test that psa_mac_abort succeeds in this scenario. Signed-off-by: Ryan Everett --- src/psa_exercise_key.c | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/src/psa_exercise_key.c b/src/psa_exercise_key.c index 30f21da90..dc5b2bf00 100644 --- a/src/psa_exercise_key.c +++ b/src/psa_exercise_key.c @@ -119,20 +119,27 @@ exit: static int exercise_mac_key(mbedtls_svc_key_id_t key, psa_key_usage_t usage, - psa_algorithm_t alg) + psa_algorithm_t alg, + int key_destroyable) { psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT; const unsigned char input[] = "foo"; unsigned char mac[PSA_MAC_MAX_SIZE] = { 0 }; size_t mac_length = sizeof(mac); - + psa_status_t status = PSA_SUCCESS; /* Convert wildcard algorithm to exercisable algorithm */ if (alg & PSA_ALG_MAC_AT_LEAST_THIS_LENGTH_FLAG) { alg = PSA_ALG_TRUNCATED_MAC(alg, PSA_MAC_TRUNCATED_LENGTH(alg)); } if (usage & PSA_KEY_USAGE_SIGN_HASH) { - PSA_ASSERT(psa_mac_sign_setup(&operation, key, alg)); + status = psa_mac_sign_setup(&operation, key, alg); + if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) { + /* The key has been destroyed. */ + PSA_ASSERT(psa_mac_abort(&operation)); + return 1; + } + PSA_ASSERT(status); PSA_ASSERT(psa_mac_update(&operation, input, sizeof(input))); PSA_ASSERT(psa_mac_sign_finish(&operation, @@ -145,7 +152,13 @@ static int exercise_mac_key(mbedtls_svc_key_id_t key, (usage & PSA_KEY_USAGE_SIGN_HASH ? PSA_SUCCESS : PSA_ERROR_INVALID_SIGNATURE); - PSA_ASSERT(psa_mac_verify_setup(&operation, key, alg)); + status = psa_mac_verify_setup(&operation, key, alg); + if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) { + /* The key has been destroyed. */ + PSA_ASSERT(psa_mac_abort(&operation)); + return 1; + } + PSA_ASSERT(status); PSA_ASSERT(psa_mac_update(&operation, input, sizeof(input))); TEST_EQUAL(psa_mac_verify_finish(&operation, mac, mac_length), From 6049968220ad63de377aeac641a48c262c89d591 Mon Sep 17 00:00:00 2001 From: Ryan Everett Date: Tue, 12 Mar 2024 16:04:45 +0000 Subject: [PATCH 05/19] Add key_destroyable parameter to psa_exercise_cipher_key If the key has been destroyed (and the new parameter is 1), we test that psa_cipher_abort succeeds in this scenario. Signed-off-by: Ryan Everett --- src/psa_exercise_key.c | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/src/psa_exercise_key.c b/src/psa_exercise_key.c index dc5b2bf00..ff0d1c0a6 100644 --- a/src/psa_exercise_key.c +++ b/src/psa_exercise_key.c @@ -174,7 +174,8 @@ exit: static int exercise_cipher_key(mbedtls_svc_key_id_t key, psa_key_usage_t usage, - psa_algorithm_t alg) + psa_algorithm_t alg, + int key_destroyable) { psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT; unsigned char iv[PSA_CIPHER_IV_MAX_SIZE] = { 0 }; @@ -186,13 +187,20 @@ static int exercise_cipher_key(mbedtls_svc_key_id_t key, size_t ciphertext_length = sizeof(ciphertext); unsigned char decrypted[sizeof(ciphertext)]; size_t part_length; + psa_status_t status = PSA_SUCCESS; PSA_ASSERT(psa_get_key_attributes(key, &attributes)); key_type = psa_get_key_type(&attributes); iv_length = PSA_CIPHER_IV_LENGTH(key_type, alg); if (usage & PSA_KEY_USAGE_ENCRYPT) { - PSA_ASSERT(psa_cipher_encrypt_setup(&operation, key, alg)); + status = psa_cipher_encrypt_setup(&operation, key, alg); + if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) { + /* The key has been destroyed. */ + PSA_ASSERT(psa_cipher_abort(&operation)); + return 1; + } + PSA_ASSERT(status); if (iv_length != 0) { PSA_ASSERT(psa_cipher_generate_iv(&operation, iv, sizeof(iv), @@ -210,12 +218,17 @@ static int exercise_cipher_key(mbedtls_svc_key_id_t key, } if (usage & PSA_KEY_USAGE_DECRYPT) { - psa_status_t status; int maybe_invalid_padding = 0; if (!(usage & PSA_KEY_USAGE_ENCRYPT)) { maybe_invalid_padding = !PSA_ALG_IS_STREAM_CIPHER(alg); } - PSA_ASSERT(psa_cipher_decrypt_setup(&operation, key, alg)); + status = psa_cipher_decrypt_setup(&operation, key, alg); + if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) { + /* The key has been destroyed. */ + PSA_ASSERT(psa_cipher_abort(&operation)); + return 1; + } + PSA_ASSERT(status); if (iv_length != 0) { PSA_ASSERT(psa_cipher_set_iv(&operation, iv, iv_length)); From e0cfa29e206208936097bdeb8de5dbbdc535f4b2 Mon Sep 17 00:00:00 2001 From: Ryan Everett Date: Tue, 12 Mar 2024 16:09:25 +0000 Subject: [PATCH 06/19] Add key_destroyable parameter to exercise_aead_key Signed-off-by: Ryan Everett --- src/psa_exercise_key.c | 39 +++++++++++++++++++++++++-------------- 1 file changed, 25 insertions(+), 14 deletions(-) diff --git a/src/psa_exercise_key.c b/src/psa_exercise_key.c index ff0d1c0a6..89434bfdc 100644 --- a/src/psa_exercise_key.c +++ b/src/psa_exercise_key.c @@ -262,7 +262,8 @@ exit: static int exercise_aead_key(mbedtls_svc_key_id_t key, psa_key_usage_t usage, - psa_algorithm_t alg) + psa_algorithm_t alg, + int key_destroyable) { unsigned char nonce[PSA_AEAD_NONCE_MAX_SIZE] = { 0 }; size_t nonce_length; @@ -272,6 +273,7 @@ static int exercise_aead_key(mbedtls_svc_key_id_t key, unsigned char ciphertext[48] = "(wabblewebblewibblewobblewubble)"; size_t ciphertext_length = sizeof(ciphertext); size_t plaintext_length = sizeof(ciphertext); + psa_status_t status = PSA_SUCCESS; /* Convert wildcard algorithm to exercisable algorithm */ if (alg & PSA_ALG_AEAD_AT_LEAST_THIS_LENGTH_FLAG) { @@ -283,12 +285,17 @@ static int exercise_aead_key(mbedtls_svc_key_id_t key, nonce_length = PSA_AEAD_NONCE_LENGTH(key_type, alg); if (usage & PSA_KEY_USAGE_ENCRYPT) { - PSA_ASSERT(psa_aead_encrypt(key, alg, - nonce, nonce_length, - NULL, 0, - plaintext, sizeof(plaintext), - ciphertext, sizeof(ciphertext), - &ciphertext_length)); + status = psa_aead_encrypt(key, alg, + nonce, nonce_length, + NULL, 0, + plaintext, sizeof(plaintext), + ciphertext, sizeof(ciphertext), + &ciphertext_length); + if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) { + /* The key has been destroyed. */ + return 1; + } + PSA_ASSERT(status); } if (usage & PSA_KEY_USAGE_DECRYPT) { @@ -296,13 +303,17 @@ static int exercise_aead_key(mbedtls_svc_key_id_t key, (usage & PSA_KEY_USAGE_ENCRYPT ? PSA_SUCCESS : PSA_ERROR_INVALID_SIGNATURE); - TEST_EQUAL(psa_aead_decrypt(key, alg, - nonce, nonce_length, - NULL, 0, - ciphertext, ciphertext_length, - plaintext, sizeof(plaintext), - &plaintext_length), - verify_status); + status = psa_aead_decrypt(key, alg, + nonce, nonce_length, + NULL, 0, + ciphertext, ciphertext_length, + plaintext, sizeof(plaintext), + &plaintext_length); + if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) { + /* The key has been destroyed. */ + return 1; + } + TEST_ASSERT(status == verify_status); } return 1; From 33fba7c84b7a8c333bb49298c0fdcc9c88ab5cd3 Mon Sep 17 00:00:00 2001 From: Ryan Everett Date: Tue, 12 Mar 2024 16:11:01 +0000 Subject: [PATCH 07/19] Add key_destroyable parameter to exercise_signature_key Signed-off-by: Ryan Everett --- src/psa_exercise_key.c | 54 +++++++++++++++++++++++++++++------------- 1 file changed, 37 insertions(+), 17 deletions(-) diff --git a/src/psa_exercise_key.c b/src/psa_exercise_key.c index 89434bfdc..fde1187e7 100644 --- a/src/psa_exercise_key.c +++ b/src/psa_exercise_key.c @@ -337,7 +337,8 @@ static int can_sign_or_verify_message(psa_key_usage_t usage, static int exercise_signature_key(mbedtls_svc_key_id_t key, psa_key_usage_t usage, - psa_algorithm_t alg) + psa_algorithm_t alg, + int key_destroyable) { /* If the policy allows signing with any hash, just pick one. */ psa_algorithm_t hash_alg = PSA_ALG_SIGN_GET_HASH(alg); @@ -351,6 +352,7 @@ static int exercise_signature_key(mbedtls_svc_key_id_t key, TEST_FAIL("No hash algorithm for hash-and-sign testing"); #endif } + psa_status_t status = PSA_SUCCESS; if (usage & (PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH) && PSA_ALG_IS_SIGN_HASH(alg)) { @@ -367,10 +369,15 @@ static int exercise_signature_key(mbedtls_svc_key_id_t key, } if (usage & PSA_KEY_USAGE_SIGN_HASH) { - PSA_ASSERT(psa_sign_hash(key, alg, - payload, payload_length, - signature, sizeof(signature), - &signature_length)); + status = psa_sign_hash(key, alg, + payload, payload_length, + signature, sizeof(signature), + &signature_length); + if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) { + /* The key has been destroyed. */ + return 1; + } + PSA_ASSERT(status); } if (usage & PSA_KEY_USAGE_VERIFY_HASH) { @@ -378,10 +385,14 @@ static int exercise_signature_key(mbedtls_svc_key_id_t key, (usage & PSA_KEY_USAGE_SIGN_HASH ? PSA_SUCCESS : PSA_ERROR_INVALID_SIGNATURE); - TEST_EQUAL(psa_verify_hash(key, alg, - payload, payload_length, - signature, signature_length), - verify_status); + status = psa_verify_hash(key, alg, + payload, payload_length, + signature, signature_length); + if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) { + /* The key has been destroyed. */ + return 1; + } + TEST_ASSERT(status == verify_status); } } @@ -392,10 +403,15 @@ static int exercise_signature_key(mbedtls_svc_key_id_t key, size_t signature_length = sizeof(signature); if (usage & PSA_KEY_USAGE_SIGN_MESSAGE) { - PSA_ASSERT(psa_sign_message(key, alg, - message, message_length, - signature, sizeof(signature), - &signature_length)); + status = psa_sign_message(key, alg, + message, message_length, + signature, sizeof(signature), + &signature_length); + if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) { + /* The key has been destroyed. */ + return 1; + } + PSA_ASSERT(status); } if (usage & PSA_KEY_USAGE_VERIFY_MESSAGE) { @@ -403,10 +419,14 @@ static int exercise_signature_key(mbedtls_svc_key_id_t key, (usage & PSA_KEY_USAGE_SIGN_MESSAGE ? PSA_SUCCESS : PSA_ERROR_INVALID_SIGNATURE); - TEST_EQUAL(psa_verify_message(key, alg, - message, message_length, - signature, signature_length), - verify_status); + status = psa_verify_message(key, alg, + message, message_length, + signature, signature_length); + if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) { + /* The key has been destroyed. */ + return 1; + } + TEST_ASSERT(status == verify_status); } } From 0032477d1d205bf67b01c11529ef94129a024c19 Mon Sep 17 00:00:00 2001 From: Ryan Everett Date: Tue, 12 Mar 2024 16:12:41 +0000 Subject: [PATCH 08/19] Add key_destroyable parameter to exercise_asymmetric_encryption_key Signed-off-by: Ryan Everett --- src/psa_exercise_key.c | 35 ++++++++++++++++++++++------------- 1 file changed, 22 insertions(+), 13 deletions(-) diff --git a/src/psa_exercise_key.c b/src/psa_exercise_key.c index fde1187e7..470073930 100644 --- a/src/psa_exercise_key.c +++ b/src/psa_exercise_key.c @@ -438,7 +438,8 @@ exit: static int exercise_asymmetric_encryption_key(mbedtls_svc_key_id_t key, psa_key_usage_t usage, - psa_algorithm_t alg) + psa_algorithm_t alg, + int key_destroyable) { unsigned char plaintext[PSA_ASYMMETRIC_DECRYPT_OUTPUT_MAX_SIZE] = "Hello, world..."; @@ -446,22 +447,30 @@ static int exercise_asymmetric_encryption_key(mbedtls_svc_key_id_t key, "(wabblewebblewibblewobblewubble)"; size_t ciphertext_length = sizeof(ciphertext); size_t plaintext_length = 16; - + psa_status_t status = PSA_SUCCESS; if (usage & PSA_KEY_USAGE_ENCRYPT) { - PSA_ASSERT(psa_asymmetric_encrypt(key, alg, - plaintext, plaintext_length, - NULL, 0, - ciphertext, sizeof(ciphertext), - &ciphertext_length)); + status = psa_asymmetric_encrypt(key, alg, + plaintext, plaintext_length, + NULL, 0, + ciphertext, sizeof(ciphertext), + &ciphertext_length); + if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) { + /* The key has been destroyed. */ + return 1; + } + PSA_ASSERT(status); } if (usage & PSA_KEY_USAGE_DECRYPT) { - psa_status_t status = - psa_asymmetric_decrypt(key, alg, - ciphertext, ciphertext_length, - NULL, 0, - plaintext, sizeof(plaintext), - &plaintext_length); + status = psa_asymmetric_decrypt(key, alg, + ciphertext, ciphertext_length, + NULL, 0, + plaintext, sizeof(plaintext), + &plaintext_length); + if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) { + /* The key has been destroyed. */ + return 1; + } TEST_ASSERT(status == PSA_SUCCESS || ((usage & PSA_KEY_USAGE_ENCRYPT) == 0 && (status == PSA_ERROR_INVALID_ARGUMENT || From 051d2981524e027b77b1355e35abaaf881b92491 Mon Sep 17 00:00:00 2001 From: Ryan Everett Date: Tue, 12 Mar 2024 16:17:43 +0000 Subject: [PATCH 09/19] Add key_destroyable parameter to key derivation smoke tests All current usages have this parameter set to 0 (in this case the behaviour of the test is unchanged) Signed-off-by: Ryan Everett --- include/test/psa_exercise_key.h | 5 ++- src/psa_exercise_key.c | 77 +++++++++++++++++++++++---------- 2 files changed, 59 insertions(+), 23 deletions(-) diff --git a/include/test/psa_exercise_key.h b/include/test/psa_exercise_key.h index fa57d8872..713b09310 100644 --- a/include/test/psa_exercise_key.h +++ b/include/test/psa_exercise_key.h @@ -123,6 +123,9 @@ * \param input2 The first input to pass. * \param input2_length The length of \p input2 in bytes. * \param capacity The capacity to set. + * \param key_destroyable If set to 1, a failure due to the key not existing + * or the key being destroyed mid-operation will only + * be reported if the error code is unexpected. * * \return \c 1 on success, \c 0 on failure. */ @@ -132,7 +135,7 @@ int mbedtls_test_psa_setup_key_derivation_wrap( psa_algorithm_t alg, const unsigned char *input1, size_t input1_length, const unsigned char *input2, size_t input2_length, - size_t capacity); + size_t capacity, int key_destroyable); /** Perform a key agreement using the given key pair against its public key * using psa_raw_key_agreement(). diff --git a/src/psa_exercise_key.c b/src/psa_exercise_key.c index 470073930..7260f1a4d 100644 --- a/src/psa_exercise_key.c +++ b/src/psa_exercise_key.c @@ -489,16 +489,22 @@ int mbedtls_test_psa_setup_key_derivation_wrap( psa_algorithm_t alg, const unsigned char *input1, size_t input1_length, const unsigned char *input2, size_t input2_length, - size_t capacity) + size_t capacity, int key_destroyable) { PSA_ASSERT(psa_key_derivation_setup(operation, alg)); + psa_status_t status = PSA_SUCCESS; if (PSA_ALG_IS_HKDF(alg)) { PSA_ASSERT(psa_key_derivation_input_bytes(operation, PSA_KEY_DERIVATION_INPUT_SALT, input1, input1_length)); - PSA_ASSERT(psa_key_derivation_input_key(operation, - PSA_KEY_DERIVATION_INPUT_SECRET, - key)); + status = psa_key_derivation_input_key(operation, + PSA_KEY_DERIVATION_INPUT_SECRET, + key); + if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) { + /* The key has been destroyed. */ + return 1; + } + PSA_ASSERT(status); PSA_ASSERT(psa_key_derivation_input_bytes(operation, PSA_KEY_DERIVATION_INPUT_INFO, input2, @@ -507,13 +513,23 @@ int mbedtls_test_psa_setup_key_derivation_wrap( PSA_ASSERT(psa_key_derivation_input_bytes(operation, PSA_KEY_DERIVATION_INPUT_SALT, input1, input1_length)); - PSA_ASSERT(psa_key_derivation_input_key(operation, - PSA_KEY_DERIVATION_INPUT_SECRET, - key)); + status = psa_key_derivation_input_key(operation, + PSA_KEY_DERIVATION_INPUT_SECRET, + key); + if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) { + /* The key has been destroyed. */ + return 1; + } + PSA_ASSERT(status); } else if (PSA_ALG_IS_HKDF_EXPAND(alg)) { - PSA_ASSERT(psa_key_derivation_input_key(operation, - PSA_KEY_DERIVATION_INPUT_SECRET, - key)); + status = psa_key_derivation_input_key(operation, + PSA_KEY_DERIVATION_INPUT_SECRET, + key); + if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) { + /* The key has been destroyed. */ + return 1; + } + PSA_ASSERT(status); PSA_ASSERT(psa_key_derivation_input_bytes(operation, PSA_KEY_DERIVATION_INPUT_INFO, input2, @@ -523,9 +539,14 @@ int mbedtls_test_psa_setup_key_derivation_wrap( PSA_ASSERT(psa_key_derivation_input_bytes(operation, PSA_KEY_DERIVATION_INPUT_SEED, input1, input1_length)); - PSA_ASSERT(psa_key_derivation_input_key(operation, - PSA_KEY_DERIVATION_INPUT_SECRET, - key)); + status = psa_key_derivation_input_key(operation, + PSA_KEY_DERIVATION_INPUT_SECRET, + key); + if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) { + /* The key has been destroyed. */ + return 1; + } + PSA_ASSERT(status); PSA_ASSERT(psa_key_derivation_input_bytes(operation, PSA_KEY_DERIVATION_INPUT_LABEL, input2, input2_length)); @@ -537,9 +558,14 @@ int mbedtls_test_psa_setup_key_derivation_wrap( PSA_KEY_DERIVATION_INPUT_SALT, input2, input2_length)); - PSA_ASSERT(psa_key_derivation_input_key(operation, - PSA_KEY_DERIVATION_INPUT_PASSWORD, - key)); + status = psa_key_derivation_input_key(operation, + PSA_KEY_DERIVATION_INPUT_PASSWORD, + key); + if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) { + /* The key has been destroyed. */ + return 1; + } + PSA_ASSERT(status); } else if (alg == PSA_ALG_TLS12_ECJPAKE_TO_PMS) { PSA_ASSERT(psa_key_derivation_input_bytes(operation, PSA_KEY_DERIVATION_INPUT_SECRET, @@ -561,7 +587,8 @@ exit: static int exercise_key_derivation_key(mbedtls_svc_key_id_t key, psa_key_usage_t usage, - psa_algorithm_t alg) + psa_algorithm_t alg, + int key_destroyable) { psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT; unsigned char input1[] = "Input 1"; @@ -575,14 +602,20 @@ static int exercise_key_derivation_key(mbedtls_svc_key_id_t key, if (!mbedtls_test_psa_setup_key_derivation_wrap(&operation, key, alg, input1, input1_length, input2, input2_length, - capacity)) { + capacity, key_destroyable)) { goto exit; } - PSA_ASSERT(psa_key_derivation_output_bytes(&operation, - output, - capacity)); - PSA_ASSERT(psa_key_derivation_abort(&operation)); + psa_status_t status = psa_key_derivation_output_bytes(&operation, + output, + capacity); + if (key_destroyable && status == PSA_ERROR_BAD_STATE) { + /* The key has been destroyed. */ + PSA_ASSERT(psa_key_derivation_abort(&operation)); + } else { + PSA_ASSERT(status); + PSA_ASSERT(psa_key_derivation_abort(&operation)); + } } return 1; From f7ba175dacf7b5ac1398db009f0da41f8f0449d0 Mon Sep 17 00:00:00 2001 From: Ryan Everett Date: Tue, 12 Mar 2024 16:21:12 +0000 Subject: [PATCH 10/19] Add key_destroyable parameter to raw key agreement smoke tests All current usages have this parameter set to 0 (meaning the behaviour of these tests hasn't changed). We also now return the actual error code, not GENERIC_ERROR Signed-off-by: Ryan Everett --- include/test/psa_exercise_key.h | 5 ++++- src/psa_exercise_key.c | 38 +++++++++++++++++++++++---------- 2 files changed, 31 insertions(+), 12 deletions(-) diff --git a/include/test/psa_exercise_key.h b/include/test/psa_exercise_key.h index 713b09310..23349166a 100644 --- a/include/test/psa_exercise_key.h +++ b/include/test/psa_exercise_key.h @@ -146,12 +146,15 @@ int mbedtls_test_psa_setup_key_derivation_wrap( * * \param alg A key agreement algorithm compatible with \p key. * \param key A key that allows key agreement with \p alg. + * \param key_destroyable If set to 1, a failure due to the key not existing + * or the key being destroyed mid-operation will only + * be reported if the error code is unexpected. * * \return \c 1 on success, \c 0 on failure. */ psa_status_t mbedtls_test_psa_raw_key_agreement_with_self( psa_algorithm_t alg, - mbedtls_svc_key_id_t key); + mbedtls_svc_key_id_t key, int key_destroyable); /** Perform a key agreement using the given key pair against its public key * using psa_key_derivation_raw_key(). diff --git a/src/psa_exercise_key.c b/src/psa_exercise_key.c index 7260f1a4d..b62a34b5d 100644 --- a/src/psa_exercise_key.c +++ b/src/psa_exercise_key.c @@ -668,7 +668,8 @@ exit: * private key against its own public key. */ psa_status_t mbedtls_test_psa_raw_key_agreement_with_self( psa_algorithm_t alg, - mbedtls_svc_key_id_t key) + mbedtls_svc_key_id_t key, + int key_destroyable) { psa_key_type_t private_key_type; psa_key_type_t public_key_type; @@ -677,25 +678,38 @@ psa_status_t mbedtls_test_psa_raw_key_agreement_with_self( size_t public_key_length; uint8_t output[1024]; size_t output_length; - /* Return GENERIC_ERROR if something other than the final call to - * psa_key_derivation_key_agreement fails. This isn't fully satisfactory, - * but it's good enough: callers will report it as a failed test anyway. */ - psa_status_t status = PSA_ERROR_GENERIC_ERROR; psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; - PSA_ASSERT(psa_get_key_attributes(key, &attributes)); + psa_status_t status = psa_get_key_attributes(key, &attributes); + if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) { + /* The key has been destroyed. */ + psa_reset_key_attributes(&attributes); + return PSA_SUCCESS; + } + PSA_ASSERT(status); + private_key_type = psa_get_key_type(&attributes); key_bits = psa_get_key_bits(&attributes); public_key_type = PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(private_key_type); public_key_length = PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(public_key_type, key_bits); TEST_CALLOC(public_key, public_key_length); - PSA_ASSERT(psa_export_public_key(key, - public_key, public_key_length, - &public_key_length)); + status = psa_export_public_key(key, + public_key, public_key_length, + &public_key_length); + if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) { + /* The key has been destroyed. */ + status = PSA_SUCCESS; + goto exit; + } status = psa_raw_key_agreement(alg, key, public_key, public_key_length, output, sizeof(output), &output_length); + if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) { + /* The key has been destroyed. */ + status = PSA_SUCCESS; + goto exit; + } if (status == PSA_SUCCESS) { TEST_ASSERT(output_length <= PSA_RAW_KEY_AGREEMENT_OUTPUT_SIZE(private_key_type, @@ -717,14 +731,16 @@ exit: static int exercise_raw_key_agreement_key(mbedtls_svc_key_id_t key, psa_key_usage_t usage, - psa_algorithm_t alg) + psa_algorithm_t alg, + int key_destroyable) { int ok = 0; if (usage & PSA_KEY_USAGE_DERIVE) { /* We need two keys to exercise key agreement. Exercise the * private key against its own public key. */ - PSA_ASSERT(mbedtls_test_psa_raw_key_agreement_with_self(alg, key)); + PSA_ASSERT(mbedtls_test_psa_raw_key_agreement_with_self(alg, key, + key_destroyable)); } ok = 1; From 1290451303567b4383b33e6974e8e0335ff20011 Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Tue, 12 Mar 2024 13:30:29 +0100 Subject: [PATCH 11/19] psa_crypto_stubs: extend stub functions for the CRYPTO_CLIENT tests Signed-off-by: Valerio Setti --- src/psa_crypto_stubs.c | 50 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/src/psa_crypto_stubs.c b/src/psa_crypto_stubs.c index f3ca85074..81d7f4b32 100644 --- a/src/psa_crypto_stubs.c +++ b/src/psa_crypto_stubs.c @@ -22,4 +22,54 @@ psa_status_t psa_generate_random(uint8_t *output, return PSA_ERROR_COMMUNICATION_FAILURE; } +psa_status_t psa_export_key(mbedtls_svc_key_id_t key, + uint8_t *data, + size_t data_size, + size_t *data_length) +{ + (void) key; + (void) data; + (void) data_size; + (void) data_length; + return PSA_ERROR_COMMUNICATION_FAILURE; +} + +psa_status_t psa_export_public_key(mbedtls_svc_key_id_t key, + uint8_t *data, + size_t data_size, + size_t *data_length) +{ + (void) key; + (void) data; + (void) data_size; + (void) data_length; + return PSA_ERROR_COMMUNICATION_FAILURE; +} + +psa_status_t psa_get_key_attributes(mbedtls_svc_key_id_t key, + psa_key_attributes_t *attributes) +{ + (void) key; + (void) attributes; + return PSA_ERROR_COMMUNICATION_FAILURE; +} + +psa_status_t psa_hash_abort(psa_hash_operation_t *operation) +{ + (void) operation; + return PSA_ERROR_COMMUNICATION_FAILURE; +} + +psa_status_t psa_import_key(const psa_key_attributes_t *attributes, + const uint8_t *data, + size_t data_length, + mbedtls_svc_key_id_t *key) +{ + (void) attributes; + (void) data; + (void) data_length; + (void) key; + return PSA_ERROR_COMMUNICATION_FAILURE; +} + #endif /* MBEDTLS_PSA_CRYPTO_CLIENT && !MBEDTLS_PSA_CRYPTO_C */ From f89b216cbc500eab7391ea9fb51eb995d7d841d8 Mon Sep 17 00:00:00 2001 From: Ryan Everett Date: Tue, 12 Mar 2024 16:29:55 +0000 Subject: [PATCH 12/19] Add key_destroyable parameter to non-raw key agreement smoke tests All current usages have this parameter set to 0 (this means the tests are unchanged). Remove the GENERIC_ERROR return behaviour, in favour of returning the actual status. Signed-off-by: Ryan Everett --- include/test/psa_exercise_key.h | 5 +++- src/psa_exercise_key.c | 43 ++++++++++++++++++++++++--------- 2 files changed, 36 insertions(+), 12 deletions(-) diff --git a/include/test/psa_exercise_key.h b/include/test/psa_exercise_key.h index 23349166a..f656b95f8 100644 --- a/include/test/psa_exercise_key.h +++ b/include/test/psa_exercise_key.h @@ -168,12 +168,15 @@ psa_status_t mbedtls_test_psa_raw_key_agreement_with_self( * \p key. * \param key A key pair object that is suitable for a key * agreement with \p operation. + * \param key_destroyable If set to 1, a failure due to the key not existing + * or the key being destroyed mid-operation will only + * be reported if the error code is unexpected. * * \return \c 1 on success, \c 0 on failure. */ psa_status_t mbedtls_test_psa_key_agreement_with_self( psa_key_derivation_operation_t *operation, - mbedtls_svc_key_id_t key); + mbedtls_svc_key_id_t key, int key_destroyable); /** Perform sanity checks on the given key representation. * diff --git a/src/psa_exercise_key.c b/src/psa_exercise_key.c index b62a34b5d..1cf45ac56 100644 --- a/src/psa_exercise_key.c +++ b/src/psa_exercise_key.c @@ -628,31 +628,45 @@ exit: * private key against its own public key. */ psa_status_t mbedtls_test_psa_key_agreement_with_self( psa_key_derivation_operation_t *operation, - mbedtls_svc_key_id_t key) + mbedtls_svc_key_id_t key, int key_destroyable) { psa_key_type_t private_key_type; psa_key_type_t public_key_type; size_t key_bits; uint8_t *public_key = NULL; size_t public_key_length; - /* Return GENERIC_ERROR if something other than the final call to - * psa_key_derivation_key_agreement fails. This isn't fully satisfactory, - * but it's good enough: callers will report it as a failed test anyway. */ - psa_status_t status = PSA_ERROR_GENERIC_ERROR; psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; - PSA_ASSERT(psa_get_key_attributes(key, &attributes)); + psa_status_t status = psa_get_key_attributes(key, &attributes); + if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) { + /* The key has been destroyed. */ + psa_reset_key_attributes(&attributes); + return PSA_SUCCESS; + } + PSA_ASSERT(status); + private_key_type = psa_get_key_type(&attributes); key_bits = psa_get_key_bits(&attributes); public_key_type = PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(private_key_type); public_key_length = PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(public_key_type, key_bits); TEST_CALLOC(public_key, public_key_length); - PSA_ASSERT(psa_export_public_key(key, public_key, public_key_length, - &public_key_length)); + status = psa_export_public_key(key, public_key, public_key_length, + &public_key_length); + if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) { + /* The key has been destroyed. */ + status = PSA_SUCCESS; + goto exit; + } + PSA_ASSERT(status); status = psa_key_derivation_key_agreement( operation, PSA_KEY_DERIVATION_INPUT_SECRET, key, public_key, public_key_length); + if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) { + /* The key has been destroyed. */ + status = PSA_SUCCESS; + goto exit; + } exit: /* * Key attributes may have been returned by psa_get_key_attributes() @@ -750,7 +764,8 @@ exit: static int exercise_key_agreement_key(mbedtls_svc_key_id_t key, psa_key_usage_t usage, - psa_algorithm_t alg) + psa_algorithm_t alg, + int key_destroyable) { psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT; unsigned char input[1] = { 0 }; @@ -781,7 +796,12 @@ static int exercise_key_agreement_key(mbedtls_svc_key_id_t key, hash length. Otherwise test should fail with INVALID_ARGUMENT. */ if (PSA_ALG_IS_HKDF_EXPAND(kdf_alg)) { psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; - PSA_ASSERT(psa_get_key_attributes(key, &attributes)); + psa_status_t status = psa_get_key_attributes(key, &attributes); + if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) { + /* The key has been destroyed. */ + ok = 1; + } + PSA_ASSERT(status); size_t key_bits = psa_get_key_bits(&attributes); psa_algorithm_t hash_alg = PSA_ALG_HKDF_GET_HASH(kdf_alg); @@ -790,7 +810,8 @@ static int exercise_key_agreement_key(mbedtls_svc_key_id_t key, } } - TEST_EQUAL(mbedtls_test_psa_key_agreement_with_self(&operation, key), + TEST_EQUAL(mbedtls_test_psa_key_agreement_with_self(&operation, key, + key_destroyable), expected_key_agreement_status); if (expected_key_agreement_status != PSA_SUCCESS) { From 3823662208680b91ceb71f2deca1525a4ead4cf9 Mon Sep 17 00:00:00 2001 From: Ryan Everett Date: Tue, 12 Mar 2024 16:32:29 +0000 Subject: [PATCH 13/19] Add key_destroyable parameter to key export smoke tests These are only called from mbedtls_test_psa_exercise_key Signed-off-by: Ryan Everett --- src/psa_exercise_key.c | 62 +++++++++++++++++++++++++++++------------- 1 file changed, 43 insertions(+), 19 deletions(-) diff --git a/src/psa_exercise_key.c b/src/psa_exercise_key.c index 1cf45ac56..5aed683eb 100644 --- a/src/psa_exercise_key.c +++ b/src/psa_exercise_key.c @@ -1002,7 +1002,8 @@ exit: } static int exercise_export_key(mbedtls_svc_key_id_t key, - psa_key_usage_t usage) + psa_key_usage_t usage, + int key_destroyable) { psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; uint8_t *exported = NULL; @@ -1010,25 +1011,31 @@ static int exercise_export_key(mbedtls_svc_key_id_t key, size_t exported_length = 0; int ok = 0; - PSA_ASSERT(psa_get_key_attributes(key, &attributes)); + psa_status_t status = psa_get_key_attributes(key, &attributes); + if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) { + /* The key has been destroyed. */ + psa_reset_key_attributes(&attributes); + return 1; + } + PSA_ASSERT(status); exported_size = PSA_EXPORT_KEY_OUTPUT_SIZE( psa_get_key_type(&attributes), psa_get_key_bits(&attributes)); TEST_CALLOC(exported, exported_size); - if ((usage & PSA_KEY_USAGE_EXPORT) == 0 && - !PSA_KEY_TYPE_IS_PUBLIC_KEY(psa_get_key_type(&attributes))) { - TEST_EQUAL(psa_export_key(key, exported, - exported_size, &exported_length), - PSA_ERROR_NOT_PERMITTED); + status = psa_export_key(key, exported, exported_size, &exported_length); + if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) { + /* The key has been destroyed. */ + ok = 1; + goto exit; + } else if ((usage & PSA_KEY_USAGE_EXPORT) == 0 && + !PSA_KEY_TYPE_IS_PUBLIC_KEY(psa_get_key_type(&attributes))) { + TEST_EQUAL(status, PSA_ERROR_NOT_PERMITTED); ok = 1; goto exit; } - - PSA_ASSERT(psa_export_key(key, - exported, exported_size, - &exported_length)); + PSA_ASSERT(status); ok = mbedtls_test_psa_exported_key_sanity_check( psa_get_key_type(&attributes), psa_get_key_bits(&attributes), exported, exported_length); @@ -1044,7 +1051,8 @@ exit: return ok; } -static int exercise_export_public_key(mbedtls_svc_key_id_t key) +static int exercise_export_public_key(mbedtls_svc_key_id_t key, + int key_destroyable) { psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; psa_key_type_t public_type; @@ -1053,16 +1061,27 @@ static int exercise_export_public_key(mbedtls_svc_key_id_t key) size_t exported_length = 0; int ok = 0; - PSA_ASSERT(psa_get_key_attributes(key, &attributes)); + psa_status_t status = psa_get_key_attributes(key, &attributes); + if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) { + /* The key has been destroyed. */ + psa_reset_key_attributes(&attributes); + return 1; + } + PSA_ASSERT(status); if (!PSA_KEY_TYPE_IS_ASYMMETRIC(psa_get_key_type(&attributes))) { exported_size = PSA_EXPORT_KEY_OUTPUT_SIZE( psa_get_key_type(&attributes), psa_get_key_bits(&attributes)); TEST_CALLOC(exported, exported_size); - TEST_EQUAL(psa_export_public_key(key, exported, - exported_size, &exported_length), - PSA_ERROR_INVALID_ARGUMENT); + status = psa_export_public_key(key, exported, + exported_size, &exported_length); + if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) { + /* The key has been destroyed. */ + ok = 1; + goto exit; + } + TEST_EQUAL(status, PSA_ERROR_INVALID_ARGUMENT); ok = 1; goto exit; } @@ -1073,9 +1092,14 @@ static int exercise_export_public_key(mbedtls_svc_key_id_t key) psa_get_key_bits(&attributes)); TEST_CALLOC(exported, exported_size); - PSA_ASSERT(psa_export_public_key(key, - exported, exported_size, - &exported_length)); + status = psa_export_public_key(key, exported, + exported_size, &exported_length); + if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) { + /* The key has been destroyed. */ + ok = 1; + goto exit; + } + PSA_ASSERT(status); ok = mbedtls_test_psa_exported_key_sanity_check( public_type, psa_get_key_bits(&attributes), exported, exported_length); From bfdaaf75ed5e7f40f45990280f388f743220e142 Mon Sep 17 00:00:00 2001 From: Waleed Elmelegy Date: Fri, 23 Feb 2024 17:51:47 +0000 Subject: [PATCH 14/19] Add ALPN information in session tickets Signed-off-by: Waleed Elmelegy --- src/test_helpers/ssl_helpers.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/test_helpers/ssl_helpers.c b/src/test_helpers/ssl_helpers.c index 56e03f109..89c1bbf52 100644 --- a/src/test_helpers/ssl_helpers.c +++ b/src/test_helpers/ssl_helpers.c @@ -1793,7 +1793,14 @@ int mbedtls_test_ssl_tls13_populate_session(mbedtls_ssl_session *session, #if defined(MBEDTLS_SSL_EARLY_DATA) session->max_early_data_size = 0x87654321; -#endif +#if defined(MBEDTLS_SSL_ALPN) && defined(MBEDTLS_SSL_SRV_C) + session->alpn = mbedtls_calloc(strlen("ALPNExample")+1, sizeof(char)); + if (session->alpn == NULL) { + return -1; + } + strcpy(session->alpn, "ALPNExample"); +#endif /* MBEDTLS_SSL_ALPN && MBEDTLS_SSL_SRV_C */ +#endif /* MBEDTLS_SSL_EARLY_DATA */ #if defined(MBEDTLS_HAVE_TIME) && defined(MBEDTLS_SSL_SRV_C) if (session->endpoint == MBEDTLS_SSL_IS_SERVER) { From f4bd241ab33bff936dff67f514b4844342fd162c Mon Sep 17 00:00:00 2001 From: Waleed Elmelegy Date: Wed, 6 Mar 2024 19:09:41 +0000 Subject: [PATCH 15/19] Add mbedtls_ssl_session_set_alpn() function Signed-off-by: Waleed Elmelegy --- src/test_helpers/ssl_helpers.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/test_helpers/ssl_helpers.c b/src/test_helpers/ssl_helpers.c index 89c1bbf52..9c1676fc6 100644 --- a/src/test_helpers/ssl_helpers.c +++ b/src/test_helpers/ssl_helpers.c @@ -1794,11 +1794,11 @@ int mbedtls_test_ssl_tls13_populate_session(mbedtls_ssl_session *session, #if defined(MBEDTLS_SSL_EARLY_DATA) session->max_early_data_size = 0x87654321; #if defined(MBEDTLS_SSL_ALPN) && defined(MBEDTLS_SSL_SRV_C) - session->alpn = mbedtls_calloc(strlen("ALPNExample")+1, sizeof(char)); - if (session->alpn == NULL) { + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; + ret = mbedtls_ssl_session_set_alpn(session, "ALPNExample"); + if (ret != 0) { return -1; } - strcpy(session->alpn, "ALPNExample"); #endif /* MBEDTLS_SSL_ALPN && MBEDTLS_SSL_SRV_C */ #endif /* MBEDTLS_SSL_EARLY_DATA */ From e98de40b968a02d079ef9db963822f558aef75fd Mon Sep 17 00:00:00 2001 From: Waleed Elmelegy Date: Tue, 12 Mar 2024 16:25:08 +0000 Subject: [PATCH 16/19] Add code improvments and refactoring in dealing with ALPN Signed-off-by: Waleed Elmelegy --- src/test_helpers/ssl_helpers.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/test_helpers/ssl_helpers.c b/src/test_helpers/ssl_helpers.c index 9c1676fc6..963938f1f 100644 --- a/src/test_helpers/ssl_helpers.c +++ b/src/test_helpers/ssl_helpers.c @@ -1794,8 +1794,7 @@ int mbedtls_test_ssl_tls13_populate_session(mbedtls_ssl_session *session, #if defined(MBEDTLS_SSL_EARLY_DATA) session->max_early_data_size = 0x87654321; #if defined(MBEDTLS_SSL_ALPN) && defined(MBEDTLS_SSL_SRV_C) - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - ret = mbedtls_ssl_session_set_alpn(session, "ALPNExample"); + int ret = mbedtls_ssl_session_set_ticket_alpn(session, "ALPNExample"); if (ret != 0) { return -1; } From 8302c74c4fe5132a3c4e9e12608762a9b9c3ab9c Mon Sep 17 00:00:00 2001 From: Ryan Everett Date: Thu, 14 Mar 2024 17:50:39 +0000 Subject: [PATCH 17/19] Add missing PSA_ASSERT in mbedtls_test_psa_raw_key_agreement_with_self Signed-off-by: Ryan Everett --- src/psa_exercise_key.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/psa_exercise_key.c b/src/psa_exercise_key.c index 5aed683eb..937bd45d2 100644 --- a/src/psa_exercise_key.c +++ b/src/psa_exercise_key.c @@ -715,6 +715,7 @@ psa_status_t mbedtls_test_psa_raw_key_agreement_with_self( status = PSA_SUCCESS; goto exit; } + PSA_ASSERT(status); status = psa_raw_key_agreement(alg, key, public_key, public_key_length, From e519cc6807a8f3eac202018c0d22899ef686b075 Mon Sep 17 00:00:00 2001 From: Ryan Everett Date: Thu, 14 Mar 2024 17:51:09 +0000 Subject: [PATCH 18/19] Document unsupported concurrency scenario in psa_exercise_key Signed-off-by: Ryan Everett --- include/test/psa_exercise_key.h | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/include/test/psa_exercise_key.h b/include/test/psa_exercise_key.h index f656b95f8..f6be3073a 100644 --- a/include/test/psa_exercise_key.h +++ b/include/test/psa_exercise_key.h @@ -223,6 +223,14 @@ int mbedtls_test_psa_exported_key_sanity_check( * to 1, while another thread calls psa_destroy_key on the same key; * this will test whether destroying the key in use leads to any corruption. * + * There cannot be a set of concurrent calls: + * `mbedtls_test_psa_exercise_key(ki,...)` such that each ki is a unique + * persistent key not loaded into any key slot, and i is greater than the + * number of free key slots. + * This is because such scenarios can lead to unsupported + * `PSA_ERROR_INSUFFICIENT_MEMORY` return codes. + * + * * \param key The key to exercise. It should be capable of performing * \p alg. * \param usage The usage flags to assume. From 84523d72c999168133bde79e972598f69b701ca2 Mon Sep 17 00:00:00 2001 From: Waleed Elmelegy Date: Thu, 14 Mar 2024 01:48:40 +0000 Subject: [PATCH 19/19] Add ALPN checking when accepting early data Signed-off-by: Waleed Elmelegy --- include/test/ssl_helpers.h | 7 +++++++ src/test_helpers/ssl_helpers.c | 6 ++++++ 2 files changed, 13 insertions(+) diff --git a/include/test/ssl_helpers.h b/include/test/ssl_helpers.h index 335386be1..77f85c496 100644 --- a/include/test/ssl_helpers.h +++ b/include/test/ssl_helpers.h @@ -78,6 +78,10 @@ enum { #undef MBEDTLS_SSL_TLS1_3_LABEL }; +#if defined(MBEDTLS_SSL_ALPN) +#define MBEDTLS_TEST_MAX_ALPN_LIST_SIZE 10 +#endif + typedef struct mbedtls_test_ssl_log_pattern { const char *pattern; size_t counter; @@ -118,6 +122,9 @@ typedef struct mbedtls_test_handshake_test_options { #if defined(MBEDTLS_SSL_CACHE_C) mbedtls_ssl_cache_context *cache; #endif +#if defined(MBEDTLS_SSL_ALPN) + const char *alpn_list[MBEDTLS_TEST_MAX_ALPN_LIST_SIZE]; +#endif } mbedtls_test_handshake_test_options; /* diff --git a/src/test_helpers/ssl_helpers.c b/src/test_helpers/ssl_helpers.c index 963938f1f..55201c0b7 100644 --- a/src/test_helpers/ssl_helpers.c +++ b/src/test_helpers/ssl_helpers.c @@ -833,6 +833,12 @@ int mbedtls_test_ssl_endpoint_init( options->max_early_data_size); } #endif +#if defined(MBEDTLS_SSL_ALPN) + /* check that alpn_list contains at least one valid entry */ + if (options->alpn_list[0] != NULL) { + mbedtls_ssl_conf_alpn_protocols(&(ep->conf), options->alpn_list); + } +#endif #endif #if defined(MBEDTLS_SSL_CACHE_C) && defined(MBEDTLS_SSL_SRV_C)