Merge pull request #8924 from Ryan-Everett-arm/threading-same-key-tests

Add testing for concurrently loading/using/destroying the same key
This commit is contained in:
Paul Elliott 2024-03-15 10:24:44 +00:00 committed by GitHub
commit 44ccc8764b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 609 additions and 173 deletions

View File

@ -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().
@ -143,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().
@ -162,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.
*
@ -209,18 +218,34 @@ 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.
* 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.
* \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);

View File

@ -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
@ -110,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,
@ -136,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),
@ -152,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 };
@ -164,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),
@ -188,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));
@ -227,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;
@ -237,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) {
@ -248,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) {
@ -261,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;
@ -291,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);
@ -305,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)) {
@ -321,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) {
@ -332,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);
}
}
@ -346,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) {
@ -357,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);
}
}
@ -372,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...";
@ -380,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 ||
@ -414,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,
@ -432,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,
@ -448,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));
@ -462,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,
@ -486,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";
@ -500,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;
@ -520,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()
@ -560,7 +682,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;
@ -569,25 +692,39 @@ 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;
}
PSA_ASSERT(status);
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,
@ -609,14 +746,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;
@ -626,7 +765,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 };
@ -657,7 +797,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);
@ -666,7 +811,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) {
@ -857,7 +1003,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;
@ -865,25 +1012,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);
@ -899,7 +1052,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;
@ -908,16 +1062,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;
}
@ -928,9 +1093,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);
@ -948,38 +1118,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;

View File

@ -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);

View File

@ -4278,6 +4278,50 @@ PSA import/exercise: TLS 1.2 PRF SHA-256
depends_on:PSA_WANT_ALG_SHA_256:PSA_WANT_ALG_TLS12_PRF
import_and_exercise_key:"c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0":PSA_KEY_TYPE_DERIVE:192:PSA_ALG_TLS12_PRF(PSA_ALG_SHA_256)
PSA concurrently import/exercise same key: RSA keypair, PKCS#1 v1.5 raw
depends_on:PSA_WANT_ALG_RSA_PKCS1V15_SIGN:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_BASIC:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_IMPORT
concurrently_use_same_persistent_key:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":PSA_KEY_TYPE_RSA_KEY_PAIR:1024:PSA_ALG_RSA_PKCS1V15_SIGN_RAW:100
PSA concurrently import/exercise same key: RSA keypair, PSS-SHA-256
depends_on:PSA_WANT_ALG_RSA_PSS:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_BASIC:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_IMPORT
concurrently_use_same_persistent_key:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":PSA_KEY_TYPE_RSA_KEY_PAIR:1024:PSA_ALG_RSA_PSS(PSA_ALG_SHA_256):100
PSA concurrently import/exercise same key: RSA keypair, PSS-any-salt-SHA-256
depends_on:PSA_WANT_ALG_RSA_PSS:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_BASIC:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_IMPORT
concurrently_use_same_persistent_key:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":PSA_KEY_TYPE_RSA_KEY_PAIR:1024:PSA_ALG_RSA_PSS(PSA_ALG_SHA_256):100
PSA concurrently import/exercise same key: RSA public key, PKCS#1 v1.5 raw
depends_on:PSA_WANT_ALG_RSA_PKCS1V15_SIGN:PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY
concurrently_use_same_persistent_key:"30818902818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc30203010001":PSA_KEY_TYPE_RSA_PUBLIC_KEY:1024:PSA_ALG_RSA_PKCS1V15_SIGN_RAW:100
PSA concurrently import/exercise same key: RSA public key, PSS-SHA-256
depends_on:PSA_WANT_ALG_RSA_PSS:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY
concurrently_use_same_persistent_key:"30818902818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc30203010001":PSA_KEY_TYPE_RSA_PUBLIC_KEY:1024:PSA_ALG_RSA_PSS(PSA_ALG_SHA_256):100
PSA concurrently import/exercise same key: RSA public key, PSS-any-salt-SHA-256
depends_on:PSA_WANT_ALG_RSA_PSS:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY
concurrently_use_same_persistent_key:"30818902818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc30203010001":PSA_KEY_TYPE_RSA_PUBLIC_KEY:1024:PSA_ALG_RSA_PSS_ANY_SALT(PSA_ALG_SHA_256):100
PSA concurrently import/exercise same key: ECP SECP256R1 keypair, ECDSA
depends_on:PSA_WANT_ALG_ECDSA:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_BASIC:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_IMPORT:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_EXPORT:PSA_WANT_ECC_SECP_R1_256
concurrently_use_same_persistent_key:"49c9a8c18c4b885638c431cf1df1c994131609b580d4fd43a0cab17db2f13eee":PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):256:PSA_ALG_ECDSA_ANY:100
PSA concurrently import/exercise same key: ECP SECP256R1 keypair, deterministic ECDSA
depends_on:PSA_WANT_ALG_DETERMINISTIC_ECDSA:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_BASIC:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_IMPORT:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_EXPORT:PSA_WANT_ECC_SECP_R1_256
concurrently_use_same_persistent_key:"49c9a8c18c4b885638c431cf1df1c994131609b580d4fd43a0cab17db2f13eee":PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):256:PSA_ALG_DETERMINISTIC_ECDSA( PSA_ALG_SHA_256 ):100
PSA concurrently import/exercise same key: ECP SECP256R1 keypair, ECDH
depends_on:PSA_WANT_ALG_ECDH:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_BASIC:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_IMPORT:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_EXPORT:PSA_WANT_ECC_SECP_R1_256
concurrently_use_same_persistent_key:"49c9a8c18c4b885638c431cf1df1c994131609b580d4fd43a0cab17db2f13eee":PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):256:PSA_ALG_ECDH:100
PSA concurrently import/exercise same key: HKDF SHA-256
depends_on:PSA_WANT_ALG_HKDF:PSA_WANT_ALG_SHA_256
concurrently_use_same_persistent_key:"c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0":PSA_KEY_TYPE_DERIVE:192:PSA_ALG_HKDF(PSA_ALG_SHA_256):100
PSA concurrently import/exercise same key: TLS 1.2 PRF SHA-256
depends_on:PSA_WANT_ALG_SHA_256:PSA_WANT_ALG_TLS12_PRF
concurrently_use_same_persistent_key:"c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0":PSA_KEY_TYPE_DERIVE:192:PSA_ALG_TLS12_PRF(PSA_ALG_SHA_256):100
PSA sign hash: RSA PKCS#1 v1.5, raw
depends_on:PSA_WANT_ALG_RSA_PKCS1V15_SIGN:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_BASIC:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_IMPORT
sign_hash_deterministic:PSA_KEY_TYPE_RSA_KEY_PAIR:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":PSA_ALG_RSA_PKCS1V15_SIGN_RAW:"616263":"2c7744983f023ac7bb1c55529d83ed11a76a7898a1bb5ce191375a4aa7495a633d27879ff58eba5a57371c34feb1180e8b850d552476ebb5634df620261992f12ebee9097041dbbea85a42d45b344be5073ceb772ffc604954b9158ba81ec3dc4d9d65e3ab7aa318165f38c36f841f1c69cb1cfa494aa5cbb4d6c0efbafb043a"

View File

@ -1338,6 +1338,126 @@ exit:
}
#if defined(MBEDTLS_THREADING_PTHREAD)
typedef struct same_key_context {
data_t *data;
mbedtls_svc_key_id_t key;
psa_key_attributes_t *attributes;
int type;
int bits;
/* The following two parameters are used to ensure that when multiple
* threads attempt to load/destroy the key, exactly one thread succeeds. */
int key_loaded;
mbedtls_threading_mutex_t MBEDTLS_PRIVATE(key_loaded_mutex);
}
same_key_context;
/* Attempt to import the key in ctx. This handles any valid error codes
* and reports an error for any invalid codes. This function also insures
* that once imported by some thread, all threads can use the key. */
void *thread_import_key(void *ctx)
{
mbedtls_svc_key_id_t returned_key_id;
same_key_context *skc = (struct same_key_context *) ctx;
psa_key_attributes_t got_attributes = PSA_KEY_ATTRIBUTES_INIT;
/* Import the key, exactly one thread must succeed. */
psa_status_t status = psa_import_key(skc->attributes, skc->data->x,
skc->data->len, &returned_key_id);
switch (status) {
case PSA_SUCCESS:
if (mbedtls_mutex_lock(&skc->key_loaded_mutex) == 0) {
if (skc->key_loaded) {
mbedtls_mutex_unlock(&skc->key_loaded_mutex);
/* More than one thread has succeeded, report a failure. */
TEST_FAIL("The same key has been loaded into the key store multiple times.");
}
skc->key_loaded = 1;
mbedtls_mutex_unlock(&skc->key_loaded_mutex);
}
break;
case PSA_ERROR_INSUFFICIENT_MEMORY:
/* If all of the key slots are reserved when a thread
* locks the mutex to reserve a new slot, it will return
* PSA_ERROR_INSUFFICIENT_MEMORY; this is correct behaviour.
* There is a chance for this to occur here when the number of
* threads running this function is larger than the number of
* free key slots. Each thread reserves an empty key slot,
* unlocks the mutex, then relocks it to finalize key creation.
* It is at that point where the thread sees that the key
* already exists, releases the reserved slot,
* and returns PSA_ERROR_ALREADY_EXISTS.
* There is no guarantee that the key is loaded upon this return
* code, so we can't test the key information. Just stop this
* thread from executing, note that this is not an error. */
goto exit;
break;
case PSA_ERROR_ALREADY_EXISTS:
/* The key has been loaded by a different thread. */
break;
default:
PSA_ASSERT(status);
}
/* At this point the key must exist, test the key information. */
status = psa_get_key_attributes(skc->key, &got_attributes);
if (status == PSA_ERROR_INSUFFICIENT_MEMORY) {
/* This is not a test failure. The following sequence of events
* causes this to occur:
* 1: This thread successfuly imports a persistent key skc->key.
* 2: N threads reserve an empty key slot in psa_import_key,
* where N is equal to the number of free key slots.
* 3: A final thread attempts to reserve an empty key slot, kicking
* skc->key (which has no registered readers) out of its slot.
* 4: This thread calls psa_get_key_attributes(skc->key,...):
* it sees that skc->key is not in a slot, attempts to load it and
* finds that there are no free slots.
* This thread returns PSA_ERROR_INSUFFICIENT_MEMORY.
*
* The PSA spec allows this behaviour, it is an unavoidable consequence
* of allowing persistent keys to be kicked out of the key store while
* they are still valid. */
goto exit;
}
PSA_ASSERT(status);
TEST_EQUAL(psa_get_key_type(&got_attributes), skc->type);
TEST_EQUAL(psa_get_key_bits(&got_attributes), skc->bits);
exit:
/* Key attributes may have been returned by psa_get_key_attributes(),
* reset them as required. */
psa_reset_key_attributes(&got_attributes);
return NULL;
}
void *thread_use_and_destroy_key(void *ctx)
{
same_key_context *skc = (struct same_key_context *) ctx;
/* Do something with the key according
* to its type and permitted usage. */
TEST_ASSERT(mbedtls_test_psa_exercise_key(skc->key,
skc->attributes->policy.usage,
skc->attributes->policy.alg, 1));
psa_status_t status = psa_destroy_key(skc->key);
if (status == PSA_SUCCESS) {
if (mbedtls_mutex_lock(&skc->key_loaded_mutex) == 0) {
/* Ensure that we are the only thread to succeed. */
if (skc->key_loaded != 1) {
mbedtls_mutex_unlock(&skc->key_loaded_mutex);
TEST_FAIL("The same key has been destroyed multiple times.");
}
skc->key_loaded = 0;
mbedtls_mutex_unlock(&skc->key_loaded_mutex);
}
} else {
TEST_EQUAL(status, PSA_ERROR_INVALID_HANDLE);
}
exit:
return NULL;
}
typedef struct generate_key_context {
psa_key_type_t type;
psa_key_usage_t usage;
@ -1379,7 +1499,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 +1835,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;
}
}
@ -1824,6 +1944,78 @@ exit:
}
/* END_CASE */
#if defined(MBEDTLS_THREADING_PTHREAD)
/* BEGIN_CASE depends_on:MBEDTLS_THREADING_PTHREAD:MBEDTLS_PSA_CRYPTO_STORAGE_C */
void concurrently_use_same_persistent_key(data_t *data,
int type_arg,
int bits_arg,
int alg_arg,
int thread_count_arg)
{
size_t thread_count = (size_t) thread_count_arg;
mbedtls_test_thread_t *threads = NULL;
mbedtls_svc_key_id_t key_id = mbedtls_svc_key_id_make(1, 1);
same_key_context skc;
skc.data = data;
skc.key = key_id;
skc.type = type_arg;
skc.bits = bits_arg;
skc.key_loaded = 0;
mbedtls_mutex_init(&skc.key_loaded_mutex);
psa_key_usage_t usage = mbedtls_test_psa_usage_to_exercise(skc.type, alg_arg);
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
PSA_ASSERT(psa_crypto_init());
psa_set_key_id(&attributes, key_id);
psa_set_key_lifetime(&attributes, PSA_KEY_LIFETIME_PERSISTENT);
psa_set_key_usage_flags(&attributes, usage);
psa_set_key_algorithm(&attributes, alg_arg);
psa_set_key_type(&attributes, type_arg);
psa_set_key_bits(&attributes, bits_arg);
skc.attributes = &attributes;
TEST_CALLOC(threads, sizeof(mbedtls_test_thread_t) * thread_count);
/* Test that when multiple threads import the same key,
* exactly one thread succeeds and the rest fail with valid errors.
* Also test that all threads can use the key as soon as it has been
* imported. */
for (size_t i = 0; i < thread_count; i++) {
TEST_EQUAL(
mbedtls_test_thread_create(&threads[i], thread_import_key,
(void *) &skc), 0);
}
/* Join threads. */
for (size_t i = 0; i < thread_count; i++) {
TEST_EQUAL(mbedtls_test_thread_join(&threads[i]), 0);
}
/* Test that when multiple threads use and destroy a key no corruption
* occurs, and exactly one thread succeeds when destroying the key. */
for (size_t i = 0; i < thread_count; i++) {
TEST_EQUAL(
mbedtls_test_thread_create(&threads[i], thread_use_and_destroy_key,
(void *) &skc), 0);
}
/* Join threads. */
for (size_t i = 0; i < thread_count; i++) {
TEST_EQUAL(mbedtls_test_thread_join(&threads[i]), 0);
}
/* Ensure that one thread succeeded in destroying the key. */
TEST_ASSERT(!skc.key_loaded);
exit:
psa_reset_key_attributes(&attributes);
mbedtls_mutex_free(&skc.key_loaded_mutex);
mbedtls_free(threads);
PSA_DONE();
}
/* END_CASE */
#endif
/* BEGIN_CASE */
void import_and_exercise_key(data_t *data,
int type_arg,
@ -1853,7 +2045,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;
}
@ -2490,7 +2682,7 @@ void agreement_key_policy(int policy_usage,
&key));
PSA_ASSERT(psa_key_derivation_setup(&operation, exercise_alg));
status = mbedtls_test_psa_key_agreement_with_self(&operation, key);
status = mbedtls_test_psa_key_agreement_with_self(&operation, key, 0);
TEST_EQUAL(status, expected_status);
@ -2529,10 +2721,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;
}
@ -2572,7 +2764,7 @@ void raw_agreement_key_policy(int policy_usage,
PSA_ASSERT(psa_import_key(&attributes, key_data->x, key_data->len,
&key));
status = mbedtls_test_psa_raw_key_agreement_with_self(exercise_alg, key);
status = mbedtls_test_psa_raw_key_agreement_with_self(exercise_alg, key, 0);
TEST_EQUAL(status, expected_status);
@ -2663,10 +2855,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;
}
}
@ -8681,7 +8873,7 @@ void derive_input(int alg_arg,
// When taking a private key as secret input, use key agreement
// to add the shared secret to the derivation
TEST_EQUAL(mbedtls_test_psa_key_agreement_with_self(
&operation, keys[i]),
&operation, keys[i], 0),
expected_statuses[i]);
} else {
TEST_EQUAL(psa_key_derivation_input_key(&operation, steps[i],
@ -8780,7 +8972,7 @@ void derive_over_capacity(int alg_arg)
if (!mbedtls_test_psa_setup_key_derivation_wrap(&operation, key, alg,
input1, input1_length,
input2, input2_length,
capacity)) {
capacity, 0)) {
goto exit;
}
@ -9099,7 +9291,7 @@ void derive_full(int alg_arg,
if (!mbedtls_test_psa_setup_key_derivation_wrap(&operation, key, alg,
input1->x, input1->len,
input2->x, input2->len,
requested_capacity)) {
requested_capacity, 0)) {
goto exit;
}
@ -9216,7 +9408,7 @@ void derive_key_exercise(int alg_arg,
if (!mbedtls_test_psa_setup_key_derivation_wrap(&operation, base_key, alg,
input1->x, input1->len,
input2->x, input2->len,
capacity)) {
capacity, 0)) {
goto exit;
}
@ -9233,7 +9425,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;
}
@ -9286,7 +9478,7 @@ void derive_key_export(int alg_arg,
if (!mbedtls_test_psa_setup_key_derivation_wrap(&operation, base_key, alg,
input1->x, input1->len,
input2->x, input2->len,
capacity)) {
capacity, 0)) {
goto exit;
}
@ -9299,7 +9491,7 @@ void derive_key_export(int alg_arg,
if (!mbedtls_test_psa_setup_key_derivation_wrap(&operation, base_key, alg,
input1->x, input1->len,
input2->x, input2->len,
capacity)) {
capacity, 0)) {
goto exit;
}
@ -9370,7 +9562,7 @@ void derive_key_type(int alg_arg,
&operation, base_key, alg,
input1->x, input1->len,
input2->x, input2->len,
PSA_KEY_DERIVATION_UNLIMITED_CAPACITY) == 0) {
PSA_KEY_DERIVATION_UNLIMITED_CAPACITY, 0) == 0) {
goto exit;
}
@ -9435,7 +9627,7 @@ void derive_key_ext(int alg_arg,
&operation, base_key, alg,
input1->x, input1->len,
input2->x, input2->len,
PSA_KEY_DERIVATION_UNLIMITED_CAPACITY) == 0) {
PSA_KEY_DERIVATION_UNLIMITED_CAPACITY, 0) == 0) {
goto exit;
}
@ -9499,7 +9691,7 @@ void derive_key(int alg_arg,
if (!mbedtls_test_psa_setup_key_derivation_wrap(&operation, base_key, alg,
input1->x, input1->len,
input2->x, input2->len,
SIZE_MAX)) {
SIZE_MAX, 0)) {
goto exit;
}
@ -9941,7 +10133,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 +10203,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 +10354,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;
}

View File

@ -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));
}