Test psa_copy_key

Split the testing into tests that exercise policies in
test_suite_psa_crypto and tests that exercise slot content (slot
states, key material) in test_suite_psa_crypto_slot_management.

Test various cases of source and target policies with and without
wildcards. Missing: testing of the policy constraint on psa_copy_key
itself.

Test several key types (raw data, AES, RSA). Test with the
source or target being persistent.

Add failure tests (incompatible policies, source slot empty, target
slot occupied).
diff --git a/tests/suites/test_suite_psa_crypto.data b/tests/suites/test_suite_psa_crypto.data
index 656418d..2cde60a 100644
--- a/tests/suites/test_suite_psa_crypto.data
+++ b/tests/suites/test_suite_psa_crypto.data
@@ -492,6 +492,73 @@
 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, 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_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: 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 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, 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 a9d76db..87ad1ff 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;
+#elif defined(MBEDTLS_RIPEMD160_C)
+        hash_alg = PSA_ALG_RIPEMD160;
+#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,
@@ -1742,6 +1767,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 7295758..c545617 100644
--- a/tests/suites/test_suite_psa_crypto_slot_management.data
+++ b/tests/suites/test_suite_psa_crypto_slot_management.data
@@ -66,16 +66,56 @@
 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:-1:-1:PSA_KEY_USAGE_EXPORT:0
+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
-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:-1:-1:PSA_KEY_USAGE_EXPORT:0
+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
-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:-1:-1:PSA_KEY_USAGE_EXPORT:0
+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
-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:-1:-1:PSA_KEY_USAGE_EXPORT:0
+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 8a6ef07..0ebdb1e 100644
--- a/tests/suites/test_suite_psa_crypto_slot_management.function
+++ b/tests/suites/test_suite_psa_crypto_slot_management.function
@@ -299,7 +299,6 @@
                             int type_arg, data_t *material,
                             int target_lifetime_arg, int target_id_arg,
                             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_lifetime_t source_lifetime = source_lifetime_arg;
@@ -318,20 +317,10 @@
     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 );
-    }
     TEST_MAX_KEY_ID( source_id );
     TEST_MAX_KEY_ID( target_id );
 
@@ -360,7 +349,7 @@
     target_policy = psa_key_policy_init();
 
     /* Copy the key. */
-    PSA_ASSERT( psa_copy_key( source_handle, target_handle, p_constraint ) );
+    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 ) );
@@ -378,11 +367,11 @@
     /* Test that the target slot has the expected content. */
     PSA_ASSERT( psa_get_key_information( target_handle,
                                          &target_type, &target_bits ) );
-    TEST_ASSERT( source_type == target_type );
-    TEST_ASSERT( source_bits == 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_ASSERT( expected_usage == psa_key_policy_get_usage( &target_policy ) );
-    TEST_ASSERT( expected_alg == psa_key_policy_get_algorithm( &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;
@@ -403,6 +392,223 @@
 /* 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;