From 0a271fde761d1692f250a56822a380b640326c30 Mon Sep 17 00:00:00 2001 From: Ryan Everett Date: Tue, 12 Mar 2024 16:34:02 +0000 Subject: [PATCH] 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 --- tests/include/test/psa_exercise_key.h | 18 ++++++++---- tests/src/psa_exercise_key.c | 29 +++++++++++-------- tests/suites/test_suite_pkparse.function | 2 +- tests/suites/test_suite_psa_crypto.function | 22 +++++++------- ...t_suite_psa_crypto_storage_format.function | 2 +- 5 files changed, 43 insertions(+), 30 deletions(-) diff --git a/tests/include/test/psa_exercise_key.h b/tests/include/test/psa_exercise_key.h index 44f5c08aa..fa57d8872 100644 --- a/tests/include/test/psa_exercise_key.h +++ b/tests/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/tests/src/psa_exercise_key.c b/tests/src/psa_exercise_key.c index 7b81052c8..e5cce7939 100644 --- a/tests/src/psa_exercise_key.c +++ b/tests/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; diff --git a/tests/suites/test_suite_pkparse.function b/tests/suites/test_suite_pkparse.function index 7dc8413c8..a06fc30bc 100644 --- a/tests/suites/test_suite_pkparse.function +++ b/tests/suites/test_suite_pkparse.function @@ -57,7 +57,7 @@ static int test_psa_bridge(const mbedtls_pk_context *ctx, if (mbedtls_test_can_exercise_psa_algorithm(exercise_alg)) { TEST_ASSERT(mbedtls_test_psa_exercise_key(psa_key, exercise_usage, - exercise_alg)); + exercise_alg, 0)); } mbedtls_test_set_step((unsigned long) -1); diff --git a/tests/suites/test_suite_psa_crypto.function b/tests/suites/test_suite_psa_crypto.function index 114159799..dfddbb94d 100644 --- a/tests/suites/test_suite_psa_crypto.function +++ b/tests/suites/test_suite_psa_crypto.function @@ -1379,7 +1379,7 @@ void *thread_generate_key(void *ctx) /* Do something with the key according * to its type and permitted usage. */ - if (!mbedtls_test_psa_exercise_key(key, gkc->usage, gkc->alg)) { + if (!mbedtls_test_psa_exercise_key(key, gkc->usage, gkc->alg, 0)) { psa_destroy_key(key); goto exit; } @@ -1715,7 +1715,7 @@ void import_export(data_t *data, * this doesn't directly validate the implementation, but it still helps * by cross-validating the test data with the sanity check code. */ if (!psa_key_lifetime_is_external(lifetime)) { - if (!mbedtls_test_psa_exercise_key(key, usage_arg, 0)) { + if (!mbedtls_test_psa_exercise_key(key, usage_arg, 0, 0)) { goto exit; } } @@ -1853,7 +1853,7 @@ void import_and_exercise_key(data_t *data, TEST_EQUAL(psa_get_key_bits(&got_attributes), bits); /* Do something with the key according to its type and permitted usage. */ - if (!mbedtls_test_psa_exercise_key(key, usage, alg)) { + if (!mbedtls_test_psa_exercise_key(key, usage, alg, 0)) { goto exit; } @@ -2529,10 +2529,10 @@ void key_policy_alg2(int key_type_arg, data_t *key_data, TEST_EQUAL(psa_get_key_algorithm(&got_attributes), alg); TEST_EQUAL(psa_get_key_enrollment_algorithm(&got_attributes), alg2); - if (!mbedtls_test_psa_exercise_key(key, usage, alg)) { + if (!mbedtls_test_psa_exercise_key(key, usage, alg, 0)) { goto exit; } - if (!mbedtls_test_psa_exercise_key(key, usage, alg2)) { + if (!mbedtls_test_psa_exercise_key(key, usage, alg2, 0)) { goto exit; } @@ -2663,10 +2663,10 @@ void copy_success(int source_usage_arg, } if (!psa_key_lifetime_is_external(target_lifetime)) { - if (!mbedtls_test_psa_exercise_key(target_key, expected_usage, expected_alg)) { + if (!mbedtls_test_psa_exercise_key(target_key, expected_usage, expected_alg, 0)) { goto exit; } - if (!mbedtls_test_psa_exercise_key(target_key, expected_usage, expected_alg2)) { + if (!mbedtls_test_psa_exercise_key(target_key, expected_usage, expected_alg2, 0)) { goto exit; } } @@ -9233,7 +9233,7 @@ void derive_key_exercise(int alg_arg, TEST_EQUAL(psa_get_key_bits(&got_attributes), derived_bits); /* Exercise the derived key. */ - if (!mbedtls_test_psa_exercise_key(derived_key, derived_usage, derived_alg)) { + if (!mbedtls_test_psa_exercise_key(derived_key, derived_usage, derived_alg, 0)) { goto exit; } @@ -9941,7 +9941,7 @@ void generate_key(int type_arg, TEST_EQUAL(psa_get_key_bits(&got_attributes), bits); /* Do something with the key according to its type and permitted usage. */ - if (!mbedtls_test_psa_exercise_key(key, usage, alg)) { + if (!mbedtls_test_psa_exercise_key(key, usage, alg, 0)) { goto exit; } @@ -10011,7 +10011,7 @@ void generate_key_ext(int type_arg, #endif /* Do something with the key according to its type and permitted usage. */ - if (!mbedtls_test_psa_exercise_key(key, usage, alg)) { + if (!mbedtls_test_psa_exercise_key(key, usage, alg, 0)) { goto exit; } @@ -10162,7 +10162,7 @@ void persistent_key_load_key_from_storage(data_t *data, } /* Do something with the key according to its type and permitted usage. */ - if (!mbedtls_test_psa_exercise_key(key, usage_flags, alg)) { + if (!mbedtls_test_psa_exercise_key(key, usage_flags, alg, 0)) { goto exit; } diff --git a/tests/suites/test_suite_psa_crypto_storage_format.function b/tests/suites/test_suite_psa_crypto_storage_format.function index bb1e2c68c..efaaba58a 100644 --- a/tests/suites/test_suite_psa_crypto_storage_format.function +++ b/tests/suites/test_suite_psa_crypto_storage_format.function @@ -187,7 +187,7 @@ static int test_read_key(const psa_key_attributes_t *expected_attributes, TEST_ASSERT(mbedtls_test_psa_exercise_key( key_id, psa_get_key_usage_flags(expected_attributes), - psa_get_key_algorithm(expected_attributes))); + psa_get_key_algorithm(expected_attributes), 0)); }