Merge pull request #43 from Patater/update-2.16-dev
Update to a development version of Mbed TLS 2.16.0
diff --git a/README.md b/README.md
index 5b52153..785584a 100644
--- a/README.md
+++ b/README.md
@@ -24,10 +24,24 @@
## Documentation
-Since the Mbed Crypto library is a reference implementation of the PSA cryptography API, the library's API documentation is the PSA cryptography API specification. The PSA cryptography API specification consists of the following documents:
+The Mbed Crypto library is a reference implementation of the PSA cryptography API. Please refer to the PSA Cryptography API documents for an overview of the library's interfaces and a detailed description of the types, macros and functions that it provides.
-* The [PSA Cryptography API overview](docs/PSA_Crypto_API_Overview.pdf).
-* The [PSA Cryptography API detailed function reference](docs/PSA_Crypto_API_Reference.pdf), which you can also browse in [HTML format](docs/html/modules.html).
+There are currently a few deviations where the library does not yet implement the latest version of the specification. Please refer to the [compliance issues on Github](https://github.com/ARMmbed/mbed-crypto/labels/compliance) for an up-to-date list.
+
+### PSA Cryptography API
+
+The PSA cryptography API specification consists of the following documents:
+
+* The [PSA Cryptography API overview](https://github.com/ARMmbed/mbed-crypto/blob/psa-crypto-api/docs/PSA_Cryptography_API_Specification.pdf).
+* The [PSA Cryptography API detailed function reference](https://github.com/ARMmbed/mbed-crypto/blob/psa-crypto-api/docs/PSA_Cryptography_API_Reference.pdf), which you can also browse in [HTML format](https://htmlpreview.github.io/?https://github.com/ARMmbed/mbed-crypto/blob/psa-crypto-api/docs/html/modules.html).
+
+### Browsable library documentation
+
+To generate a local copy of the library documentation in HTML format:
+
+1. Make sure that [Doxygen](http://www.doxygen.nl/) is installed. We use version 1.8.11 but slightly older or more recent versions should work.
+1. Run `make apidoc`.
+1. Browse `apidoc/index.html` or `apidoc/modules.html`.
## Compiling
diff --git a/docs/PSA_Crypto_API_Overview.pdf b/docs/PSA_Crypto_API_Overview.pdf
deleted file mode 100644
index ecaf399..0000000
--- a/docs/PSA_Crypto_API_Overview.pdf
+++ /dev/null
Binary files differ
diff --git a/docs/PSA_Crypto_API_Reference.pdf b/docs/PSA_Crypto_API_Reference.pdf
deleted file mode 100644
index 2315471..0000000
--- a/docs/PSA_Crypto_API_Reference.pdf
+++ /dev/null
Binary files differ
diff --git a/include/psa/crypto.h b/include/psa/crypto.h
index 06f9eb8..93f8968 100644
--- a/include/psa/crypto.h
+++ b/include/psa/crypto.h
@@ -93,6 +93,140 @@
/**@}*/
+/** \defgroup policy Key policies
+ * @{
+ */
+
+/** The type of the key policy data structure.
+ *
+ * Before calling any function on a key policy, the application must initialize
+ * it by any of the following means:
+ * - Set the structure to all-bits-zero, for example:
+ * \code
+ * psa_key_policy_t policy;
+ * memset(&policy, 0, sizeof(policy));
+ * \endcode
+ * - Initialize the structure to logical zero values, for example:
+ * \code
+ * psa_key_policy_t policy = {0};
+ * \endcode
+ * - Initialize the structure to the initializer #PSA_KEY_POLICY_INIT,
+ * for example:
+ * \code
+ * psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
+ * \endcode
+ * - Assign the result of the function psa_key_policy_init()
+ * to the structure, for example:
+ * \code
+ * psa_key_policy_t policy;
+ * policy = psa_key_policy_init();
+ * \endcode
+ *
+ * This is an implementation-defined \c struct. Applications should not
+ * make any assumptions about the content of this structure except
+ * as directed by the documentation of a specific implementation. */
+typedef struct psa_key_policy_s psa_key_policy_t;
+
+/** \def PSA_KEY_POLICY_INIT
+ *
+ * This macro returns a suitable initializer for a key policy object of type
+ * #psa_key_policy_t.
+ */
+#ifdef __DOXYGEN_ONLY__
+/* This is an example definition for documentation purposes.
+ * Implementations should define a suitable value in `crypto_struct.h`.
+ */
+#define PSA_KEY_POLICY_INIT {0}
+#endif
+
+/** Return an initial value for a key policy that forbids all usage of the key.
+ */
+static psa_key_policy_t psa_key_policy_init(void);
+
+/** \brief Set the standard fields of a policy structure.
+ *
+ * Note that this function does not make any consistency check of the
+ * parameters. The values are only checked when applying the policy to
+ * a key slot with psa_set_key_policy().
+ *
+ * \param[in,out] policy The key policy to modify. It must have been
+ * initialized as per the documentation for
+ * #psa_key_policy_t.
+ * \param usage The permitted uses for the key.
+ * \param alg The algorithm that the key may be used for.
+ */
+void psa_key_policy_set_usage(psa_key_policy_t *policy,
+ psa_key_usage_t usage,
+ psa_algorithm_t alg);
+
+/** \brief Retrieve the usage field of a policy structure.
+ *
+ * \param[in] policy The policy object to query.
+ *
+ * \return The permitted uses for a key with this policy.
+ */
+psa_key_usage_t psa_key_policy_get_usage(const psa_key_policy_t *policy);
+
+/** \brief Retrieve the algorithm field of a policy structure.
+ *
+ * \param[in] policy The policy object to query.
+ *
+ * \return The permitted algorithm for a key with this policy.
+ */
+psa_algorithm_t psa_key_policy_get_algorithm(const psa_key_policy_t *policy);
+
+/** \brief Set the usage policy on a key slot.
+ *
+ * This function must be called on an empty key slot, before importing,
+ * generating or creating a key in the slot. Changing the policy of an
+ * existing key is not permitted.
+ *
+ * Implementations may set restrictions on supported key policies
+ * depending on the key type and the key slot.
+ *
+ * \param handle Handle to the key whose policy is to be changed.
+ * \param[in] policy The policy object to query.
+ *
+ * \retval #PSA_SUCCESS
+ * Success.
+ * If the key is persistent, it is implementation-defined whether
+ * the policy has been saved to persistent storage. Implementations
+ * may defer saving the policy until the key material is created.
+ * \retval #PSA_ERROR_INVALID_HANDLE
+ * \retval #PSA_ERROR_OCCUPIED_SLOT
+ * \retval #PSA_ERROR_NOT_SUPPORTED
+ * \retval #PSA_ERROR_INVALID_ARGUMENT
+ * \retval #PSA_ERROR_COMMUNICATION_FAILURE
+ * \retval #PSA_ERROR_HARDWARE_FAILURE
+ * \retval #PSA_ERROR_TAMPERING_DETECTED
+ * \retval #PSA_ERROR_BAD_STATE
+ * The library has not been previously initialized by psa_crypto_init().
+ * It is implementation-dependent whether a failure to initialize
+ * results in this error code.
+ */
+psa_status_t psa_set_key_policy(psa_key_handle_t handle,
+ const psa_key_policy_t *policy);
+
+/** \brief Get the usage policy for a key slot.
+ *
+ * \param handle Handle to the key slot whose policy is being queried.
+ * \param[out] policy On success, the key's policy.
+ *
+ * \retval #PSA_SUCCESS
+ * \retval #PSA_ERROR_INVALID_HANDLE
+ * \retval #PSA_ERROR_COMMUNICATION_FAILURE
+ * \retval #PSA_ERROR_HARDWARE_FAILURE
+ * \retval #PSA_ERROR_TAMPERING_DETECTED
+ * \retval #PSA_ERROR_BAD_STATE
+ * The library has not been previously initialized by psa_crypto_init().
+ * It is implementation-dependent whether a failure to initialize
+ * results in this error code.
+ */
+psa_status_t psa_get_key_policy(psa_key_handle_t handle,
+ psa_key_policy_t *policy);
+
+/**@}*/
+
/** \defgroup key_management Key management
* @{
*/
@@ -530,139 +664,71 @@
size_t data_size,
size_t *data_length);
-/**@}*/
-
-/** \defgroup policy Key policies
- * @{
- */
-
-/** The type of the key policy data structure.
+/** Make a copy of a key.
*
- * Before calling any function on a key policy, the application must initialize
- * it by any of the following means:
- * - Set the structure to all-bits-zero, for example:
- * \code
- * psa_key_policy_t policy;
- * memset(&policy, 0, sizeof(policy));
- * \endcode
- * - Initialize the structure to logical zero values, for example:
- * \code
- * psa_key_policy_t policy = {0};
- * \endcode
- * - Initialize the structure to the initializer #PSA_KEY_POLICY_INIT,
- * for example:
- * \code
- * psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
- * \endcode
- * - Assign the result of the function psa_key_policy_init()
- * to the structure, for example:
- * \code
- * psa_key_policy_t policy;
- * policy = psa_key_policy_init();
- * \endcode
+ * Copy key material from one location to another.
*
- * This is an implementation-defined \c struct. Applications should not
- * make any assumptions about the content of this structure except
- * as directed by the documentation of a specific implementation. */
-typedef struct psa_key_policy_s psa_key_policy_t;
-
-/** \def PSA_KEY_POLICY_INIT
+ * This function is primarily useful to copy a key from one location
+ * to another, since it populates a key using the material from
+ * another key which may have a different lifetime.
*
- * This macro returns a suitable initializer for a key policy object of type
- * #psa_key_policy_t.
- */
-#ifdef __DOXYGEN_ONLY__
-/* This is an example definition for documentation purposes.
- * Implementations should define a suitable value in `crypto_struct.h`.
- */
-#define PSA_KEY_POLICY_INIT {0}
-#endif
-
-/** Return an initial value for a key policy that forbids all usage of the key.
- */
-static psa_key_policy_t psa_key_policy_init(void);
-
-/** \brief Set the standard fields of a policy structure.
+ * In an implementation where slots have different ownerships,
+ * this function may be used to share a key with a different party,
+ * subject to implementation-defined restrictions on key sharing.
+ * In this case \p constraint would typically prevent the recipient
+ * from exporting the key.
*
- * Note that this function does not make any consistency check of the
- * parameters. The values are only checked when applying the policy to
- * a key slot with psa_set_key_policy().
+ * The resulting key may only be used in a way that conforms to all
+ * three of: the policy of the source key, the policy previously set
+ * on the target, and the \p constraint parameter passed when calling
+ * this function.
+ * - The usage flags on the resulting key are the bitwise-and of the
+ * usage flags on the source policy, the previously-set target policy
+ * and the policy constraint.
+ * - If all three policies allow the same algorithm or wildcard-based
+ * algorithm policy, the resulting key has the same algorithm policy.
+ * - If one of the policies allows an algorithm and all the other policies
+ * either allow the same algorithm or a wildcard-based algorithm policy
+ * that includes this algorithm, the resulting key allows the same
+ * algorithm.
*
- * \param[in,out] policy The key policy to modify. It must have been
- * initialized as per the documentation for
- * #psa_key_policy_t.
- * \param usage The permitted uses for the key.
- * \param alg The algorithm that the key may be used for.
- */
-void psa_key_policy_set_usage(psa_key_policy_t *policy,
- psa_key_usage_t usage,
- psa_algorithm_t alg);
-
-/** \brief Retrieve the usage field of a policy structure.
+ * The effect of this function on implementation-defined metadata is
+ * implementation-defined.
*
- * \param[in] policy The policy object to query.
- *
- * \return The permitted uses for a key with this policy.
- */
-psa_key_usage_t psa_key_policy_get_usage(const psa_key_policy_t *policy);
-
-/** \brief Retrieve the algorithm field of a policy structure.
- *
- * \param[in] policy The policy object to query.
- *
- * \return The permitted algorithm for a key with this policy.
- */
-psa_algorithm_t psa_key_policy_get_algorithm(const psa_key_policy_t *policy);
-
-/** \brief Set the usage policy on a key slot.
- *
- * This function must be called on an empty key slot, before importing,
- * generating or creating a key in the slot. Changing the policy of an
- * existing key is not permitted.
- *
- * Implementations may set restrictions on supported key policies
- * depending on the key type and the key slot.
- *
- * \param handle Handle to the key whose policy is to be changed.
- * \param[in] policy The policy object to query.
+ * \param source_handle The key to copy. It must be a handle to an
+ * occupied slot.
+ * \param target_handle A handle to the target slot. It must not contain
+ * key material yet.
+ * \param[in] constraint An optional policy constraint. If this parameter
+ * is non-null then the resulting key will conform
+ * to this policy in addition to the source policy
+ * and the policy already present on the target
+ * slot. If this parameter is null then the
+ * function behaves in the same way as if it was
+ * the target policy, i.e. only the source and
+ * target policies apply.
*
* \retval #PSA_SUCCESS
- * Success.
- * If the key is persistent, it is implementation-defined whether
- * the policy has been saved to persistent storage. Implementations
- * may defer saving the policy until the key material is created.
* \retval #PSA_ERROR_INVALID_HANDLE
* \retval #PSA_ERROR_OCCUPIED_SLOT
- * \retval #PSA_ERROR_NOT_SUPPORTED
+ * \p target already contains key material.
+ * \retval #PSA_ERROR_EMPTY_SLOT
+ * \p source does not contain key material.
* \retval #PSA_ERROR_INVALID_ARGUMENT
+ * The policy constraints on the source, on the target and
+ * \p constraints are incompatible.
+ * \retval #PSA_ERROR_NOT_PERMITTED
+ * The source key is not exportable and its lifetime does not
+ * allow copying it to the target's lifetime.
+ * \retval #PSA_ERROR_INSUFFICIENT_MEMORY
+ * \retval #PSA_ERROR_INSUFFICIENT_STORAGE
* \retval #PSA_ERROR_COMMUNICATION_FAILURE
* \retval #PSA_ERROR_HARDWARE_FAILURE
* \retval #PSA_ERROR_TAMPERING_DETECTED
- * \retval #PSA_ERROR_BAD_STATE
- * The library has not been previously initialized by psa_crypto_init().
- * It is implementation-dependent whether a failure to initialize
- * results in this error code.
*/
-psa_status_t psa_set_key_policy(psa_key_handle_t handle,
- const psa_key_policy_t *policy);
-
-/** \brief Get the usage policy for a key slot.
- *
- * \param handle Handle to the key slot whose policy is being queried.
- * \param[out] policy On success, the key's policy.
- *
- * \retval #PSA_SUCCESS
- * \retval #PSA_ERROR_INVALID_HANDLE
- * \retval #PSA_ERROR_COMMUNICATION_FAILURE
- * \retval #PSA_ERROR_HARDWARE_FAILURE
- * \retval #PSA_ERROR_TAMPERING_DETECTED
- * \retval #PSA_ERROR_BAD_STATE
- * The library has not been previously initialized by psa_crypto_init().
- * It is implementation-dependent whether a failure to initialize
- * results in this error code.
- */
-psa_status_t psa_get_key_policy(psa_key_handle_t handle,
- psa_key_policy_t *policy);
+psa_status_t psa_copy_key(psa_key_handle_t source_handle,
+ psa_key_handle_t target_handle,
+ const psa_key_policy_t *constraint);
/**@}*/
diff --git a/library/cipher.c b/library/cipher.c
index 16037fb..5d7e53f 100644
--- a/library/cipher.c
+++ b/library/cipher.c
@@ -1100,8 +1100,6 @@
* operations, we currently don't make it
* accessible through the cipher layer. */
return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
-
- return( 0 );
}
#endif /* MBEDTLS_USE_PSA_CRYPTO */
diff --git a/library/psa_crypto.c b/library/psa_crypto.c
index 7fb1adb..d9d4870 100644
--- a/library/psa_crypto.c
+++ b/library/psa_crypto.c
@@ -748,6 +748,32 @@
return( status );
}
+/** Calculate the intersection of two algorithm usage policies.
+ *
+ * Return 0 (which allows no operation) on incompatibility.
+ */
+static psa_algorithm_t psa_key_policy_algorithm_intersection(
+ psa_algorithm_t alg1,
+ psa_algorithm_t alg2 )
+{
+ /* Common case: the policy only allows alg. */
+ if( alg1 == alg2 )
+ return( alg1 );
+ /* If the policies are from the same hash-and-sign family, check
+ * if one is a wildcard. If so the other has the specific algorithm. */
+ if( PSA_ALG_IS_HASH_AND_SIGN( alg1 ) &&
+ PSA_ALG_IS_HASH_AND_SIGN( alg2 ) &&
+ ( alg1 & ~PSA_ALG_HASH_MASK ) == ( alg2 & ~PSA_ALG_HASH_MASK ) )
+ {
+ if( PSA_ALG_SIGN_GET_HASH( alg1 ) == PSA_ALG_ANY_HASH )
+ return( alg2 );
+ if( PSA_ALG_SIGN_GET_HASH( alg2 ) == PSA_ALG_ANY_HASH )
+ return( alg1 );
+ }
+ /* If the policies are incompatible, allow nothing. */
+ return( 0 );
+}
+
/** Test whether a policy permits an algorithm.
*
* The caller must test usage flags separately.
@@ -771,6 +797,31 @@
return( 0 );
}
+/** Restrict a key policy based on a constraint.
+ *
+ * \param[in,out] policy The policy to restrict.
+ * \param[in] constraint The policy constraint to apply.
+ *
+ * \retval #PSA_SUCCESS
+ * \c *policy contains the intersection of the original value of
+ * \c *policy and \c *constraint.
+ * \retval #PSA_ERROR_INVALID_ARGUMENT
+ * \c *policy and \c *constraint are incompatible.
+ * \c *policy is unchanged.
+ */
+static psa_status_t psa_restrict_key_policy(
+ psa_key_policy_t *policy,
+ const psa_key_policy_t *constraint )
+{
+ psa_algorithm_t intersection_alg =
+ psa_key_policy_algorithm_intersection( policy->alg, constraint->alg );
+ if( intersection_alg == 0 && policy->alg != 0 && constraint->alg != 0 )
+ return( PSA_ERROR_INVALID_ARGUMENT );
+ policy->usage &= constraint->usage;
+ policy->alg = intersection_alg;
+ return( PSA_SUCCESS );
+}
+
/** Retrieve a slot which must contain a key. The key must have allow all the
* usage flags set in \p usage. If \p alg is nonzero, the key must allow
* operations with this algorithm. */
@@ -974,11 +1025,11 @@
}
#endif /* defined(MBEDTLS_RSA_C) || defined(MBEDTLS_ECP_C) */
-static psa_status_t psa_internal_export_key( psa_key_slot_t *slot,
- uint8_t *data,
- size_t data_size,
- size_t *data_length,
- int export_public_key )
+static psa_status_t psa_internal_export_key( const psa_key_slot_t *slot,
+ uint8_t *data,
+ size_t data_size,
+ size_t *data_length,
+ int export_public_key )
{
*data_length = 0;
@@ -1165,6 +1216,64 @@
}
#endif /* defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) */
+static psa_status_t psa_copy_key_material( const psa_key_slot_t *source,
+ psa_key_handle_t target )
+{
+ psa_status_t status;
+ uint8_t *buffer = NULL;
+ size_t buffer_size = 0;
+ size_t length;
+
+ buffer_size = PSA_KEY_EXPORT_MAX_SIZE( source->type,
+ psa_get_key_bits( source ) );
+ buffer = mbedtls_calloc( 1, buffer_size );
+ if( buffer == NULL )
+ return( PSA_ERROR_INSUFFICIENT_MEMORY );
+ status = psa_internal_export_key( source, buffer, buffer_size, &length, 0 );
+ if( status != PSA_SUCCESS )
+ goto exit;
+ status = psa_import_key( target, source->type, buffer, length );
+
+exit:
+ mbedtls_platform_zeroize( buffer, buffer_size );
+ mbedtls_free( buffer );
+ return( status );
+}
+
+psa_status_t psa_copy_key(psa_key_handle_t source_handle,
+ psa_key_handle_t target_handle,
+ const psa_key_policy_t *constraint)
+{
+ psa_key_slot_t *source_slot = NULL;
+ psa_key_slot_t *target_slot = NULL;
+ psa_key_policy_t new_policy;
+ psa_status_t status;
+ status = psa_get_key_from_slot( source_handle, &source_slot, 0, 0 );
+ if( status != PSA_SUCCESS )
+ return( status );
+ status = psa_get_empty_key_slot( target_handle, &target_slot );
+ if( status != PSA_SUCCESS )
+ return( status );
+
+ new_policy = target_slot->policy;
+ status = psa_restrict_key_policy( &new_policy, &source_slot->policy );
+ if( status != PSA_SUCCESS )
+ return( status );
+ if( constraint != NULL )
+ {
+ status = psa_restrict_key_policy( &new_policy, constraint );
+ if( status != PSA_SUCCESS )
+ return( status );
+ }
+
+ status = psa_copy_key_material( source_slot, target_handle );
+ if( status != PSA_SUCCESS )
+ return( status );
+
+ target_slot->policy = new_policy;
+ return( PSA_SUCCESS );
+}
+
/****************************************************************/
diff --git a/tests/suites/test_suite_psa_crypto.data b/tests/suites/test_suite_psa_crypto.data
index 923aa0c..d9dd9ef 100644
--- a/tests/suites/test_suite_psa_crypto.data
+++ b/tests/suites/test_suite_psa_crypto.data
@@ -492,6 +492,117 @@
depends_on:MBEDTLS_PK_PARSE_C:MBEDTLS_ECP_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_ECDH_C
agreement_key_policy:PSA_KEY_USAGE_DERIVE:PSA_ALG_ECDH(PSA_ALG_SELECT_RAW):PSA_KEY_TYPE_ECC_KEYPAIR(PSA_ECC_CURVE_SECP256R1):"49c9a8c18c4b885638c431cf1df1c994131609b580d4fd43a0cab17db2f13eee":PSA_ALG_FFDH(PSA_ALG_SELECT_RAW)
+Copy key: raw, 0 bytes
+copy_key_policy:0:0:PSA_KEY_TYPE_RAW_DATA:"":0:0:-1:-1:0:0
+
+Copy key: AES, same usage flags
+depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CTR
+copy_key_policy:PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_EXPORT:PSA_ALG_CTR:PSA_KEY_TYPE_AES:"404142434445464748494a4b4c4d4e4f":PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_EXPORT:PSA_ALG_CTR:-1:-1:PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_EXPORT:PSA_ALG_CTR
+
+Copy key: AES, fewer usage flags
+depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CTR
+copy_key_policy:PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_EXPORT:PSA_ALG_CTR:PSA_KEY_TYPE_AES:"404142434445464748494a4b4c4d4e4f":PSA_KEY_USAGE_ENCRYPT:PSA_ALG_CTR:-1:-1:PSA_KEY_USAGE_ENCRYPT:PSA_ALG_CTR
+
+Copy key: AES, 1 more usage flag
+depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CTR
+copy_key_policy:PSA_KEY_USAGE_ENCRYPT:PSA_ALG_CTR:PSA_KEY_TYPE_AES:"404142434445464748494a4b4c4d4e4f":PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT:PSA_ALG_CTR:-1:-1:PSA_KEY_USAGE_ENCRYPT:PSA_ALG_CTR
+
+Copy key: AES, 2 more usage flags
+depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CTR
+copy_key_policy:PSA_KEY_USAGE_ENCRYPT:PSA_ALG_CTR:PSA_KEY_TYPE_AES:"404142434445464748494a4b4c4d4e4f":PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT | PSA_KEY_USAGE_EXPORT:PSA_ALG_CTR:-1:-1:PSA_KEY_USAGE_ENCRYPT:PSA_ALG_CTR
+
+Copy key: AES, intersect usage flags
+depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CTR
+copy_key_policy:PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_EXPORT:PSA_ALG_CTR:PSA_KEY_TYPE_AES:"404142434445464748494a4b4c4d4e4f":PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT:PSA_ALG_CTR:-1:-1:PSA_KEY_USAGE_ENCRYPT:PSA_ALG_CTR
+
+Copy key: AES, source=target, constraint with same usage flags
+depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CTR
+copy_key_policy:PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_EXPORT:PSA_ALG_CTR:PSA_KEY_TYPE_AES:"404142434445464748494a4b4c4d4e4f":PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_EXPORT:PSA_ALG_CTR:PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_EXPORT:PSA_ALG_CTR:PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_EXPORT:PSA_ALG_CTR
+
+Copy key: AES, source=target, constraint with fewer usage flags
+depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CTR
+copy_key_policy:PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_EXPORT:PSA_ALG_CTR:PSA_KEY_TYPE_AES:"404142434445464748494a4b4c4d4e4f":PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_EXPORT:PSA_ALG_CTR:PSA_KEY_USAGE_ENCRYPT:PSA_ALG_CTR:PSA_KEY_USAGE_ENCRYPT:PSA_ALG_CTR
+
+Copy key: AES, source=target, constraint with 1 more usage flag
+depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CTR
+copy_key_policy:PSA_KEY_USAGE_ENCRYPT:PSA_ALG_CTR:PSA_KEY_TYPE_AES:"404142434445464748494a4b4c4d4e4f":PSA_KEY_USAGE_ENCRYPT:PSA_ALG_CTR:PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT:PSA_ALG_CTR:PSA_KEY_USAGE_ENCRYPT:PSA_ALG_CTR
+
+Copy key: AES, source=target, constraint with 2 more usage flags
+depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CTR
+copy_key_policy:PSA_KEY_USAGE_ENCRYPT:PSA_ALG_CTR:PSA_KEY_TYPE_AES:"404142434445464748494a4b4c4d4e4f":PSA_KEY_USAGE_ENCRYPT:PSA_ALG_CTR:PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT | PSA_KEY_USAGE_EXPORT:PSA_ALG_CTR:PSA_KEY_USAGE_ENCRYPT:PSA_ALG_CTR
+
+Copy key: AES, source=target, constraint with different usage flags
+depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CTR
+copy_key_policy:PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_EXPORT:PSA_ALG_CTR:PSA_KEY_TYPE_AES:"404142434445464748494a4b4c4d4e4f":PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_EXPORT:PSA_ALG_CTR:PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT:PSA_ALG_CTR:PSA_KEY_USAGE_ENCRYPT:PSA_ALG_CTR
+
+Copy key: AES, permissive target, restrictive constraint
+depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CTR
+copy_key_policy:PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_EXPORT:PSA_ALG_CTR:PSA_KEY_TYPE_AES:"404142434445464748494a4b4c4d4e4f":PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT | PSA_KEY_USAGE_EXPORT:PSA_ALG_CTR:PSA_KEY_USAGE_ENCRYPT:PSA_ALG_CTR:PSA_KEY_USAGE_ENCRYPT:PSA_ALG_CTR
+
+Copy key: RSA key pair, same usage flags
+depends_on:MBEDTLS_PK_PARSE_C:MBEDTLS_PK_WRITE_C:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V15:MBEDTLS_SHA256_C
+copy_key_policy:PSA_KEY_USAGE_SIGN | PSA_KEY_USAGE_EXPORT:PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_SHA_256):PSA_KEY_TYPE_RSA_KEYPAIR:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":PSA_KEY_USAGE_SIGN | PSA_KEY_USAGE_EXPORT:PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_SHA_256):-1:-1:PSA_KEY_USAGE_SIGN | PSA_KEY_USAGE_EXPORT:PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_SHA_256)
+
+Copy key: RSA key pair, fewer usage flags
+depends_on:MBEDTLS_PK_PARSE_C:MBEDTLS_PK_WRITE_C:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V15:MBEDTLS_SHA256_C
+copy_key_policy:PSA_KEY_USAGE_SIGN | PSA_KEY_USAGE_EXPORT:PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_SHA_256):PSA_KEY_TYPE_RSA_KEYPAIR:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":PSA_KEY_USAGE_SIGN:PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_SHA_256):-1:-1:PSA_KEY_USAGE_SIGN:PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_SHA_256)
+
+Copy key: RSA key pair, more usage flags
+depends_on:MBEDTLS_PK_PARSE_C:MBEDTLS_PK_WRITE_C:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V15:MBEDTLS_SHA256_C
+copy_key_policy:PSA_KEY_USAGE_SIGN:PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_SHA_256):PSA_KEY_TYPE_RSA_KEYPAIR:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":PSA_KEY_USAGE_SIGN | PSA_KEY_USAGE_VERIFY:PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_SHA_256):-1:-1:PSA_KEY_USAGE_SIGN:PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_SHA_256)
+
+Copy key: RSA key pair, intersect usage flags
+depends_on:MBEDTLS_PK_PARSE_C:MBEDTLS_PK_WRITE_C:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V15:MBEDTLS_SHA256_C
+copy_key_policy:PSA_KEY_USAGE_SIGN | PSA_KEY_USAGE_EXPORT:PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_SHA_256):PSA_KEY_TYPE_RSA_KEYPAIR:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":PSA_KEY_USAGE_SIGN | PSA_KEY_USAGE_VERIFY:PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_SHA_256):-1:-1:PSA_KEY_USAGE_SIGN:PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_SHA_256)
+
+Copy key: RSA key pair, wildcard algorithm in source
+depends_on:MBEDTLS_PK_PARSE_C:MBEDTLS_PK_WRITE_C:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V15:MBEDTLS_SHA256_C
+copy_key_policy:PSA_KEY_USAGE_SIGN | PSA_KEY_USAGE_EXPORT:PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_ANY_HASH):PSA_KEY_TYPE_RSA_KEYPAIR:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":PSA_KEY_USAGE_SIGN | PSA_KEY_USAGE_EXPORT:PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_SHA_256):-1:-1:PSA_KEY_USAGE_SIGN | PSA_KEY_USAGE_EXPORT:PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_SHA_256)
+
+Copy key: RSA key pair, wildcard algorithm in target
+depends_on:MBEDTLS_PK_PARSE_C:MBEDTLS_PK_WRITE_C:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V15:MBEDTLS_SHA256_C
+copy_key_policy:PSA_KEY_USAGE_SIGN | PSA_KEY_USAGE_EXPORT:PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_SHA_256):PSA_KEY_TYPE_RSA_KEYPAIR:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":PSA_KEY_USAGE_SIGN | PSA_KEY_USAGE_EXPORT:PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_ANY_HASH):-1:-1:PSA_KEY_USAGE_SIGN | PSA_KEY_USAGE_EXPORT:PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_SHA_256)
+
+Copy key: RSA key pair, wildcard algorithm in source and target
+depends_on:MBEDTLS_PK_PARSE_C:MBEDTLS_PK_WRITE_C:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V15:MBEDTLS_SHA256_C
+copy_key_policy:PSA_KEY_USAGE_SIGN | PSA_KEY_USAGE_EXPORT:PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_ANY_HASH):PSA_KEY_TYPE_RSA_KEYPAIR:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":PSA_KEY_USAGE_SIGN | PSA_KEY_USAGE_EXPORT:PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_ANY_HASH):-1:-1:PSA_KEY_USAGE_SIGN | PSA_KEY_USAGE_EXPORT:PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_ANY_HASH)
+
+Copy key: RSA key pair, wildcard in constraint
+depends_on:MBEDTLS_PK_PARSE_C:MBEDTLS_PK_WRITE_C:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V15:MBEDTLS_SHA256_C
+copy_key_policy:PSA_KEY_USAGE_SIGN | PSA_KEY_USAGE_EXPORT:PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_ANY_HASH):PSA_KEY_TYPE_RSA_KEYPAIR:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":PSA_KEY_USAGE_SIGN | PSA_KEY_USAGE_VERIFY | PSA_KEY_USAGE_EXPORT:PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_ANY_HASH):PSA_KEY_USAGE_SIGN:PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_ANY_HASH):PSA_KEY_USAGE_SIGN:PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_ANY_HASH)
+
+Copy key: RSA key pair, wildcard, restrictive constraint
+depends_on:MBEDTLS_PK_PARSE_C:MBEDTLS_PK_WRITE_C:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V15:MBEDTLS_SHA256_C
+copy_key_policy:PSA_KEY_USAGE_SIGN | PSA_KEY_USAGE_EXPORT:PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_ANY_HASH):PSA_KEY_TYPE_RSA_KEYPAIR:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":PSA_KEY_USAGE_SIGN | PSA_KEY_USAGE_VERIFY | PSA_KEY_USAGE_EXPORT:PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_ANY_HASH):PSA_KEY_USAGE_SIGN:PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_SHA_256):PSA_KEY_USAGE_SIGN:PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_SHA_256)
+
+Copy fail: AES, incompatible target policy
+depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CTR:MBEDTLS_CIPHER_MODE_CBC
+copy_fail:PSA_KEY_USAGE_EXPORT:PSA_ALG_CTR:PSA_KEY_TYPE_AES:"404142434445464748494a4b4c4d4e4f":PSA_KEY_USAGE_EXPORT:PSA_ALG_CBC_NO_PADDING:-1:-1:PSA_ERROR_INVALID_ARGUMENT
+
+Copy fail: RSA, incompatible target policy (source wildcard)
+depends_on:MBEDTLS_PK_PARSE_C:MBEDTLS_PK_WRITE_C:MBEDTLS_RSA_C:MBEDTLS_SHA256_C
+copy_fail:PSA_KEY_USAGE_EXPORT:PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_ANY_HASH):PSA_KEY_TYPE_RSA_KEYPAIR:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":PSA_KEY_USAGE_EXPORT:PSA_ALG_RSA_PSS(PSA_ALG_SHA_256):-1:-1:PSA_ERROR_INVALID_ARGUMENT
+
+Copy fail: RSA, incompatible target policy (target wildcard)
+depends_on:MBEDTLS_PK_PARSE_C:MBEDTLS_PK_WRITE_C:MBEDTLS_RSA_C:MBEDTLS_SHA256_C
+copy_fail:PSA_KEY_USAGE_EXPORT:PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_SHA_256):PSA_KEY_TYPE_RSA_KEYPAIR:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":PSA_KEY_USAGE_EXPORT:PSA_ALG_RSA_PSS(PSA_ALG_ANY_HASH):-1:-1:PSA_ERROR_INVALID_ARGUMENT
+
+Copy fail: RSA, incompatible target policy (source and target wildcard)
+depends_on:MBEDTLS_PK_PARSE_C:MBEDTLS_PK_WRITE_C:MBEDTLS_RSA_C:MBEDTLS_SHA256_C
+copy_fail:PSA_KEY_USAGE_EXPORT:PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_ANY_HASH):PSA_KEY_TYPE_RSA_KEYPAIR:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":PSA_KEY_USAGE_EXPORT:PSA_ALG_RSA_PSS(PSA_ALG_ANY_HASH):-1:-1:PSA_ERROR_INVALID_ARGUMENT
+
+Copy fail: RSA, incompatible constraint (wildcard on different base)
+depends_on:MBEDTLS_PK_PARSE_C:MBEDTLS_PK_WRITE_C:MBEDTLS_RSA_C:MBEDTLS_SHA256_C
+copy_fail:PSA_KEY_USAGE_EXPORT:PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_SHA_256):PSA_KEY_TYPE_RSA_KEYPAIR:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":PSA_KEY_USAGE_EXPORT:PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_SHA_256):PSA_KEY_USAGE_EXPORT:PSA_ALG_RSA_PSS(PSA_ALG_ANY_HASH):PSA_ERROR_INVALID_ARGUMENT
+
+Copy fail: RSA, incompatible constraint
+depends_on:MBEDTLS_PK_PARSE_C:MBEDTLS_PK_WRITE_C:MBEDTLS_RSA_C:MBEDTLS_SHA256_C
+copy_fail:PSA_KEY_USAGE_EXPORT:PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_ANY_HASH):PSA_KEY_TYPE_RSA_KEYPAIR:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":PSA_KEY_USAGE_EXPORT:PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_ANY_HASH):PSA_KEY_USAGE_EXPORT:PSA_ALG_RSA_PSS(PSA_ALG_ANY_HASH):PSA_ERROR_INVALID_ARGUMENT
+
+Copy fail: RSA, ANY_HASH is not meaningful with OAEP
+depends_on:MBEDTLS_PK_PARSE_C:MBEDTLS_PK_WRITE_C:MBEDTLS_RSA_C:MBEDTLS_SHA256_C
+copy_fail:PSA_KEY_USAGE_EXPORT:PSA_ALG_RSA_OAEP(PSA_ALG_ANY_HASH):PSA_KEY_TYPE_RSA_KEYPAIR:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":PSA_KEY_USAGE_EXPORT:PSA_ALG_RSA_OAEP(PSA_ALG_SHA_256):-1:-1:PSA_ERROR_INVALID_ARGUMENT
+
Hash operation object initializers zero properly
hash_operation_init:
diff --git a/tests/suites/test_suite_psa_crypto.function b/tests/suites/test_suite_psa_crypto.function
index 2a49141..4a3044a 100644
--- a/tests/suites/test_suite_psa_crypto.function
+++ b/tests/suites/test_suite_psa_crypto.function
@@ -282,13 +282,38 @@
size_t payload_length = 16;
unsigned char signature[PSA_ASYMMETRIC_SIGNATURE_MAX_SIZE] = {0};
size_t signature_length = sizeof( signature );
+ psa_algorithm_t hash_alg = PSA_ALG_SIGN_GET_HASH( alg );
+
+ /* If the policy allows signing with any hash, just pick one. */
+ if( PSA_ALG_IS_HASH_AND_SIGN( alg ) && hash_alg == PSA_ALG_ANY_HASH )
+ {
+#if defined(MBEDTLS_MD2_C)
+ hash_alg = PSA_ALG_MD2;
+#elif defined(MBEDTLS_MD4_C)
+ hash_alg = PSA_ALG_MD4;
+#elif defined(MBEDTLS_MD5_C)
+ hash_alg = PSA_ALG_MD5;
+ /* MBEDTLS_RIPEMD160_C omitted because Mbed TLS doesn't
+ * support it in RSA PKCS#1v1.5 signatures. */
+#elif defined(MBEDTLS_SHA1_C)
+ hash_alg = PSA_ALG_SHA_1;
+#elif defined(MBEDTLS_SHA256_C)
+ hash_alg = PSA_ALG_SHA_256;
+#elif defined(MBEDTLS_SHA512_C)
+ hash_alg = PSA_ALG_SHA_384;
+#elif defined(MBEDTLS_SHA3_C)
+ hash_alg = PSA_ALG_SHA3_256;
+#else
+ test_fail( "No hash algorithm for hash-and-sign testing", __LINE__, __FILE__ );
+#endif
+ alg ^= PSA_ALG_ANY_HASH ^ hash_alg;
+ }
if( usage & PSA_KEY_USAGE_SIGN )
{
/* Some algorithms require the payload to have the size of
* the hash encoded in the algorithm. Use this input size
* even for algorithms that allow other input sizes. */
- psa_algorithm_t hash_alg = PSA_ALG_SIGN_GET_HASH( alg );
if( hash_alg != 0 )
payload_length = PSA_HASH_SIZE( hash_alg );
PSA_ASSERT( psa_asymmetric_sign( handle, alg,
@@ -746,6 +771,33 @@
return( ok );
}
+/** Do smoke tests on a key.
+ *
+ * Perform one of each operation indicated by \p alg (decrypt/encrypt,
+ * sign/verify, or derivation) that is permitted according to \p usage.
+ * \p usage and \p alg should correspond to the expected policy on the
+ * key.
+ *
+ * Export the key if permitted by \p usage, and check that the output
+ * looks sensible. If \p usage forbids export, check that
+ * \p psa_export_key correctly rejects the attempt. If the key is
+ * asymmetric, also check \p psa_export_public_key.
+ *
+ * If the key fails the tests, this function calls the test framework's
+ * `test_fail` function and returns false. Otherwise this function returns
+ * true. Therefore it should be used as follows:
+ * ```
+ * if( ! exercise_key( ... ) ) goto exit;
+ * ```
+ *
+ * \param handle 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.
+ *
+ * \retval 0 The key failed the smoke tests.
+ * \retval 1 The key passed the smoke tests.
+ */
static int exercise_key( psa_key_handle_t handle,
psa_key_usage_t usage,
psa_algorithm_t alg )
@@ -895,7 +947,8 @@
if( expected_import1_status == PSA_SUCCESS ||
expected_import2_status == PSA_SUCCESS )
{
- TEST_ASSERT( exercise_key( handle, usage, alg ) );
+ if( ! exercise_key( handle, usage, alg ) )
+ goto exit;
}
exit:
@@ -1742,6 +1795,159 @@
/* END_CASE */
/* BEGIN_CASE */
+void copy_key_policy( int source_usage_arg, int source_alg_arg,
+ int type_arg, data_t *material,
+ int target_usage_arg, int target_alg_arg,
+ int constraint_usage_arg, int constraint_alg_arg,
+ int expected_usage_arg, int expected_alg_arg )
+{
+ psa_key_usage_t source_usage = source_usage_arg;
+ psa_algorithm_t source_alg = source_alg_arg;
+ psa_key_handle_t source_handle = 0;
+ psa_key_policy_t source_policy = PSA_KEY_POLICY_INIT;
+ psa_key_type_t source_type = type_arg;
+ size_t source_bits;
+ psa_key_usage_t target_usage = target_usage_arg;
+ psa_algorithm_t target_alg = target_alg_arg;
+ psa_key_handle_t target_handle = 0;
+ psa_key_policy_t target_policy = PSA_KEY_POLICY_INIT;
+ psa_key_type_t target_type;
+ size_t target_bits;
+ psa_key_usage_t constraint_usage = constraint_usage_arg;
+ psa_algorithm_t constraint_alg = constraint_alg_arg;
+ psa_key_policy_t constraint = PSA_KEY_POLICY_INIT;
+ psa_key_policy_t *p_constraint = NULL;
+ psa_key_usage_t expected_usage = expected_usage_arg;
+ psa_algorithm_t expected_alg = expected_alg_arg;
+ uint8_t *export_buffer = NULL;
+
+ if( constraint_usage_arg != -1 )
+ {
+ p_constraint = &constraint;
+ psa_key_policy_set_usage( p_constraint,
+ constraint_usage, constraint_alg );
+ }
+
+ PSA_ASSERT( psa_crypto_init( ) );
+
+ /* Populate the source slot. */
+ PSA_ASSERT( psa_allocate_key( &source_handle ) );
+ psa_key_policy_set_usage( &source_policy, source_usage, source_alg );
+ PSA_ASSERT( psa_set_key_policy( source_handle, &source_policy ) );
+ PSA_ASSERT( psa_import_key( source_handle, source_type,
+ material->x, material->len ) );
+ PSA_ASSERT( psa_get_key_information( source_handle, NULL, &source_bits ) );
+
+ /* Prepare the target slot. */
+ PSA_ASSERT( psa_allocate_key( &target_handle ) );
+ psa_key_policy_set_usage( &target_policy, target_usage, target_alg );
+ PSA_ASSERT( psa_set_key_policy( target_handle, &target_policy ) );
+ target_policy = psa_key_policy_init();
+
+ /* Copy the key. */
+ PSA_ASSERT( psa_copy_key( source_handle, target_handle, p_constraint ) );
+
+ /* Destroy the source to ensure that this doesn't affect the target. */
+ PSA_ASSERT( psa_destroy_key( source_handle ) );
+
+ /* Test that the target slot has the expected content and policy. */
+ PSA_ASSERT( psa_get_key_information( target_handle,
+ &target_type, &target_bits ) );
+ TEST_EQUAL( source_type, target_type );
+ TEST_EQUAL( source_bits, target_bits );
+ PSA_ASSERT( psa_get_key_policy( target_handle, &target_policy ) );
+ TEST_EQUAL( expected_usage, psa_key_policy_get_usage( &target_policy ) );
+ TEST_EQUAL( expected_alg, psa_key_policy_get_algorithm( &target_policy ) );
+ if( expected_usage & PSA_KEY_USAGE_EXPORT )
+ {
+ size_t length;
+ ASSERT_ALLOC( export_buffer, material->len );
+ PSA_ASSERT( psa_export_key( target_handle, export_buffer,
+ material->len, &length ) );
+ ASSERT_COMPARE( material->x, material->len,
+ export_buffer, length );
+ }
+ if( ! exercise_key( target_handle, expected_usage, expected_alg ) )
+ goto exit;
+
+ PSA_ASSERT( psa_close_key( target_handle ) );
+
+exit:
+ mbedtls_psa_crypto_free( );
+ mbedtls_free( export_buffer );
+}
+/* END_CASE */
+
+/* BEGIN_CASE */
+void copy_fail( int source_usage_arg, int source_alg_arg,
+ int type_arg, data_t *material,
+ int target_usage_arg, int target_alg_arg,
+ int constraint_usage_arg, int constraint_alg_arg,
+ int expected_status_arg )
+{
+ /* Test copy failure into an empty slot. There is a test for copy failure
+ * into an occupied slot in
+ * test_suite_psa_crypto_slot_management.function. */
+
+ psa_key_usage_t source_usage = source_usage_arg;
+ psa_algorithm_t source_alg = source_alg_arg;
+ psa_key_handle_t source_handle = 0;
+ psa_key_policy_t source_policy = PSA_KEY_POLICY_INIT;
+ psa_key_type_t source_type = type_arg;
+ size_t source_bits;
+ psa_key_usage_t target_usage = target_usage_arg;
+ psa_algorithm_t target_alg = target_alg_arg;
+ psa_key_handle_t target_handle = 0;
+ psa_key_policy_t target_policy = PSA_KEY_POLICY_INIT;
+ psa_key_type_t target_type;
+ size_t target_bits;
+ psa_key_usage_t constraint_usage = constraint_usage_arg;
+ psa_algorithm_t constraint_alg = constraint_alg_arg;
+ psa_key_policy_t constraint = PSA_KEY_POLICY_INIT;
+ psa_key_policy_t *p_constraint = NULL;
+ psa_status_t expected_status = expected_status_arg;
+
+ if( constraint_usage_arg != -1 )
+ {
+ p_constraint = &constraint;
+ psa_key_policy_set_usage( p_constraint,
+ constraint_usage, constraint_alg );
+ }
+
+ PSA_ASSERT( psa_crypto_init( ) );
+
+ /* Populate the source slot. */
+ PSA_ASSERT( psa_allocate_key( &source_handle ) );
+ psa_key_policy_set_usage( &source_policy, source_usage, source_alg );
+ PSA_ASSERT( psa_set_key_policy( source_handle, &source_policy ) );
+ PSA_ASSERT( psa_import_key( source_handle, source_type,
+ material->x, material->len ) );
+ PSA_ASSERT( psa_get_key_information( source_handle, NULL, &source_bits ) );
+
+ /* Prepare the target slot. */
+ PSA_ASSERT( psa_allocate_key( &target_handle ) );
+ psa_key_policy_set_usage( &target_policy, target_usage, target_alg );
+ PSA_ASSERT( psa_set_key_policy( target_handle, &target_policy ) );
+ target_policy = psa_key_policy_init();
+
+ /* Copy the key. */
+ TEST_EQUAL( psa_copy_key( source_handle, target_handle, p_constraint ),
+ expected_status );
+
+ /* Test that the target slot is unaffected. */
+ TEST_EQUAL( psa_get_key_information( target_handle,
+ &target_type, &target_bits ),
+ PSA_ERROR_EMPTY_SLOT );
+ PSA_ASSERT( psa_get_key_policy( target_handle, &target_policy ) );
+ TEST_EQUAL( target_usage, psa_key_policy_get_usage( &target_policy ) );
+ TEST_EQUAL( target_alg, psa_key_policy_get_algorithm( &target_policy ) );
+
+exit:
+ mbedtls_psa_crypto_free( );
+}
+/* END_CASE */
+
+/* BEGIN_CASE */
void hash_operation_init( )
{
/* Test each valid way of initializing the object, except for `= {0}`, as
diff --git a/tests/suites/test_suite_psa_crypto_slot_management.data b/tests/suites/test_suite_psa_crypto_slot_management.data
index e8ec40c..c545617 100644
--- a/tests/suites/test_suite_psa_crypto_slot_management.data
+++ b/tests/suites/test_suite_psa_crypto_slot_management.data
@@ -65,6 +65,58 @@
depends_on:!MBEDTLS_PSA_CRYPTO_STORAGE_C
create_fail:PSA_KEY_LIFETIME_PERSISTENT:1:PSA_ERROR_NOT_SUPPORTED
+Copy volatile to volatile
+copy_across_lifetimes:PSA_KEY_LIFETIME_VOLATILE:0:PSA_KEY_USAGE_EXPORT:0:PSA_KEY_TYPE_RAW_DATA:"4142434445":PSA_KEY_LIFETIME_VOLATILE:0:PSA_KEY_USAGE_EXPORT:0:PSA_KEY_USAGE_EXPORT:0
+
+Copy volatile to persistent
+depends_on:MBEDTLS_PSA_CRYPTO_STORAGE_C
+copy_across_lifetimes:PSA_KEY_LIFETIME_VOLATILE:0:PSA_KEY_USAGE_EXPORT:0:PSA_KEY_TYPE_RAW_DATA:"4142434445":PSA_KEY_LIFETIME_PERSISTENT:1:PSA_KEY_USAGE_EXPORT:0:PSA_KEY_USAGE_EXPORT:0
+
+Copy persistent to volatile
+depends_on:MBEDTLS_PSA_CRYPTO_STORAGE_C
+copy_across_lifetimes:PSA_KEY_LIFETIME_PERSISTENT:1:PSA_KEY_USAGE_EXPORT:0:PSA_KEY_TYPE_RAW_DATA:"4142434445":PSA_KEY_LIFETIME_VOLATILE:0:PSA_KEY_USAGE_EXPORT:0:PSA_KEY_USAGE_EXPORT:0
+
+Copy persistent to persistent
+depends_on:MBEDTLS_PSA_CRYPTO_STORAGE_C
+copy_across_lifetimes:PSA_KEY_LIFETIME_PERSISTENT:1:PSA_KEY_USAGE_EXPORT:0:PSA_KEY_TYPE_RAW_DATA:"4142434445":PSA_KEY_LIFETIME_PERSISTENT:2:PSA_KEY_USAGE_EXPORT:0:PSA_KEY_USAGE_EXPORT:0
+
+Copy empty volatile to volatile
+copy_from_empty:PSA_KEY_LIFETIME_VOLATILE:0:PSA_KEY_USAGE_EXPORT:0:PSA_KEY_LIFETIME_VOLATILE:0:PSA_KEY_USAGE_EXPORT:0
+
+Copy empty volatile to persistent
+depends_on:MBEDTLS_PSA_CRYPTO_STORAGE_C
+copy_from_empty:PSA_KEY_LIFETIME_VOLATILE:0:PSA_KEY_USAGE_EXPORT:0:PSA_KEY_LIFETIME_PERSISTENT:1:PSA_KEY_USAGE_EXPORT:0
+
+Copy empty persistent to volatile
+depends_on:MBEDTLS_PSA_CRYPTO_STORAGE_C
+copy_from_empty:PSA_KEY_LIFETIME_PERSISTENT:1:PSA_KEY_USAGE_EXPORT:0:PSA_KEY_LIFETIME_VOLATILE:0:PSA_KEY_USAGE_EXPORT:0
+
+Copy empty persistent to persistent
+depends_on:MBEDTLS_PSA_CRYPTO_STORAGE_C
+copy_from_empty:PSA_KEY_LIFETIME_PERSISTENT:1:PSA_KEY_USAGE_EXPORT:0:PSA_KEY_LIFETIME_PERSISTENT:2:PSA_KEY_USAGE_EXPORT:0
+
+Copy volatile to occupied volatile
+copy_to_occupied:PSA_KEY_LIFETIME_VOLATILE:0:PSA_KEY_USAGE_EXPORT:PSA_ALG_CTR:PSA_KEY_TYPE_AES:"404142434445464748494a4b4c4d4e4f":PSA_KEY_LIFETIME_VOLATILE:0:PSA_KEY_USAGE_EXPORT:PSA_ALG_CBC_NO_PADDING:PSA_KEY_TYPE_AES:"606162636465666768696a6b6c6d6e6f"
+
+Copy volatile to occupied persistent
+depends_on:MBEDTLS_PSA_CRYPTO_STORAGE_C
+copy_to_occupied:PSA_KEY_LIFETIME_VOLATILE:0:PSA_KEY_USAGE_EXPORT:PSA_ALG_CTR:PSA_KEY_TYPE_AES:"404142434445464748494a4b4c4d4e4f":PSA_KEY_LIFETIME_PERSISTENT:2:PSA_KEY_USAGE_EXPORT:PSA_ALG_CBC_NO_PADDING:PSA_KEY_TYPE_AES:"606162636465666768696a6b6c6d6e6f"
+
+Copy persistent to occupied volatile
+depends_on:MBEDTLS_PSA_CRYPTO_STORAGE_C
+copy_to_occupied:PSA_KEY_LIFETIME_PERSISTENT:1:PSA_KEY_USAGE_EXPORT:PSA_ALG_CTR:PSA_KEY_TYPE_AES:"404142434445464748494a4b4c4d4e4f":PSA_KEY_LIFETIME_VOLATILE:0:PSA_KEY_USAGE_EXPORT:PSA_ALG_CBC_NO_PADDING:PSA_KEY_TYPE_AES:"606162636465666768696a6b6c6d6e6f"
+
+Copy persistent to occupied persistent
+depends_on:MBEDTLS_PSA_CRYPTO_STORAGE_C
+copy_to_occupied:PSA_KEY_LIFETIME_PERSISTENT:1:PSA_KEY_USAGE_EXPORT:PSA_ALG_CTR:PSA_KEY_TYPE_AES:"404142434445464748494a4b4c4d4e4f":PSA_KEY_LIFETIME_PERSISTENT:2:PSA_KEY_USAGE_EXPORT:PSA_ALG_CBC_NO_PADDING:PSA_KEY_TYPE_AES:"606162636465666768696a6b6c6d6e6f"
+
+Copy volatile to itself
+copy_to_same:PSA_KEY_LIFETIME_VOLATILE:0:PSA_KEY_USAGE_EXPORT:PSA_ALG_CTR:PSA_KEY_TYPE_AES:"404142434445464748494a4b4c4d4e4f"
+
+Copy persistent to itself
+depends_on:MBEDTLS_PSA_CRYPTO_STORAGE_C
+copy_to_same:PSA_KEY_LIFETIME_VOLATILE:0:PSA_KEY_USAGE_EXPORT:PSA_ALG_CTR:PSA_KEY_TYPE_AES:"404142434445464748494a4b4c4d4e4f"
+
Close/destroy invalid handle
invalid_handle:
diff --git a/tests/suites/test_suite_psa_crypto_slot_management.function b/tests/suites/test_suite_psa_crypto_slot_management.function
index 46fafcc..0ebdb1e 100644
--- a/tests/suites/test_suite_psa_crypto_slot_management.function
+++ b/tests/suites/test_suite_psa_crypto_slot_management.function
@@ -294,6 +294,321 @@
/* END_CASE */
/* BEGIN_CASE */
+void copy_across_lifetimes( int source_lifetime_arg, int source_id_arg,
+ int source_usage_arg, int source_alg_arg,
+ int type_arg, data_t *material,
+ int target_lifetime_arg, int target_id_arg,
+ int target_usage_arg, int target_alg_arg,
+ int expected_usage_arg, int expected_alg_arg )
+{
+ psa_key_lifetime_t source_lifetime = source_lifetime_arg;
+ psa_key_id_t source_id = source_id_arg;
+ psa_key_usage_t source_usage = source_usage_arg;
+ psa_algorithm_t source_alg = source_alg_arg;
+ psa_key_handle_t source_handle = 0;
+ psa_key_policy_t source_policy = PSA_KEY_POLICY_INIT;
+ psa_key_type_t source_type = type_arg;
+ size_t source_bits;
+ psa_key_lifetime_t target_lifetime = target_lifetime_arg;
+ psa_key_id_t target_id = target_id_arg;
+ psa_key_usage_t target_usage = target_usage_arg;
+ psa_algorithm_t target_alg = target_alg_arg;
+ psa_key_handle_t target_handle = 0;
+ psa_key_policy_t target_policy = PSA_KEY_POLICY_INIT;
+ psa_key_type_t target_type;
+ size_t target_bits;
+ psa_key_usage_t expected_usage = expected_usage_arg;
+ psa_algorithm_t expected_alg = expected_alg_arg;
+ uint8_t *export_buffer = NULL;
+
+ TEST_MAX_KEY_ID( source_id );
+ TEST_MAX_KEY_ID( target_id );
+
+ PSA_ASSERT( psa_crypto_init( ) );
+
+ /* Populate the source slot. */
+ if( source_lifetime == PSA_KEY_LIFETIME_VOLATILE )
+ PSA_ASSERT( psa_allocate_key( &source_handle ) );
+ else
+ PSA_ASSERT( psa_create_key( source_lifetime, source_id,
+ &source_handle ) );
+ psa_key_policy_set_usage( &source_policy, source_usage, source_alg );
+ PSA_ASSERT( psa_set_key_policy( source_handle, &source_policy ) );
+ PSA_ASSERT( psa_import_key( source_handle, source_type,
+ material->x, material->len ) );
+ PSA_ASSERT( psa_get_key_information( source_handle, NULL, &source_bits ) );
+
+ /* Prepare the target slot. */
+ if( target_lifetime == PSA_KEY_LIFETIME_VOLATILE )
+ PSA_ASSERT( psa_allocate_key( &target_handle ) );
+ else
+ PSA_ASSERT( psa_create_key( target_lifetime, target_id,
+ &target_handle ) );
+ psa_key_policy_set_usage( &target_policy, target_usage, target_alg );
+ PSA_ASSERT( psa_set_key_policy( target_handle, &target_policy ) );
+ target_policy = psa_key_policy_init();
+
+ /* Copy the key. */
+ PSA_ASSERT( psa_copy_key( source_handle, target_handle, NULL ) );
+
+ /* Destroy the source to ensure that this doesn't affect the target. */
+ PSA_ASSERT( psa_destroy_key( source_handle ) );
+
+ /* If the target key is persistent, restart the system to make
+ * sure that the material is still alive. */
+ if( target_lifetime != PSA_KEY_LIFETIME_VOLATILE )
+ {
+ mbedtls_psa_crypto_free( );
+ PSA_ASSERT( psa_crypto_init( ) );
+ PSA_ASSERT( psa_open_key( target_lifetime, target_id,
+ &target_handle ) );
+ }
+
+ /* Test that the target slot has the expected content. */
+ PSA_ASSERT( psa_get_key_information( target_handle,
+ &target_type, &target_bits ) );
+ TEST_EQUAL( source_type, target_type );
+ TEST_EQUAL( source_bits, target_bits );
+ PSA_ASSERT( psa_get_key_policy( target_handle, &target_policy ) );
+ TEST_EQUAL( expected_usage, psa_key_policy_get_usage( &target_policy ) );
+ TEST_EQUAL( expected_alg, psa_key_policy_get_algorithm( &target_policy ) );
+ if( expected_usage & PSA_KEY_USAGE_EXPORT )
+ {
+ size_t length;
+ ASSERT_ALLOC( export_buffer, material->len );
+ PSA_ASSERT( psa_export_key( target_handle, export_buffer,
+ material->len, &length ) );
+ ASSERT_COMPARE( material->x, material->len,
+ export_buffer, length );
+ }
+
+exit:
+ mbedtls_psa_crypto_free( );
+ mbedtls_free( export_buffer );
+#if defined(MBEDTLS_PSA_CRYPTO_STORAGE_C)
+ psa_purge_key_storage( );
+#endif
+}
+/* END_CASE */
+
+/* BEGIN_CASE */
+void copy_from_empty( int source_lifetime_arg, int source_id_arg,
+ int source_usage_arg, int source_alg_arg,
+ int target_lifetime_arg, int target_id_arg,
+ int target_usage_arg, int target_alg_arg )
+{
+ psa_key_lifetime_t source_lifetime = source_lifetime_arg;
+ psa_key_id_t source_id = source_id_arg;
+ psa_key_usage_t source_usage = source_usage_arg;
+ psa_algorithm_t source_alg = source_alg_arg;
+ psa_key_handle_t source_handle = 0;
+ psa_key_policy_t source_policy = PSA_KEY_POLICY_INIT;
+ psa_key_lifetime_t target_lifetime = target_lifetime_arg;
+ psa_key_id_t target_id = target_id_arg;
+ psa_key_usage_t target_usage = target_usage_arg;
+ psa_algorithm_t target_alg = target_alg_arg;
+ psa_key_handle_t target_handle = 0;
+ psa_key_policy_t target_policy = PSA_KEY_POLICY_INIT;
+ psa_key_policy_t got_policy;
+
+ TEST_MAX_KEY_ID( source_id );
+ TEST_MAX_KEY_ID( target_id );
+
+ PSA_ASSERT( psa_crypto_init( ) );
+
+ /* Prepare the source slot. */
+ if( source_lifetime == PSA_KEY_LIFETIME_VOLATILE )
+ PSA_ASSERT( psa_allocate_key( &source_handle ) );
+ else
+ PSA_ASSERT( psa_create_key( source_lifetime, source_id,
+ &source_handle ) );
+ psa_key_policy_set_usage( &source_policy, source_usage, source_alg );
+ PSA_ASSERT( psa_set_key_policy( source_handle, &source_policy ) );
+
+ /* Prepare the target slot. */
+ if( target_lifetime == PSA_KEY_LIFETIME_VOLATILE )
+ PSA_ASSERT( psa_allocate_key( &target_handle ) );
+ else
+ PSA_ASSERT( psa_create_key( target_lifetime, target_id,
+ &target_handle ) );
+ psa_key_policy_set_usage( &target_policy, target_usage, target_alg );
+ PSA_ASSERT( psa_set_key_policy( target_handle, &target_policy ) );
+
+ /* Copy the key. */
+ TEST_EQUAL( psa_copy_key( source_handle, target_handle, NULL ),
+ PSA_ERROR_EMPTY_SLOT );
+
+ /* Test that the slots are unaffected. */
+ PSA_ASSERT( psa_get_key_policy( source_handle, &got_policy ) );
+ TEST_EQUAL( source_usage, psa_key_policy_get_usage( &got_policy ) );
+ TEST_EQUAL( source_alg, psa_key_policy_get_algorithm( &got_policy ) );
+ PSA_ASSERT( psa_get_key_policy( target_handle, &got_policy ) );
+ TEST_EQUAL( target_usage, psa_key_policy_get_usage( &got_policy ) );
+ TEST_EQUAL( target_alg, psa_key_policy_get_algorithm( &got_policy ) );
+
+exit:
+ mbedtls_psa_crypto_free( );
+#if defined(MBEDTLS_PSA_CRYPTO_STORAGE_C)
+ psa_purge_key_storage( );
+#endif
+}
+/* END_CASE */
+
+/* BEGIN_CASE */
+void copy_to_occupied( int source_lifetime_arg, int source_id_arg,
+ int source_usage_arg, int source_alg_arg,
+ int source_type_arg, data_t *source_material,
+ int target_lifetime_arg, int target_id_arg,
+ int target_usage_arg, int target_alg_arg,
+ int target_type_arg, data_t *target_material )
+{
+ psa_key_lifetime_t source_lifetime = source_lifetime_arg;
+ psa_key_id_t source_id = source_id_arg;
+ psa_key_usage_t source_usage = source_usage_arg;
+ psa_algorithm_t source_alg = source_alg_arg;
+ psa_key_handle_t source_handle = 0;
+ psa_key_policy_t source_policy = PSA_KEY_POLICY_INIT;
+ psa_key_type_t source_type = source_type_arg;
+ size_t source_bits;
+ psa_key_lifetime_t target_lifetime = target_lifetime_arg;
+ psa_key_id_t target_id = target_id_arg;
+ psa_key_usage_t target_usage = target_usage_arg;
+ psa_algorithm_t target_alg = target_alg_arg;
+ psa_key_handle_t target_handle = 0;
+ psa_key_policy_t target_policy = PSA_KEY_POLICY_INIT;
+ psa_key_type_t target_type = target_type_arg;
+ size_t target_bits;
+ psa_key_policy_t got_policy;
+ psa_key_type_t got_type;
+ size_t got_bits;
+ uint8_t *export_buffer = NULL;
+
+ TEST_MAX_KEY_ID( source_id );
+ TEST_MAX_KEY_ID( target_id );
+
+ PSA_ASSERT( psa_crypto_init( ) );
+
+ /* Populate the source slot. */
+ if( source_lifetime == PSA_KEY_LIFETIME_VOLATILE )
+ PSA_ASSERT( psa_allocate_key( &source_handle ) );
+ else
+ PSA_ASSERT( psa_create_key( source_lifetime, source_id,
+ &source_handle ) );
+ psa_key_policy_set_usage( &source_policy, source_usage, source_alg );
+ PSA_ASSERT( psa_set_key_policy( source_handle, &source_policy ) );
+ PSA_ASSERT( psa_import_key( source_handle, source_type,
+ source_material->x, source_material->len ) );
+ PSA_ASSERT( psa_get_key_information( source_handle, NULL, &source_bits ) );
+
+ /* Populate the target slot. */
+ if( target_lifetime == PSA_KEY_LIFETIME_VOLATILE )
+ PSA_ASSERT( psa_allocate_key( &target_handle ) );
+ else
+ PSA_ASSERT( psa_create_key( target_lifetime, target_id,
+ &target_handle ) );
+ psa_key_policy_set_usage( &target_policy, target_usage, target_alg );
+ PSA_ASSERT( psa_set_key_policy( target_handle, &target_policy ) );
+ PSA_ASSERT( psa_import_key( target_handle, target_type,
+ target_material->x, target_material->len ) );
+ PSA_ASSERT( psa_get_key_information( target_handle, NULL, &target_bits ) );
+
+ /* Copy the key. */
+ TEST_EQUAL( psa_copy_key( source_handle, target_handle, NULL ),
+ PSA_ERROR_OCCUPIED_SLOT );
+
+ /* Test that the target slot is unaffected. */
+ PSA_ASSERT( psa_get_key_information( target_handle,
+ &got_type, &got_bits ) );
+ TEST_EQUAL( target_type, got_type );
+ TEST_EQUAL( target_bits, got_bits );
+ PSA_ASSERT( psa_get_key_policy( target_handle, &got_policy ) );
+ TEST_EQUAL( target_usage, psa_key_policy_get_usage( &got_policy ) );
+ TEST_EQUAL( target_alg, psa_key_policy_get_algorithm( &got_policy ) );
+ if( target_usage & PSA_KEY_USAGE_EXPORT )
+ {
+ size_t length;
+ ASSERT_ALLOC( export_buffer, target_material->len );
+ PSA_ASSERT( psa_export_key( target_handle, export_buffer,
+ target_material->len, &length ) );
+ ASSERT_COMPARE( target_material->x, target_material->len,
+ export_buffer, length );
+ }
+
+exit:
+ mbedtls_psa_crypto_free( );
+ mbedtls_free( export_buffer );
+#if defined(MBEDTLS_PSA_CRYPTO_STORAGE_C)
+ psa_purge_key_storage( );
+#endif
+}
+/* END_CASE */
+
+/* BEGIN_CASE */
+void copy_to_same( int lifetime_arg, int id_arg,
+ int usage_arg, int alg_arg,
+ int type_arg, data_t *material )
+{
+ psa_key_lifetime_t lifetime = lifetime_arg;
+ psa_key_id_t id = id_arg;
+ psa_key_usage_t usage = usage_arg;
+ psa_algorithm_t alg = alg_arg;
+ psa_key_handle_t handle = 0;
+ psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
+ psa_key_type_t type = type_arg;
+ size_t bits;
+ psa_key_policy_t got_policy;
+ psa_key_type_t got_type;
+ size_t got_bits;
+ uint8_t *export_buffer = NULL;
+
+ TEST_MAX_KEY_ID( id );
+
+ PSA_ASSERT( psa_crypto_init( ) );
+
+ /* Populate the slot. */
+ if( lifetime == PSA_KEY_LIFETIME_VOLATILE )
+ PSA_ASSERT( psa_allocate_key( &handle ) );
+ else
+ PSA_ASSERT( psa_create_key( lifetime, id,
+ &handle ) );
+ psa_key_policy_set_usage( &policy, usage, alg );
+ PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
+ PSA_ASSERT( psa_import_key( handle, type,
+ material->x, material->len ) );
+ PSA_ASSERT( psa_get_key_information( handle, NULL, &bits ) );
+
+ /* Copy the key. */
+ TEST_EQUAL( psa_copy_key( handle, handle, NULL ),
+ PSA_ERROR_OCCUPIED_SLOT );
+
+ /* Test that the slot is unaffected. */
+ PSA_ASSERT( psa_get_key_information( handle,
+ &got_type, &got_bits ) );
+ TEST_EQUAL( type, got_type );
+ TEST_EQUAL( bits, got_bits );
+ PSA_ASSERT( psa_get_key_policy( handle, &got_policy ) );
+ TEST_EQUAL( usage, psa_key_policy_get_usage( &got_policy ) );
+ TEST_EQUAL( alg, psa_key_policy_get_algorithm( &got_policy ) );
+ if( usage & PSA_KEY_USAGE_EXPORT )
+ {
+ size_t length;
+ ASSERT_ALLOC( export_buffer, material->len );
+ PSA_ASSERT( psa_export_key( handle, export_buffer,
+ material->len, &length ) );
+ ASSERT_COMPARE( material->x, material->len,
+ export_buffer, length );
+ }
+
+exit:
+ mbedtls_psa_crypto_free( );
+ mbedtls_free( export_buffer );
+#if defined(MBEDTLS_PSA_CRYPTO_STORAGE_C)
+ psa_purge_key_storage( );
+#endif
+}
+/* END_CASE */
+
+/* BEGIN_CASE */
void invalid_handle( )
{
psa_key_handle_t handle1 = 0;