mirror of
https://github.com/Mbed-TLS/mbedtls-framework.git
synced 2026-09-17 15:49:54 +00:00
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:
@@ -123,6 +123,9 @@
|
|||||||
* \param input2 The first input to pass.
|
* \param input2 The first input to pass.
|
||||||
* \param input2_length The length of \p input2 in bytes.
|
* \param input2_length The length of \p input2 in bytes.
|
||||||
* \param capacity The capacity to set.
|
* \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.
|
* \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,
|
psa_algorithm_t alg,
|
||||||
const unsigned char *input1, size_t input1_length,
|
const unsigned char *input1, size_t input1_length,
|
||||||
const unsigned char *input2, size_t input2_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
|
/** Perform a key agreement using the given key pair against its public key
|
||||||
* using psa_raw_key_agreement().
|
* 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 alg A key agreement algorithm compatible with \p key.
|
||||||
* \param key A key that allows key agreement with \p alg.
|
* \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.
|
* \return \c 1 on success, \c 0 on failure.
|
||||||
*/
|
*/
|
||||||
psa_status_t mbedtls_test_psa_raw_key_agreement_with_self(
|
psa_status_t mbedtls_test_psa_raw_key_agreement_with_self(
|
||||||
psa_algorithm_t alg,
|
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
|
/** Perform a key agreement using the given key pair against its public key
|
||||||
* using psa_key_derivation_raw_key().
|
* using psa_key_derivation_raw_key().
|
||||||
@@ -162,12 +168,15 @@ psa_status_t mbedtls_test_psa_raw_key_agreement_with_self(
|
|||||||
* \p key.
|
* \p key.
|
||||||
* \param key A key pair object that is suitable for a key
|
* \param key A key pair object that is suitable for a key
|
||||||
* agreement with \p operation.
|
* 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.
|
* \return \c 1 on success, \c 0 on failure.
|
||||||
*/
|
*/
|
||||||
psa_status_t mbedtls_test_psa_key_agreement_with_self(
|
psa_status_t mbedtls_test_psa_key_agreement_with_self(
|
||||||
psa_key_derivation_operation_t *operation,
|
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.
|
/** 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;
|
* 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
|
* There cannot be a set of concurrent calls:
|
||||||
* \p alg.
|
* `mbedtls_test_psa_exercise_key(ki,...)` such that each ki is a unique
|
||||||
* \param usage The usage flags to assume.
|
* persistent key not loaded into any key slot, and i is greater than the
|
||||||
* \param alg The algorithm to exercise.
|
* 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 0 The key failed the smoke tests.
|
||||||
* \retval 1 The key passed the smoke tests.
|
* \retval 1 The key passed the smoke tests.
|
||||||
*/
|
*/
|
||||||
int mbedtls_test_psa_exercise_key(mbedtls_svc_key_id_t key,
|
int mbedtls_test_psa_exercise_key(mbedtls_svc_key_id_t key,
|
||||||
psa_key_usage_t usage,
|
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_key_usage_t mbedtls_test_psa_usage_to_exercise(psa_key_type_t type,
|
||||||
psa_algorithm_t alg);
|
psa_algorithm_t alg);
|
||||||
|
|||||||
+316
-141
@@ -38,7 +38,8 @@ static int lifetime_is_dynamic_secure_element(psa_key_lifetime_t lifetime)
|
|||||||
}
|
}
|
||||||
#endif
|
#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;
|
int ok = 0;
|
||||||
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
|
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;
|
mbedtls_svc_key_id_t id;
|
||||||
psa_key_type_t type;
|
psa_key_type_t type;
|
||||||
size_t bits;
|
size_t bits;
|
||||||
|
psa_status_t status = psa_get_key_attributes(key, &attributes);
|
||||||
PSA_ASSERT(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);
|
lifetime = psa_get_key_lifetime(&attributes);
|
||||||
id = psa_get_key_id(&attributes);
|
id = psa_get_key_id(&attributes);
|
||||||
type = psa_get_key_type(&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));
|
(MBEDTLS_SVC_KEY_ID_GET_KEY_ID(id) <= PSA_KEY_ID_USER_MAX));
|
||||||
}
|
}
|
||||||
#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
|
#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
|
||||||
/* randomly-generated 64-bit constant, should never appear in test data */
|
/* MBEDTLS_PSA_CRYPTO_SE_C does not support thread safety. */
|
||||||
psa_key_slot_number_t slot_number = 0xec94d4a5058a1a21;
|
if (key_destroyable == 0) {
|
||||||
psa_status_t status = psa_get_key_slot_number(&attributes, &slot_number);
|
/* randomly-generated 64-bit constant, should never appear in test data */
|
||||||
if (lifetime_is_dynamic_secure_element(lifetime)) {
|
psa_key_slot_number_t slot_number = 0xec94d4a5058a1a21;
|
||||||
/* Mbed TLS currently always exposes the slot number to
|
status = psa_get_key_slot_number(&attributes, &slot_number);
|
||||||
* applications. This is not mandated by the PSA specification
|
if (lifetime_is_dynamic_secure_element(lifetime)) {
|
||||||
* and may change in future versions. */
|
/* Mbed TLS currently always exposes the slot number to
|
||||||
TEST_EQUAL(status, 0);
|
* applications. This is not mandated by the PSA specification
|
||||||
TEST_ASSERT(slot_number != 0xec94d4a5058a1a21);
|
* and may change in future versions. */
|
||||||
} else {
|
TEST_EQUAL(status, 0);
|
||||||
TEST_EQUAL(status, PSA_ERROR_INVALID_ARGUMENT);
|
TEST_ASSERT(slot_number != 0xec94d4a5058a1a21);
|
||||||
|
} else {
|
||||||
|
TEST_EQUAL(status, PSA_ERROR_INVALID_ARGUMENT);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -110,20 +119,27 @@ exit:
|
|||||||
|
|
||||||
static int exercise_mac_key(mbedtls_svc_key_id_t key,
|
static int exercise_mac_key(mbedtls_svc_key_id_t key,
|
||||||
psa_key_usage_t usage,
|
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;
|
psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT;
|
||||||
const unsigned char input[] = "foo";
|
const unsigned char input[] = "foo";
|
||||||
unsigned char mac[PSA_MAC_MAX_SIZE] = { 0 };
|
unsigned char mac[PSA_MAC_MAX_SIZE] = { 0 };
|
||||||
size_t mac_length = sizeof(mac);
|
size_t mac_length = sizeof(mac);
|
||||||
|
psa_status_t status = PSA_SUCCESS;
|
||||||
/* Convert wildcard algorithm to exercisable algorithm */
|
/* Convert wildcard algorithm to exercisable algorithm */
|
||||||
if (alg & PSA_ALG_MAC_AT_LEAST_THIS_LENGTH_FLAG) {
|
if (alg & PSA_ALG_MAC_AT_LEAST_THIS_LENGTH_FLAG) {
|
||||||
alg = PSA_ALG_TRUNCATED_MAC(alg, PSA_MAC_TRUNCATED_LENGTH(alg));
|
alg = PSA_ALG_TRUNCATED_MAC(alg, PSA_MAC_TRUNCATED_LENGTH(alg));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (usage & PSA_KEY_USAGE_SIGN_HASH) {
|
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,
|
PSA_ASSERT(psa_mac_update(&operation,
|
||||||
input, sizeof(input)));
|
input, sizeof(input)));
|
||||||
PSA_ASSERT(psa_mac_sign_finish(&operation,
|
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 ?
|
(usage & PSA_KEY_USAGE_SIGN_HASH ?
|
||||||
PSA_SUCCESS :
|
PSA_SUCCESS :
|
||||||
PSA_ERROR_INVALID_SIGNATURE);
|
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,
|
PSA_ASSERT(psa_mac_update(&operation,
|
||||||
input, sizeof(input)));
|
input, sizeof(input)));
|
||||||
TEST_EQUAL(psa_mac_verify_finish(&operation, mac, mac_length),
|
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,
|
static int exercise_cipher_key(mbedtls_svc_key_id_t key,
|
||||||
psa_key_usage_t usage,
|
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;
|
psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
|
||||||
unsigned char iv[PSA_CIPHER_IV_MAX_SIZE] = { 0 };
|
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);
|
size_t ciphertext_length = sizeof(ciphertext);
|
||||||
unsigned char decrypted[sizeof(ciphertext)];
|
unsigned char decrypted[sizeof(ciphertext)];
|
||||||
size_t part_length;
|
size_t part_length;
|
||||||
|
psa_status_t status = PSA_SUCCESS;
|
||||||
|
|
||||||
PSA_ASSERT(psa_get_key_attributes(key, &attributes));
|
PSA_ASSERT(psa_get_key_attributes(key, &attributes));
|
||||||
key_type = psa_get_key_type(&attributes);
|
key_type = psa_get_key_type(&attributes);
|
||||||
iv_length = PSA_CIPHER_IV_LENGTH(key_type, alg);
|
iv_length = PSA_CIPHER_IV_LENGTH(key_type, alg);
|
||||||
|
|
||||||
if (usage & PSA_KEY_USAGE_ENCRYPT) {
|
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) {
|
if (iv_length != 0) {
|
||||||
PSA_ASSERT(psa_cipher_generate_iv(&operation,
|
PSA_ASSERT(psa_cipher_generate_iv(&operation,
|
||||||
iv, sizeof(iv),
|
iv, sizeof(iv),
|
||||||
@@ -188,12 +218,17 @@ static int exercise_cipher_key(mbedtls_svc_key_id_t key,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (usage & PSA_KEY_USAGE_DECRYPT) {
|
if (usage & PSA_KEY_USAGE_DECRYPT) {
|
||||||
psa_status_t status;
|
|
||||||
int maybe_invalid_padding = 0;
|
int maybe_invalid_padding = 0;
|
||||||
if (!(usage & PSA_KEY_USAGE_ENCRYPT)) {
|
if (!(usage & PSA_KEY_USAGE_ENCRYPT)) {
|
||||||
maybe_invalid_padding = !PSA_ALG_IS_STREAM_CIPHER(alg);
|
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) {
|
if (iv_length != 0) {
|
||||||
PSA_ASSERT(psa_cipher_set_iv(&operation,
|
PSA_ASSERT(psa_cipher_set_iv(&operation,
|
||||||
iv, iv_length));
|
iv, iv_length));
|
||||||
@@ -227,7 +262,8 @@ exit:
|
|||||||
|
|
||||||
static int exercise_aead_key(mbedtls_svc_key_id_t key,
|
static int exercise_aead_key(mbedtls_svc_key_id_t key,
|
||||||
psa_key_usage_t usage,
|
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 };
|
unsigned char nonce[PSA_AEAD_NONCE_MAX_SIZE] = { 0 };
|
||||||
size_t nonce_length;
|
size_t nonce_length;
|
||||||
@@ -237,6 +273,7 @@ static int exercise_aead_key(mbedtls_svc_key_id_t key,
|
|||||||
unsigned char ciphertext[48] = "(wabblewebblewibblewobblewubble)";
|
unsigned char ciphertext[48] = "(wabblewebblewibblewobblewubble)";
|
||||||
size_t ciphertext_length = sizeof(ciphertext);
|
size_t ciphertext_length = sizeof(ciphertext);
|
||||||
size_t plaintext_length = sizeof(ciphertext);
|
size_t plaintext_length = sizeof(ciphertext);
|
||||||
|
psa_status_t status = PSA_SUCCESS;
|
||||||
|
|
||||||
/* Convert wildcard algorithm to exercisable algorithm */
|
/* Convert wildcard algorithm to exercisable algorithm */
|
||||||
if (alg & PSA_ALG_AEAD_AT_LEAST_THIS_LENGTH_FLAG) {
|
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);
|
nonce_length = PSA_AEAD_NONCE_LENGTH(key_type, alg);
|
||||||
|
|
||||||
if (usage & PSA_KEY_USAGE_ENCRYPT) {
|
if (usage & PSA_KEY_USAGE_ENCRYPT) {
|
||||||
PSA_ASSERT(psa_aead_encrypt(key, alg,
|
status = psa_aead_encrypt(key, alg,
|
||||||
nonce, nonce_length,
|
nonce, nonce_length,
|
||||||
NULL, 0,
|
NULL, 0,
|
||||||
plaintext, sizeof(plaintext),
|
plaintext, sizeof(plaintext),
|
||||||
ciphertext, sizeof(ciphertext),
|
ciphertext, sizeof(ciphertext),
|
||||||
&ciphertext_length));
|
&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) {
|
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 ?
|
(usage & PSA_KEY_USAGE_ENCRYPT ?
|
||||||
PSA_SUCCESS :
|
PSA_SUCCESS :
|
||||||
PSA_ERROR_INVALID_SIGNATURE);
|
PSA_ERROR_INVALID_SIGNATURE);
|
||||||
TEST_EQUAL(psa_aead_decrypt(key, alg,
|
status = psa_aead_decrypt(key, alg,
|
||||||
nonce, nonce_length,
|
nonce, nonce_length,
|
||||||
NULL, 0,
|
NULL, 0,
|
||||||
ciphertext, ciphertext_length,
|
ciphertext, ciphertext_length,
|
||||||
plaintext, sizeof(plaintext),
|
plaintext, sizeof(plaintext),
|
||||||
&plaintext_length),
|
&plaintext_length);
|
||||||
verify_status);
|
if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
|
||||||
|
/* The key has been destroyed. */
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
TEST_ASSERT(status == verify_status);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 1;
|
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,
|
static int exercise_signature_key(mbedtls_svc_key_id_t key,
|
||||||
psa_key_usage_t usage,
|
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. */
|
/* If the policy allows signing with any hash, just pick one. */
|
||||||
psa_algorithm_t hash_alg = PSA_ALG_SIGN_GET_HASH(alg);
|
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");
|
TEST_FAIL("No hash algorithm for hash-and-sign testing");
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
psa_status_t status = PSA_SUCCESS;
|
||||||
|
|
||||||
if (usage & (PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH) &&
|
if (usage & (PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH) &&
|
||||||
PSA_ALG_IS_SIGN_HASH(alg)) {
|
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) {
|
if (usage & PSA_KEY_USAGE_SIGN_HASH) {
|
||||||
PSA_ASSERT(psa_sign_hash(key, alg,
|
status = psa_sign_hash(key, alg,
|
||||||
payload, payload_length,
|
payload, payload_length,
|
||||||
signature, sizeof(signature),
|
signature, sizeof(signature),
|
||||||
&signature_length));
|
&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) {
|
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 ?
|
(usage & PSA_KEY_USAGE_SIGN_HASH ?
|
||||||
PSA_SUCCESS :
|
PSA_SUCCESS :
|
||||||
PSA_ERROR_INVALID_SIGNATURE);
|
PSA_ERROR_INVALID_SIGNATURE);
|
||||||
TEST_EQUAL(psa_verify_hash(key, alg,
|
status = psa_verify_hash(key, alg,
|
||||||
payload, payload_length,
|
payload, payload_length,
|
||||||
signature, signature_length),
|
signature, signature_length);
|
||||||
verify_status);
|
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);
|
size_t signature_length = sizeof(signature);
|
||||||
|
|
||||||
if (usage & PSA_KEY_USAGE_SIGN_MESSAGE) {
|
if (usage & PSA_KEY_USAGE_SIGN_MESSAGE) {
|
||||||
PSA_ASSERT(psa_sign_message(key, alg,
|
status = psa_sign_message(key, alg,
|
||||||
message, message_length,
|
message, message_length,
|
||||||
signature, sizeof(signature),
|
signature, sizeof(signature),
|
||||||
&signature_length));
|
&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) {
|
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 ?
|
(usage & PSA_KEY_USAGE_SIGN_MESSAGE ?
|
||||||
PSA_SUCCESS :
|
PSA_SUCCESS :
|
||||||
PSA_ERROR_INVALID_SIGNATURE);
|
PSA_ERROR_INVALID_SIGNATURE);
|
||||||
TEST_EQUAL(psa_verify_message(key, alg,
|
status = psa_verify_message(key, alg,
|
||||||
message, message_length,
|
message, message_length,
|
||||||
signature, signature_length),
|
signature, signature_length);
|
||||||
verify_status);
|
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,
|
static int exercise_asymmetric_encryption_key(mbedtls_svc_key_id_t key,
|
||||||
psa_key_usage_t usage,
|
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] =
|
unsigned char plaintext[PSA_ASYMMETRIC_DECRYPT_OUTPUT_MAX_SIZE] =
|
||||||
"Hello, world...";
|
"Hello, world...";
|
||||||
@@ -380,22 +447,30 @@ static int exercise_asymmetric_encryption_key(mbedtls_svc_key_id_t key,
|
|||||||
"(wabblewebblewibblewobblewubble)";
|
"(wabblewebblewibblewobblewubble)";
|
||||||
size_t ciphertext_length = sizeof(ciphertext);
|
size_t ciphertext_length = sizeof(ciphertext);
|
||||||
size_t plaintext_length = 16;
|
size_t plaintext_length = 16;
|
||||||
|
psa_status_t status = PSA_SUCCESS;
|
||||||
if (usage & PSA_KEY_USAGE_ENCRYPT) {
|
if (usage & PSA_KEY_USAGE_ENCRYPT) {
|
||||||
PSA_ASSERT(psa_asymmetric_encrypt(key, alg,
|
status = psa_asymmetric_encrypt(key, alg,
|
||||||
plaintext, plaintext_length,
|
plaintext, plaintext_length,
|
||||||
NULL, 0,
|
NULL, 0,
|
||||||
ciphertext, sizeof(ciphertext),
|
ciphertext, sizeof(ciphertext),
|
||||||
&ciphertext_length));
|
&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) {
|
if (usage & PSA_KEY_USAGE_DECRYPT) {
|
||||||
psa_status_t status =
|
status = psa_asymmetric_decrypt(key, alg,
|
||||||
psa_asymmetric_decrypt(key, alg,
|
ciphertext, ciphertext_length,
|
||||||
ciphertext, ciphertext_length,
|
NULL, 0,
|
||||||
NULL, 0,
|
plaintext, sizeof(plaintext),
|
||||||
plaintext, sizeof(plaintext),
|
&plaintext_length);
|
||||||
&plaintext_length);
|
if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
|
||||||
|
/* The key has been destroyed. */
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
TEST_ASSERT(status == PSA_SUCCESS ||
|
TEST_ASSERT(status == PSA_SUCCESS ||
|
||||||
((usage & PSA_KEY_USAGE_ENCRYPT) == 0 &&
|
((usage & PSA_KEY_USAGE_ENCRYPT) == 0 &&
|
||||||
(status == PSA_ERROR_INVALID_ARGUMENT ||
|
(status == PSA_ERROR_INVALID_ARGUMENT ||
|
||||||
@@ -414,16 +489,22 @@ int mbedtls_test_psa_setup_key_derivation_wrap(
|
|||||||
psa_algorithm_t alg,
|
psa_algorithm_t alg,
|
||||||
const unsigned char *input1, size_t input1_length,
|
const unsigned char *input1, size_t input1_length,
|
||||||
const unsigned char *input2, size_t input2_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_ASSERT(psa_key_derivation_setup(operation, alg));
|
||||||
|
psa_status_t status = PSA_SUCCESS;
|
||||||
if (PSA_ALG_IS_HKDF(alg)) {
|
if (PSA_ALG_IS_HKDF(alg)) {
|
||||||
PSA_ASSERT(psa_key_derivation_input_bytes(operation,
|
PSA_ASSERT(psa_key_derivation_input_bytes(operation,
|
||||||
PSA_KEY_DERIVATION_INPUT_SALT,
|
PSA_KEY_DERIVATION_INPUT_SALT,
|
||||||
input1, input1_length));
|
input1, input1_length));
|
||||||
PSA_ASSERT(psa_key_derivation_input_key(operation,
|
status = psa_key_derivation_input_key(operation,
|
||||||
PSA_KEY_DERIVATION_INPUT_SECRET,
|
PSA_KEY_DERIVATION_INPUT_SECRET,
|
||||||
key));
|
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_ASSERT(psa_key_derivation_input_bytes(operation,
|
||||||
PSA_KEY_DERIVATION_INPUT_INFO,
|
PSA_KEY_DERIVATION_INPUT_INFO,
|
||||||
input2,
|
input2,
|
||||||
@@ -432,13 +513,23 @@ int mbedtls_test_psa_setup_key_derivation_wrap(
|
|||||||
PSA_ASSERT(psa_key_derivation_input_bytes(operation,
|
PSA_ASSERT(psa_key_derivation_input_bytes(operation,
|
||||||
PSA_KEY_DERIVATION_INPUT_SALT,
|
PSA_KEY_DERIVATION_INPUT_SALT,
|
||||||
input1, input1_length));
|
input1, input1_length));
|
||||||
PSA_ASSERT(psa_key_derivation_input_key(operation,
|
status = psa_key_derivation_input_key(operation,
|
||||||
PSA_KEY_DERIVATION_INPUT_SECRET,
|
PSA_KEY_DERIVATION_INPUT_SECRET,
|
||||||
key));
|
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)) {
|
} else if (PSA_ALG_IS_HKDF_EXPAND(alg)) {
|
||||||
PSA_ASSERT(psa_key_derivation_input_key(operation,
|
status = psa_key_derivation_input_key(operation,
|
||||||
PSA_KEY_DERIVATION_INPUT_SECRET,
|
PSA_KEY_DERIVATION_INPUT_SECRET,
|
||||||
key));
|
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_ASSERT(psa_key_derivation_input_bytes(operation,
|
||||||
PSA_KEY_DERIVATION_INPUT_INFO,
|
PSA_KEY_DERIVATION_INPUT_INFO,
|
||||||
input2,
|
input2,
|
||||||
@@ -448,9 +539,14 @@ int mbedtls_test_psa_setup_key_derivation_wrap(
|
|||||||
PSA_ASSERT(psa_key_derivation_input_bytes(operation,
|
PSA_ASSERT(psa_key_derivation_input_bytes(operation,
|
||||||
PSA_KEY_DERIVATION_INPUT_SEED,
|
PSA_KEY_DERIVATION_INPUT_SEED,
|
||||||
input1, input1_length));
|
input1, input1_length));
|
||||||
PSA_ASSERT(psa_key_derivation_input_key(operation,
|
status = psa_key_derivation_input_key(operation,
|
||||||
PSA_KEY_DERIVATION_INPUT_SECRET,
|
PSA_KEY_DERIVATION_INPUT_SECRET,
|
||||||
key));
|
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_ASSERT(psa_key_derivation_input_bytes(operation,
|
||||||
PSA_KEY_DERIVATION_INPUT_LABEL,
|
PSA_KEY_DERIVATION_INPUT_LABEL,
|
||||||
input2, input2_length));
|
input2, input2_length));
|
||||||
@@ -462,9 +558,14 @@ int mbedtls_test_psa_setup_key_derivation_wrap(
|
|||||||
PSA_KEY_DERIVATION_INPUT_SALT,
|
PSA_KEY_DERIVATION_INPUT_SALT,
|
||||||
input2,
|
input2,
|
||||||
input2_length));
|
input2_length));
|
||||||
PSA_ASSERT(psa_key_derivation_input_key(operation,
|
status = psa_key_derivation_input_key(operation,
|
||||||
PSA_KEY_DERIVATION_INPUT_PASSWORD,
|
PSA_KEY_DERIVATION_INPUT_PASSWORD,
|
||||||
key));
|
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) {
|
} else if (alg == PSA_ALG_TLS12_ECJPAKE_TO_PMS) {
|
||||||
PSA_ASSERT(psa_key_derivation_input_bytes(operation,
|
PSA_ASSERT(psa_key_derivation_input_bytes(operation,
|
||||||
PSA_KEY_DERIVATION_INPUT_SECRET,
|
PSA_KEY_DERIVATION_INPUT_SECRET,
|
||||||
@@ -486,7 +587,8 @@ exit:
|
|||||||
|
|
||||||
static int exercise_key_derivation_key(mbedtls_svc_key_id_t key,
|
static int exercise_key_derivation_key(mbedtls_svc_key_id_t key,
|
||||||
psa_key_usage_t usage,
|
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;
|
psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
|
||||||
unsigned char input1[] = "Input 1";
|
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,
|
if (!mbedtls_test_psa_setup_key_derivation_wrap(&operation, key, alg,
|
||||||
input1, input1_length,
|
input1, input1_length,
|
||||||
input2, input2_length,
|
input2, input2_length,
|
||||||
capacity)) {
|
capacity, key_destroyable)) {
|
||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
PSA_ASSERT(psa_key_derivation_output_bytes(&operation,
|
psa_status_t status = psa_key_derivation_output_bytes(&operation,
|
||||||
output,
|
output,
|
||||||
capacity));
|
capacity);
|
||||||
PSA_ASSERT(psa_key_derivation_abort(&operation));
|
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;
|
return 1;
|
||||||
@@ -520,31 +628,45 @@ exit:
|
|||||||
* private key against its own public key. */
|
* private key against its own public key. */
|
||||||
psa_status_t mbedtls_test_psa_key_agreement_with_self(
|
psa_status_t mbedtls_test_psa_key_agreement_with_self(
|
||||||
psa_key_derivation_operation_t *operation,
|
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 private_key_type;
|
||||||
psa_key_type_t public_key_type;
|
psa_key_type_t public_key_type;
|
||||||
size_t key_bits;
|
size_t key_bits;
|
||||||
uint8_t *public_key = NULL;
|
uint8_t *public_key = NULL;
|
||||||
size_t public_key_length;
|
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_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);
|
private_key_type = psa_get_key_type(&attributes);
|
||||||
key_bits = psa_get_key_bits(&attributes);
|
key_bits = psa_get_key_bits(&attributes);
|
||||||
public_key_type = PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(private_key_type);
|
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);
|
public_key_length = PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(public_key_type, key_bits);
|
||||||
TEST_CALLOC(public_key, public_key_length);
|
TEST_CALLOC(public_key, public_key_length);
|
||||||
PSA_ASSERT(psa_export_public_key(key, public_key, public_key_length,
|
status = psa_export_public_key(key, public_key, public_key_length,
|
||||||
&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(
|
status = psa_key_derivation_key_agreement(
|
||||||
operation, PSA_KEY_DERIVATION_INPUT_SECRET, key,
|
operation, PSA_KEY_DERIVATION_INPUT_SECRET, key,
|
||||||
public_key, public_key_length);
|
public_key, public_key_length);
|
||||||
|
if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
|
||||||
|
/* The key has been destroyed. */
|
||||||
|
status = PSA_SUCCESS;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
exit:
|
exit:
|
||||||
/*
|
/*
|
||||||
* Key attributes may have been returned by psa_get_key_attributes()
|
* Key attributes may have been returned by psa_get_key_attributes()
|
||||||
@@ -560,7 +682,8 @@ exit:
|
|||||||
* private key against its own public key. */
|
* private key against its own public key. */
|
||||||
psa_status_t mbedtls_test_psa_raw_key_agreement_with_self(
|
psa_status_t mbedtls_test_psa_raw_key_agreement_with_self(
|
||||||
psa_algorithm_t alg,
|
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 private_key_type;
|
||||||
psa_key_type_t public_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;
|
size_t public_key_length;
|
||||||
uint8_t output[1024];
|
uint8_t output[1024];
|
||||||
size_t output_length;
|
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_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);
|
private_key_type = psa_get_key_type(&attributes);
|
||||||
key_bits = psa_get_key_bits(&attributes);
|
key_bits = psa_get_key_bits(&attributes);
|
||||||
public_key_type = PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(private_key_type);
|
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);
|
public_key_length = PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(public_key_type, key_bits);
|
||||||
TEST_CALLOC(public_key, public_key_length);
|
TEST_CALLOC(public_key, public_key_length);
|
||||||
PSA_ASSERT(psa_export_public_key(key,
|
status = psa_export_public_key(key,
|
||||||
public_key, public_key_length,
|
public_key, public_key_length,
|
||||||
&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,
|
status = psa_raw_key_agreement(alg, key,
|
||||||
public_key, public_key_length,
|
public_key, public_key_length,
|
||||||
output, sizeof(output), &output_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) {
|
if (status == PSA_SUCCESS) {
|
||||||
TEST_ASSERT(output_length <=
|
TEST_ASSERT(output_length <=
|
||||||
PSA_RAW_KEY_AGREEMENT_OUTPUT_SIZE(private_key_type,
|
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,
|
static int exercise_raw_key_agreement_key(mbedtls_svc_key_id_t key,
|
||||||
psa_key_usage_t usage,
|
psa_key_usage_t usage,
|
||||||
psa_algorithm_t alg)
|
psa_algorithm_t alg,
|
||||||
|
int key_destroyable)
|
||||||
{
|
{
|
||||||
int ok = 0;
|
int ok = 0;
|
||||||
|
|
||||||
if (usage & PSA_KEY_USAGE_DERIVE) {
|
if (usage & PSA_KEY_USAGE_DERIVE) {
|
||||||
/* We need two keys to exercise key agreement. Exercise the
|
/* We need two keys to exercise key agreement. Exercise the
|
||||||
* private key against its own public key. */
|
* 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;
|
ok = 1;
|
||||||
|
|
||||||
@@ -626,7 +765,8 @@ exit:
|
|||||||
|
|
||||||
static int exercise_key_agreement_key(mbedtls_svc_key_id_t key,
|
static int exercise_key_agreement_key(mbedtls_svc_key_id_t key,
|
||||||
psa_key_usage_t usage,
|
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;
|
psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
|
||||||
unsigned char input[1] = { 0 };
|
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. */
|
hash length. Otherwise test should fail with INVALID_ARGUMENT. */
|
||||||
if (PSA_ALG_IS_HKDF_EXPAND(kdf_alg)) {
|
if (PSA_ALG_IS_HKDF_EXPAND(kdf_alg)) {
|
||||||
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
|
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);
|
size_t key_bits = psa_get_key_bits(&attributes);
|
||||||
psa_algorithm_t hash_alg = PSA_ALG_HKDF_GET_HASH(kdf_alg);
|
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);
|
expected_key_agreement_status);
|
||||||
|
|
||||||
if (expected_key_agreement_status != PSA_SUCCESS) {
|
if (expected_key_agreement_status != PSA_SUCCESS) {
|
||||||
@@ -857,7 +1003,8 @@ exit:
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int exercise_export_key(mbedtls_svc_key_id_t key,
|
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;
|
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
|
||||||
uint8_t *exported = NULL;
|
uint8_t *exported = NULL;
|
||||||
@@ -865,25 +1012,31 @@ static int exercise_export_key(mbedtls_svc_key_id_t key,
|
|||||||
size_t exported_length = 0;
|
size_t exported_length = 0;
|
||||||
int ok = 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(
|
exported_size = PSA_EXPORT_KEY_OUTPUT_SIZE(
|
||||||
psa_get_key_type(&attributes),
|
psa_get_key_type(&attributes),
|
||||||
psa_get_key_bits(&attributes));
|
psa_get_key_bits(&attributes));
|
||||||
TEST_CALLOC(exported, exported_size);
|
TEST_CALLOC(exported, exported_size);
|
||||||
|
|
||||||
if ((usage & PSA_KEY_USAGE_EXPORT) == 0 &&
|
status = psa_export_key(key, exported, exported_size, &exported_length);
|
||||||
!PSA_KEY_TYPE_IS_PUBLIC_KEY(psa_get_key_type(&attributes))) {
|
if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
|
||||||
TEST_EQUAL(psa_export_key(key, exported,
|
/* The key has been destroyed. */
|
||||||
exported_size, &exported_length),
|
ok = 1;
|
||||||
PSA_ERROR_NOT_PERMITTED);
|
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;
|
ok = 1;
|
||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
|
PSA_ASSERT(status);
|
||||||
PSA_ASSERT(psa_export_key(key,
|
|
||||||
exported, exported_size,
|
|
||||||
&exported_length));
|
|
||||||
ok = mbedtls_test_psa_exported_key_sanity_check(
|
ok = mbedtls_test_psa_exported_key_sanity_check(
|
||||||
psa_get_key_type(&attributes), psa_get_key_bits(&attributes),
|
psa_get_key_type(&attributes), psa_get_key_bits(&attributes),
|
||||||
exported, exported_length);
|
exported, exported_length);
|
||||||
@@ -899,7 +1052,8 @@ exit:
|
|||||||
return ok;
|
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_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
|
||||||
psa_key_type_t public_type;
|
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;
|
size_t exported_length = 0;
|
||||||
int ok = 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))) {
|
if (!PSA_KEY_TYPE_IS_ASYMMETRIC(psa_get_key_type(&attributes))) {
|
||||||
exported_size = PSA_EXPORT_KEY_OUTPUT_SIZE(
|
exported_size = PSA_EXPORT_KEY_OUTPUT_SIZE(
|
||||||
psa_get_key_type(&attributes),
|
psa_get_key_type(&attributes),
|
||||||
psa_get_key_bits(&attributes));
|
psa_get_key_bits(&attributes));
|
||||||
TEST_CALLOC(exported, exported_size);
|
TEST_CALLOC(exported, exported_size);
|
||||||
|
|
||||||
TEST_EQUAL(psa_export_public_key(key, exported,
|
status = psa_export_public_key(key, exported,
|
||||||
exported_size, &exported_length),
|
exported_size, &exported_length);
|
||||||
PSA_ERROR_INVALID_ARGUMENT);
|
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;
|
ok = 1;
|
||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
@@ -928,9 +1093,14 @@ static int exercise_export_public_key(mbedtls_svc_key_id_t key)
|
|||||||
psa_get_key_bits(&attributes));
|
psa_get_key_bits(&attributes));
|
||||||
TEST_CALLOC(exported, exported_size);
|
TEST_CALLOC(exported, exported_size);
|
||||||
|
|
||||||
PSA_ASSERT(psa_export_public_key(key,
|
status = psa_export_public_key(key, exported,
|
||||||
exported, exported_size,
|
exported_size, &exported_length);
|
||||||
&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(
|
ok = mbedtls_test_psa_exported_key_sanity_check(
|
||||||
public_type, psa_get_key_bits(&attributes),
|
public_type, psa_get_key_bits(&attributes),
|
||||||
exported, exported_length);
|
exported, exported_length);
|
||||||
@@ -948,38 +1118,43 @@ exit:
|
|||||||
|
|
||||||
int mbedtls_test_psa_exercise_key(mbedtls_svc_key_id_t key,
|
int mbedtls_test_psa_exercise_key(mbedtls_svc_key_id_t key,
|
||||||
psa_key_usage_t usage,
|
psa_key_usage_t usage,
|
||||||
psa_algorithm_t alg)
|
psa_algorithm_t alg,
|
||||||
|
int key_destroyable)
|
||||||
{
|
{
|
||||||
int ok = 0;
|
int ok = 0;
|
||||||
|
|
||||||
if (!check_key_attributes_sanity(key)) {
|
if (!check_key_attributes_sanity(key, key_destroyable)) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (alg == 0) {
|
if (alg == 0) {
|
||||||
ok = 1; /* If no algorithm, do nothing (used for raw data "keys"). */
|
ok = 1; /* If no algorithm, do nothing (used for raw data "keys"). */
|
||||||
} else if (PSA_ALG_IS_MAC(alg)) {
|
} 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)) {
|
} 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)) {
|
} 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)) {
|
} 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)) {
|
} 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)) {
|
} 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)) {
|
} 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)) {
|
} 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 {
|
} else {
|
||||||
TEST_FAIL("No code to exercise this category of algorithm");
|
TEST_FAIL("No code to exercise this category of algorithm");
|
||||||
}
|
}
|
||||||
|
|
||||||
ok = ok && exercise_export_key(key, usage);
|
ok = ok && exercise_export_key(key,
|
||||||
ok = ok && exercise_export_public_key(key);
|
usage,
|
||||||
|
key_destroyable);
|
||||||
|
ok = ok && exercise_export_public_key(key,
|
||||||
|
key_destroyable);
|
||||||
|
|
||||||
exit:
|
exit:
|
||||||
return ok;
|
return ok;
|
||||||
|
|||||||
Reference in New Issue
Block a user