Merge pull request #109 from ARMmbed/IAR-feature-psa

Ensure release testing job passes IAR tests
diff --git a/include/psa/crypto.h b/include/psa/crypto.h
index 8ac817a..f282aa2 100644
--- a/include/psa/crypto.h
+++ b/include/psa/crypto.h
@@ -285,12 +285,18 @@
  * depend on the validity of the padding. */
 #define PSA_ERROR_INVALID_PADDING       ((psa_status_t)16)
 
+/** The generator has insufficient capacity left.
+ *
+ * Once a function returns this error, attempts to read from the
+ * generator will always return this error. */
+#define PSA_ERROR_INSUFFICIENT_CAPACITY ((psa_status_t)17)
+
 /** An error occurred that does not correspond to any defined
  * failure cause.
  *
  * Implementations may use this error code if none of the other standard
  * error codes are applicable. */
-#define PSA_ERROR_UNKNOWN_ERROR         ((psa_status_t)17)
+#define PSA_ERROR_UNKNOWN_ERROR         ((psa_status_t)18)
 
 /**
  * \brief Library initialization.
@@ -360,6 +366,13 @@
  * \c alg is the HMAC algorithm or the underlying hash algorithm. */
 #define PSA_KEY_TYPE_HMAC                       ((psa_key_type_t)0x02000001)
 
+/** A secret for key derivation.
+ *
+ * The key policy determines which key derivation algorithm the key
+ * can be used for.
+ */
+#define PSA_KEY_TYPE_DERIVE                     ((psa_key_type_t)0x02000101)
+
 /** Key for an cipher, AEAD or MAC algorithm based on the AES block cipher.
  *
  * The size of the key can be 16 bytes (AES-128), 24 bytes (AES-192) or
@@ -430,13 +443,20 @@
 /** The public key type corresponding to a key pair type. */
 #define PSA_KEY_TYPE_PUBLIC_KEY_OF_KEYPAIR(type)        \
     ((type) & ~PSA_KEY_TYPE_PAIR_FLAG)
-/** Whether a key type is an RSA key pair or public key. */
+/** Whether a key type is an RSA key (pair or public-only). */
 #define PSA_KEY_TYPE_IS_RSA(type)                                       \
     (PSA_KEY_TYPE_PUBLIC_KEY_OF_KEYPAIR(type) == PSA_KEY_TYPE_RSA_PUBLIC_KEY)
-/** Whether a key type is an elliptic curve key pair or public key. */
+
+/** Whether a key type is an elliptic curve key (pair or public-only). */
 #define PSA_KEY_TYPE_IS_ECC(type)                                       \
     ((PSA_KEY_TYPE_PUBLIC_KEY_OF_KEYPAIR(type) &                        \
       ~PSA_KEY_TYPE_ECC_CURVE_MASK) == PSA_KEY_TYPE_ECC_PUBLIC_KEY_BASE)
+#define PSA_KEY_TYPE_IS_ECC_KEYPAIR(type)                               \
+    (((type) & ~PSA_KEY_TYPE_ECC_CURVE_MASK) ==                         \
+     PSA_KEY_TYPE_ECC_KEYPAIR_BASE)
+#define PSA_KEY_TYPE_IS_ECC_PUBLIC_KEY(type)                            \
+    (((type) & ~PSA_KEY_TYPE_ECC_CURVE_MASK) ==                         \
+     PSA_KEY_TYPE_ECC_PUBLIC_KEY_BASE)
 
 /** The type of PSA elliptic curve identifiers. */
 typedef uint16_t psa_ecc_curve_t;
@@ -803,7 +823,8 @@
  *
  * This is the signature scheme defined by RFC 8017
  * (PKCS#1: RSA Cryptography Specifications) under the name
- * RSASSA-PSS, with the message generation function MGF1. The specified
+ * RSASSA-PSS, with the message generation function MGF1, and with
+ * a salt length equal to the length of the hash. The specified
  * hash algorithm is used to hash the input message, to create the
  * salted hash, and for the mask generation.
  *
@@ -843,6 +864,10 @@
      PSA_ALG_DSA_BASE)
 #define PSA_ALG_DSA_IS_DETERMINISTIC(alg)               \
     (((alg) & PSA_ALG_DSA_DETERMINISTIC_FLAG) != 0)
+#define PSA_ALG_IS_DETERMINISTIC_DSA(alg)                       \
+    (PSA_ALG_IS_DSA(alg) && PSA_ALG_DSA_IS_DETERMINISTIC(alg))
+#define PSA_ALG_IS_RANDOMIZED_DSA(alg)                          \
+    (PSA_ALG_IS_DSA(alg) && !PSA_ALG_DSA_IS_DETERMINISTIC(alg))
 
 #define PSA_ALG_ECDSA_BASE                      ((psa_algorithm_t)0x10060000)
 /** ECDSA signature with hashing.
@@ -903,6 +928,10 @@
      PSA_ALG_ECDSA_BASE)
 #define PSA_ALG_ECDSA_IS_DETERMINISTIC(alg)             \
     (((alg) & PSA_ALG_DSA_DETERMINISTIC_FLAG) != 0)
+#define PSA_ALG_IS_DETERMINISTIC_ECDSA(alg)                             \
+    (PSA_ALG_IS_ECDSA(alg) && PSA_ALG_ECDSA_IS_DETERMINISTIC(alg))
+#define PSA_ALG_IS_RANDOMIZED_ECDSA(alg)                                \
+    (PSA_ALG_IS_ECDSA(alg) && !PSA_ALG_ECDSA_IS_DETERMINISTIC(alg))
 
 /** Get the hash used by a hash-and-sign signature algorithm.
  *
@@ -925,6 +954,7 @@
 #define PSA_ALG_SIGN_GET_HASH(alg)                                     \
     (PSA_ALG_IS_RSA_PSS(alg) || PSA_ALG_IS_RSA_PKCS1V15_SIGN(alg) ||   \
      PSA_ALG_IS_DSA(alg) || PSA_ALG_IS_ECDSA(alg) ?                    \
+     ((alg) & PSA_ALG_HASH_MASK) == 0 ? /*"raw" algorithm*/ 0 :        \
      ((alg) & PSA_ALG_HASH_MASK) | PSA_ALG_CATEGORY_HASH :             \
      0)
 
@@ -951,6 +981,40 @@
     (PSA_ALG_RSA_OAEP_BASE | ((hash_alg) & PSA_ALG_HASH_MASK))
 #define PSA_ALG_IS_RSA_OAEP(alg)                                \
     (((alg) & ~PSA_ALG_HASH_MASK) == PSA_ALG_RSA_OAEP_BASE)
+#define PSA_ALG_RSA_OAEP_GET_HASH(alg)                          \
+    (PSA_ALG_IS_RSA_OAEP(alg) ?                                 \
+     ((alg) & PSA_ALG_HASH_MASK) | PSA_ALG_CATEGORY_HASH :      \
+     0)
+
+#define PSA_ALG_HKDF_BASE                       ((psa_algorithm_t)0x30000100)
+/** Macro to build an HKDF algorithm.
+ *
+ * For example, `PSA_ALG_HKDF(PSA_ALG_SHA256)` is HKDF using HMAC-SHA-256.
+ *
+ * \param hash_alg      A hash algorithm (\c PSA_ALG_XXX value such that
+ *                      #PSA_ALG_IS_HASH(\p hash_alg) is true).
+ *
+ * \return              The corresponding HKDF algorithm.
+ * \return              Unspecified if \p alg is not a supported
+ *                      hash algorithm.
+ */
+#define PSA_ALG_HKDF(hash_alg)                                  \
+    (PSA_ALG_HKDF_BASE | ((hash_alg) & PSA_ALG_HASH_MASK))
+/** Whether the specified algorithm is an HKDF algorithm.
+ *
+ * HKDF is a family of key derivation algorithms that are based on a hash
+ * function and the HMAC construction.
+ *
+ * \param alg An algorithm identifier (value of type #psa_algorithm_t).
+ *
+ * \return 1 if \c alg is an HKDF algorithm, 0 otherwise.
+ *         This macro may return either 0 or 1 if \c alg is not a supported
+ *         key derivation algorithm identifier.
+ */
+#define PSA_ALG_IS_HKDF(alg)                            \
+    (((alg) & ~PSA_ALG_HASH_MASK) == PSA_ALG_HKDF_BASE)
+#define PSA_ALG_HKDF_GET_HASH(hkdf_alg)                         \
+    (PSA_ALG_CATEGORY_HASH | ((hkdf_alg) & PSA_ALG_HASH_MASK))
 
 /**@}*/
 
@@ -1188,6 +1252,10 @@
  */
 #define PSA_KEY_USAGE_VERIFY                    ((psa_key_usage_t)0x00000800)
 
+/** Whether the key may be used to derive other keys.
+ */
+#define PSA_KEY_USAGE_DERIVE                    ((psa_key_usage_t)0x00001000)
+
 /** The type of the key policy data structure.
  *
  * This is an implementation-defined \c struct. Applications should not
@@ -2145,17 +2213,17 @@
  * \retval #PSA_ERROR_HARDWARE_FAILURE
  * \retval #PSA_ERROR_TAMPERING_DETECTED
  */
-psa_status_t psa_aead_encrypt( psa_key_slot_t key,
-                               psa_algorithm_t alg,
-                               const uint8_t *nonce,
-                               size_t nonce_length,
-                               const uint8_t *additional_data,
-                               size_t additional_data_length,
-                               const uint8_t *plaintext,
-                               size_t plaintext_length,
-                               uint8_t *ciphertext,
-                               size_t ciphertext_size,
-                               size_t *ciphertext_length );
+psa_status_t psa_aead_encrypt(psa_key_slot_t key,
+                              psa_algorithm_t alg,
+                              const uint8_t *nonce,
+                              size_t nonce_length,
+                              const uint8_t *additional_data,
+                              size_t additional_data_length,
+                              const uint8_t *plaintext,
+                              size_t plaintext_length,
+                              uint8_t *ciphertext,
+                              size_t ciphertext_size,
+                              size_t *ciphertext_length);
 
 /** Process an authenticated decryption operation.
  *
@@ -2198,17 +2266,17 @@
  * \retval #PSA_ERROR_HARDWARE_FAILURE
  * \retval #PSA_ERROR_TAMPERING_DETECTED
  */
-psa_status_t psa_aead_decrypt( psa_key_slot_t key,
-                               psa_algorithm_t alg,
-                               const uint8_t *nonce,
-                               size_t nonce_length,
-                               const uint8_t *additional_data,
-                               size_t additional_data_length,
-                               const uint8_t *ciphertext,
-                               size_t ciphertext_length,
-                               uint8_t *plaintext,
-                               size_t plaintext_size,
-                               size_t *plaintext_length );
+psa_status_t psa_aead_decrypt(psa_key_slot_t key,
+                              psa_algorithm_t alg,
+                              const uint8_t *nonce,
+                              size_t nonce_length,
+                              const uint8_t *additional_data,
+                              size_t additional_data_length,
+                              const uint8_t *ciphertext,
+                              size_t ciphertext_length,
+                              uint8_t *plaintext,
+                              size_t plaintext_size,
+                              size_t *plaintext_length);
 
 /**@}*/
 
@@ -2241,15 +2309,6 @@
  *                              the type of \p key.
  * \param[in] hash              The hash or message to sign.
  * \param hash_length           Size of the \p hash buffer in bytes.
- * \param[in] salt              A salt or label, if supported by the
- *                              signature algorithm.
- *                              If the signature algorithm does not support
- *                              a salt, pass \c NULL.
- *                              If the signature algorithm supports an
- *                              optional salt and you do not want to pass
- *                              a salt, pass \c NULL.
- * \param salt_length           Size of the \p salt buffer in bytes.
- *                              If \p salt is \c NULL, pass 0.
  * \param[out] signature        Buffer where the signature is to be written.
  * \param signature_size        Size of the \p signature buffer in bytes.
  * \param[out] signature_length On success, the number of bytes
@@ -2274,8 +2333,6 @@
                                  psa_algorithm_t alg,
                                  const uint8_t *hash,
                                  size_t hash_length,
-                                 const uint8_t *salt,
-                                 size_t salt_length,
                                  uint8_t *signature,
                                  size_t signature_size,
                                  size_t *signature_length);
@@ -2296,15 +2353,6 @@
  * \param[in] hash          The hash or message whose signature is to be
  *                          verified.
  * \param hash_length       Size of the \p hash buffer in bytes.
- * \param[in] salt          A salt or label, if supported by the signature
- *                          algorithm.
- *                          If the signature algorithm does not support a
- *                          salt, pass \c NULL.
- *                          If the signature algorithm supports an optional
- *                          salt and you do not want to pass a salt,
- *                          pass \c NULL.
- * \param salt_length       Size of the \p salt buffer in bytes.
- *                          If \p salt is \c NULL, pass 0.
  * \param[in] signature     Buffer containing the signature to verify.
  * \param signature_length  Size of the \p signature buffer in bytes.
  *
@@ -2324,14 +2372,12 @@
                                    psa_algorithm_t alg,
                                    const uint8_t *hash,
                                    size_t hash_length,
-                                   const uint8_t *salt,
-                                   size_t salt_length,
                                    const uint8_t *signature,
                                    size_t signature_length);
 
 #define PSA_RSA_MINIMUM_PADDING_SIZE(alg)                               \
-    (PSA_ALG_IS_RSA_OAEP_MGF1(alg) ?                                    \
-     2 * PSA_HASH_FINAL_SIZE(PSA_ALG_RSA_GET_HASH(alg)) + 1 :           \
+    (PSA_ALG_IS_RSA_OAEP(alg) ?                                         \
+     2 * PSA_HASH_FINAL_SIZE(PSA_ALG_RSA_OAEP_GET_HASH(alg)) + 1 :      \
      11 /*PKCS#1v1.5*/)
 
 /**
@@ -2440,6 +2486,228 @@
 
 /**@}*/
 
+/** \defgroup generation Generators
+ * @{
+ */
+
+/** The type of the state data structure for generators.
+ *
+ * Before calling any function on a generator, the application must
+ * initialize it by any of the following means:
+ * - Set the structure to all-bits-zero, for example:
+ *   \code
+ *   psa_crypto_generator_t generator;
+ *   memset(&generator, 0, sizeof(generator));
+ *   \endcode
+ * - Initialize the structure to logical zero values, for example:
+ *   \code
+ *   psa_crypto_generator_t generator = {0};
+ *   \endcode
+ * - Initialize the structure to the initializer #PSA_CRYPTO_GENERATOR_INIT,
+ *   for example:
+ *   \code
+ *   psa_crypto_generator_t generator = PSA_CRYPTO_GENERATOR_INIT;
+ *   \endcode
+ * - Assign the result of the function psa_crypto_generator_init()
+ *   to the structure, for example:
+ *   \code
+ *   psa_crypto_generator_t generator;
+ *   generator = psa_crypto_generator_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_crypto_generator_s psa_crypto_generator_t;
+
+/** \def PSA_CRYPTO_GENERATOR_INIT
+ *
+ * This macro returns a suitable initializer for a generator object
+ * of type #psa_crypto_generator_t.
+ */
+#ifdef __DOXYGEN_ONLY__
+/* This is an example definition for documentation purposes.
+ * Implementations should define a suitable value in `crypto_struct.h`.
+ */
+#define PSA_CRYPTO_GENERATOR_INIT {0}
+#endif
+
+/** Return an initial value for a generator object.
+ */
+static psa_crypto_generator_t psa_crypto_generator_init(void);
+
+/** Retrieve the current capacity of a generator.
+ *
+ * The capacity of a generator is the maximum number of bytes that it can
+ * return. Reading *N* bytes from a generator reduces its capacity by *N*.
+ *
+ * \param[in] generator     The generator to query.
+ * \param[out] capacity     On success, the capacity of the generator.
+ *
+ * \retval PSA_SUCCESS
+ * \retval PSA_ERROR_BAD_STATE
+ * \retval PSA_ERROR_COMMUNICATION_FAILURE
+ */
+psa_status_t psa_get_generator_capacity(const psa_crypto_generator_t *generator,
+                                        size_t *capacity);
+
+/** Read some data from a generator.
+ *
+ * This function reads and returns a sequence of bytes from a generator.
+ * The data that is read is discarded from the generator. The generator's
+ * capacity is decreased by the number of bytes read.
+ *
+ * \param[in,out] generator The generator object to read from.
+ * \param[out] output       Buffer where the generator output will be
+ *                          written.
+ * \param output_length     Number of bytes to output.
+ *
+ * \retval PSA_SUCCESS
+ * \retval PSA_ERROR_INSUFFICIENT_CAPACITY
+ *                          There were fewer than \p output_length bytes
+ *                          in the generator. Note that in this case, no
+ *                          output is written to the output buffer.
+ *                          The generator's capacity is set to 0, thus
+ *                          subsequent calls to this function will not
+ *                          succeed, even with a smaller output buffer.
+ * \retval PSA_ERROR_BAD_STATE
+ * \retval PSA_ERROR_INSUFFICIENT_MEMORY
+ * \retval PSA_ERROR_COMMUNICATION_FAILURE
+ * \retval PSA_ERROR_HARDWARE_FAILURE
+ * \retval PSA_ERROR_TAMPERING_DETECTED
+ */
+psa_status_t psa_generator_read(psa_crypto_generator_t *generator,
+                                uint8_t *output,
+                                size_t output_length);
+
+/** Create a symmetric key from data read from a generator.
+ *
+ * This function reads a sequence of bytes from a generator and imports
+ * these bytes as a key.
+ * The data that is read is discarded from the generator. The generator's
+ * capacity is decreased by the number of bytes read.
+ *
+ * This function is equivalent to calling #psa_generator_read and
+ * passing the resulting output to #psa_import_key, but
+ * if the implementation provides an isolation boundary then
+ * the key material is not exposed outside the isolation boundary.
+ *
+ * \param key               Slot where the key will be stored. This must be a
+ *                          valid slot for a key of the chosen type. It must
+ *                          be unoccupied.
+ * \param type              Key type (a \c PSA_KEY_TYPE_XXX value).
+ *                          This must be a symmetric key type.
+ * \param bits              Key size in bits.
+ * \param[in,out] generator The generator object to read from.
+ *
+ * \retval PSA_SUCCESS
+ *         Success.
+ * \retval PSA_ERROR_INSUFFICIENT_CAPACITY
+ *                          There were fewer than \p output_length bytes
+ *                          in the generator. Note that in this case, no
+ *                          output is written to the output buffer.
+ *                          The generator's capacity is set to 0, thus
+ *                          subsequent calls to this function will not
+ *                          succeed, even with a smaller output buffer.
+ * \retval PSA_ERROR_NOT_SUPPORTED
+ *         The key type or key size is not supported, either by the
+ *         implementation in general or in this particular slot.
+ * \retval PSA_ERROR_BAD_STATE
+ * \retval PSA_ERROR_INVALID_ARGUMENT
+ *         The key slot is invalid.
+ * \retval PSA_ERROR_OCCUPIED_SLOT
+ *         There is already a key in the specified slot.
+ * \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
+ */
+psa_status_t psa_generator_import_key(psa_key_slot_t key,
+                                      psa_key_type_t type,
+                                      size_t bits,
+                                      psa_crypto_generator_t *generator);
+
+/** Abort a generator.
+ *
+ * Once a generator has been aborted, its capacity is zero.
+ * Aborting a generator frees all associated resources except for the
+ * \c generator structure itself.
+ *
+ * This function may be called at any time as long as the generator
+ * object has been initialized to #PSA_CRYPTO_GENERATOR_INIT, to
+ * psa_crypto_generator_init() or a zero value. In particular, it is valid
+ * to call psa_generator_abort() twice, or to call psa_generator_abort()
+ * on a generator that has not been set up.
+ *
+ * Once aborted, the generator object may be called.
+ *
+ * \param[in,out] generator    The generator to abort.
+ *
+ * \retval PSA_SUCCESS
+ * \retval PSA_ERROR_BAD_STATE
+ * \retval PSA_ERROR_COMMUNICATION_FAILURE
+ * \retval PSA_ERROR_HARDWARE_FAILURE
+ * \retval PSA_ERROR_TAMPERING_DETECTED
+ */
+psa_status_t psa_generator_abort(psa_crypto_generator_t *generator);
+
+/**@}*/
+
+/** \defgroup derivation Key derivation
+ * @{
+ */
+
+/** Set up a key derivation operation.
+ *
+ * A key derivation algorithm takes three inputs: a secret input \p key and
+ * two non-secret inputs \p label and p salt.
+ * The result of this function is a byte generator which can
+ * be used to produce keys and other cryptographic material.
+ *
+ * The role of \p label and \p salt is as follows:
+ * - For HKDF (#PSA_ALG_HKDF), \p salt is the salt used in the "extract" step
+ *   and \p label is the info string used in the "expand" step.
+ *
+ * \param[in,out] generator       The generator object to set up. It must
+ *                                have been initialized to .
+ * \param key                     Slot containing the secret key to use.
+ * \param alg                     The key derivation algorithm to compute
+ *                                (\c PSA_ALG_XXX value such that
+ *                                #PSA_ALG_IS_KEY_DERIVATION(\p alg) is true).
+ * \param[in] salt                Salt to use.
+ * \param salt_length             Size of the \p salt buffer in bytes.
+ * \param[in] label               Label to use.
+ * \param label_length            Size of the \p label buffer in bytes.
+ * \param capacity                The maximum number of bytes that the
+ *                                generator will be able to provide.
+ *
+ * \retval #PSA_SUCCESS
+ *         Success.
+ * \retval #PSA_ERROR_EMPTY_SLOT
+ * \retval #PSA_ERROR_NOT_PERMITTED
+ * \retval #PSA_ERROR_INVALID_ARGUMENT
+ *         \c key is not compatible with \c alg,
+ *         or \p capacity is too large for the specified algorithm and key.
+ * \retval #PSA_ERROR_NOT_SUPPORTED
+ *         \c alg is not supported or is not a key derivation algorithm.
+ * \retval #PSA_ERROR_INSUFFICIENT_MEMORY
+ * \retval #PSA_ERROR_COMMUNICATION_FAILURE
+ * \retval #PSA_ERROR_HARDWARE_FAILURE
+ * \retval #PSA_ERROR_TAMPERING_DETECTED
+ */
+psa_status_t psa_key_derivation(psa_crypto_generator_t *generator,
+                                psa_key_type_t key,
+                                psa_algorithm_t alg,
+                                const uint8_t *salt,
+                                size_t salt_length,
+                                const uint8_t *label,
+                                size_t label_length,
+                                size_t capacity);
+
+/**@}*/
+
 /** \defgroup generation Key generation
  * @{
  */
diff --git a/include/psa/crypto_struct.h b/include/psa/crypto_struct.h
index 85c9974..baf5b14 100644
--- a/include/psa/crypto_struct.h
+++ b/include/psa/crypto_struct.h
@@ -130,6 +130,44 @@
     } ctx;
 };
 
+typedef struct
+{
+    uint8_t *info;
+    size_t info_length;
+    psa_hmac_internal_data hmac;
+    uint8_t prk[PSA_HASH_MAX_SIZE];
+    uint8_t output_block[PSA_HASH_MAX_SIZE];
+#if PSA_HASH_MAX_SIZE > 0xff
+#error "PSA_HASH_MAX_SIZE does not fit in uint8_t"
+#endif
+    uint8_t offset_in_block;
+    uint8_t block_number;
+} psa_hkdf_generator_t;
+
+struct psa_crypto_generator_s
+{
+    psa_algorithm_t alg;
+    size_t capacity;
+    union
+    {
+        struct
+        {
+            uint8_t *data;
+            size_t size;
+        } buffer;
+#if defined(MBEDTLS_MD_C)
+        psa_hkdf_generator_t hkdf;
+#endif
+    } ctx;
+};
+
+#define PSA_CRYPTO_GENERATOR_INIT {0, 0, {{0, 0}}}
+static inline struct psa_crypto_generator_s psa_crypto_generator_init( void )
+{
+    const struct psa_crypto_generator_s v = PSA_CRYPTO_GENERATOR_INIT;
+    return( v );
+}
+
 struct psa_key_policy_s
 {
     psa_key_usage_t usage;
diff --git a/library/psa_crypto.c b/library/psa_crypto.c
index eb140ea..a62fac7 100644
--- a/library/psa_crypto.c
+++ b/library/psa_crypto.c
@@ -498,8 +498,9 @@
             break;
 #if defined(MBEDTLS_MD_C)
         case PSA_KEY_TYPE_HMAC:
-            break;
 #endif
+        case PSA_KEY_TYPE_DERIVE:
+            break;
 #if defined(MBEDTLS_AES_C)
         case PSA_KEY_TYPE_AES:
             if( bits != 128 && bits != 192 && bits != 256 )
@@ -541,6 +542,43 @@
     return( PSA_SUCCESS );
 }
 
+#if defined(MBEDTLS_RSA_C) && defined(MBEDTLS_PK_PARSE_C)
+static psa_status_t psa_import_rsa_key( mbedtls_pk_context *pk,
+                                        mbedtls_rsa_context **p_rsa )
+{
+    if( mbedtls_pk_get_type( pk ) != MBEDTLS_PK_RSA )
+        return( PSA_ERROR_INVALID_ARGUMENT );
+    else
+    {
+        mbedtls_rsa_context *rsa = mbedtls_pk_rsa( *pk );
+        size_t bits = mbedtls_rsa_get_bitlen( rsa );
+        if( bits > PSA_VENDOR_RSA_MAX_KEY_BITS )
+            return( PSA_ERROR_NOT_SUPPORTED );
+        *p_rsa = rsa;
+        return( PSA_SUCCESS );
+    }
+}
+#endif /* defined(MBEDTLS_RSA_C) && defined(MBEDTLS_PK_PARSE_C) */
+
+#if defined(MBEDTLS_ECP_C) && defined(MBEDTLS_PK_PARSE_C)
+static psa_status_t psa_import_ecp_key( psa_ecc_curve_t expected_curve,
+                                        mbedtls_pk_context *pk,
+                                        mbedtls_ecp_keypair **p_ecp )
+{
+    if( mbedtls_pk_get_type( pk ) != MBEDTLS_PK_ECKEY )
+        return( PSA_ERROR_INVALID_ARGUMENT );
+    else
+    {
+        mbedtls_ecp_keypair *ecp = mbedtls_pk_ec( *pk );
+        psa_ecc_curve_t actual_curve = mbedtls_ecc_group_to_psa( ecp->grp.id );
+        if( actual_curve != expected_curve )
+            return( PSA_ERROR_INVALID_ARGUMENT );
+        *p_ecp = ecp;
+        return( PSA_SUCCESS );
+    }
+}
+#endif /* defined(MBEDTLS_ECP_C) && defined(MBEDTLS_PK_PARSE_C) */
+
 psa_status_t psa_import_key( psa_key_slot_t key,
                              psa_key_type_t type,
                              const uint8_t *data,
@@ -567,63 +605,38 @@
     }
     else
 #if defined(MBEDTLS_PK_PARSE_C)
-    if( type == PSA_KEY_TYPE_RSA_PUBLIC_KEY ||
-        type == PSA_KEY_TYPE_RSA_KEYPAIR ||
-        PSA_KEY_TYPE_IS_ECC( type ) )
+    if( PSA_KEY_TYPE_IS_RSA( type ) || PSA_KEY_TYPE_IS_ECC( type ) )
     {
         int ret;
         mbedtls_pk_context pk;
         mbedtls_pk_init( &pk );
+
+        /* Parse the data. */
         if( PSA_KEY_TYPE_IS_KEYPAIR( type ) )
             ret = mbedtls_pk_parse_key( &pk, data, data_length, NULL, 0 );
         else
             ret = mbedtls_pk_parse_public_key( &pk, data, data_length );
         if( ret != 0 )
             return( mbedtls_to_psa_error( ret ) );
-        switch( mbedtls_pk_get_type( &pk ) )
-        {
+
+        /* We have something that the pkparse module recognizes.
+         * If it has the expected type and passes any type-specific
+         * checks, store it. */
 #if defined(MBEDTLS_RSA_C)
-            case MBEDTLS_PK_RSA:
-                if( type == PSA_KEY_TYPE_RSA_PUBLIC_KEY ||
-                    type == PSA_KEY_TYPE_RSA_KEYPAIR )
-                {
-                    mbedtls_rsa_context *rsa = mbedtls_pk_rsa( pk );
-                    size_t bits = mbedtls_rsa_get_bitlen( rsa );
-                    if( bits > PSA_VENDOR_RSA_MAX_KEY_BITS )
-                    {
-                        status = PSA_ERROR_NOT_SUPPORTED;
-                        break;
-                    }
-                    slot->data.rsa = rsa;
-                }
-                else
-                    status = PSA_ERROR_INVALID_ARGUMENT;
-                break;
+        if( PSA_KEY_TYPE_IS_RSA( type ) )
+            status = psa_import_rsa_key( &pk, &slot->data.rsa );
+        else
 #endif /* MBEDTLS_RSA_C */
 #if defined(MBEDTLS_ECP_C)
-            case MBEDTLS_PK_ECKEY:
-                if( PSA_KEY_TYPE_IS_ECC( type ) )
-                {
-                    mbedtls_ecp_keypair *ecp = mbedtls_pk_ec( pk );
-                    psa_ecc_curve_t actual_curve =
-                        mbedtls_ecc_group_to_psa( ecp->grp.id );
-                    psa_ecc_curve_t expected_curve =
-                        PSA_KEY_TYPE_GET_CURVE( type );
-                    if( actual_curve != expected_curve )
-                    {
-                        status = PSA_ERROR_INVALID_ARGUMENT;
-                        break;
-                    }
-                    slot->data.ecp = ecp;
-                }
-                else
-                    status = PSA_ERROR_INVALID_ARGUMENT;
-                break;
+        if( PSA_KEY_TYPE_IS_ECC( type ) )
+            status = psa_import_ecp_key( PSA_KEY_TYPE_GET_CURVE( type ),
+                                         &pk, &slot->data.ecp );
+        else
 #endif /* MBEDTLS_ECP_C */
-            default:
-                status = PSA_ERROR_INVALID_ARGUMENT;
-                break;
+        {
+            status = PSA_ERROR_NOT_SUPPORTED;
         }
+
         /* Free the content of the pk object only on error. On success,
          * the content of the object has been stored in the slot. */
         if( status != PSA_SUCCESS )
@@ -662,8 +675,7 @@
     }
     else
 #if defined(MBEDTLS_RSA_C)
-    if( slot->type == PSA_KEY_TYPE_RSA_PUBLIC_KEY ||
-        slot->type == PSA_KEY_TYPE_RSA_KEYPAIR )
+    if( PSA_KEY_TYPE_IS_RSA( slot->type ) )
     {
         mbedtls_rsa_free( slot->data.rsa );
         mbedtls_free( slot->data.rsa );
@@ -694,8 +706,7 @@
     if( key_type_is_raw_bytes( slot->type ) )
         return( slot->data.raw.bytes * 8 );
 #if defined(MBEDTLS_RSA_C)
-    if( slot->type == PSA_KEY_TYPE_RSA_PUBLIC_KEY ||
-        slot->type == PSA_KEY_TYPE_RSA_KEYPAIR )
+    if( PSA_KEY_TYPE_IS_RSA( slot->type ) )
         return( mbedtls_rsa_get_bitlen( slot->data.rsa ) );
 #endif /* defined(MBEDTLS_RSA_C) */
 #if defined(MBEDTLS_ECP_C)
@@ -769,15 +780,13 @@
     else
     {
 #if defined(MBEDTLS_PK_WRITE_C)
-        if( slot->type == PSA_KEY_TYPE_RSA_PUBLIC_KEY ||
-            slot->type == PSA_KEY_TYPE_RSA_KEYPAIR ||
+        if( PSA_KEY_TYPE_IS_RSA( slot->type ) ||
             PSA_KEY_TYPE_IS_ECC( slot->type ) )
         {
             mbedtls_pk_context pk;
             int ret;
             mbedtls_pk_init( &pk );
-            if( slot->type == PSA_KEY_TYPE_RSA_PUBLIC_KEY ||
-                slot->type == PSA_KEY_TYPE_RSA_KEYPAIR )
+            if( PSA_KEY_TYPE_IS_RSA( slot->type ) )
             {
                 pk.pk_info = &mbedtls_rsa_info;
                 pk.pk_ctx = slot->data.rsa;
@@ -1018,6 +1027,12 @@
                               size_t input_length )
 {
     int ret;
+
+    /* Don't require hash implementations to behave correctly on a
+     * zero-length input, which may have an invalid pointer. */
+    if( input_length == 0 )
+        return( PSA_SUCCESS );
+
     switch( operation->alg )
     {
 #if defined(MBEDTLS_MD2_C)
@@ -1068,6 +1083,7 @@
             ret = MBEDTLS_ERR_MD_BAD_INPUT_DATA;
             break;
     }
+
     if( ret != 0 )
         psa_hash_abort( operation );
     return( mbedtls_to_psa_error( ret ) );
@@ -1310,8 +1326,9 @@
 #if defined(MBEDTLS_MD_C)
     if( PSA_ALG_IS_HMAC( operation->alg ) )
     {
-        status = psa_hash_setup( &operation->ctx.hmac.hash_ctx,
-                                 PSA_ALG_HMAC_HASH( alg ) );
+        /* We'll set up the hash operation later in psa_hmac_setup_internal. */
+        operation->ctx.hmac.hash_ctx.alg = 0;
+        status = PSA_SUCCESS;
     }
     else
 #endif /* MBEDTLS_MD_C */
@@ -1325,6 +1342,14 @@
     return( status );
 }
 
+#if defined(MBEDTLS_MD_C)
+static psa_status_t psa_hmac_abort_internal( psa_hmac_internal_data *hmac )
+{
+    mbedtls_zeroize( hmac->opad, sizeof( hmac->opad ) );
+    return( psa_hash_abort( &hmac->hash_ctx ) );
+}
+#endif /* MBEDTLS_MD_C */
+
 psa_status_t psa_mac_abort( psa_mac_operation_t *operation )
 {
     if( operation->alg == 0 )
@@ -1345,12 +1370,7 @@
 #if defined(MBEDTLS_MD_C)
     if( PSA_ALG_IS_HMAC( operation->alg ) )
     {
-        size_t block_size =
-            psa_get_hash_block_size( PSA_ALG_HMAC_HASH( operation->alg ) );
-        if( block_size == 0 )
-            goto bad_state;
-        psa_hash_abort( &operation->ctx.hmac.hash_ctx );
-        mbedtls_zeroize( operation->ctx.hmac.opad, block_size );
+        psa_hmac_abort_internal( &operation->ctx.hmac );
     }
     else
 #endif /* MBEDTLS_MD_C */
@@ -1400,43 +1420,49 @@
 #endif /* MBEDTLS_CMAC_C */
 
 #if defined(MBEDTLS_MD_C)
-static int psa_hmac_setup( psa_mac_operation_t *operation,
-                           psa_key_type_t key_type,
-                           key_slot_t *slot,
-                           psa_algorithm_t alg )
+static psa_status_t psa_hmac_setup_internal( psa_hmac_internal_data *hmac,
+                                             const uint8_t *key,
+                                             size_t key_length,
+                                             psa_algorithm_t hash_alg )
 {
     unsigned char ipad[PSA_HMAC_MAX_HASH_BLOCK_SIZE];
-    unsigned char *opad = operation->ctx.hmac.opad;
     size_t i;
-    size_t block_size =
-        psa_get_hash_block_size( PSA_ALG_HMAC_HASH( alg ) );
-    unsigned int digest_size =
-        PSA_HASH_SIZE( PSA_ALG_HMAC_HASH( alg ) );
-    size_t key_length = slot->data.raw.bytes;
+    size_t hash_size = PSA_HASH_SIZE( hash_alg );
+    size_t block_size = psa_get_hash_block_size( hash_alg );
     psa_status_t status;
 
-    if( block_size == 0 || digest_size == 0 )
+    /* Sanity checks on block_size, to guarantee that there won't be a buffer
+     * overflow below. This should never trigger if the hash algorithm
+     * is implemented correctly. */
+    /* The size checks against the ipad and opad buffers cannot be written
+     * `block_size > sizeof( ipad ) || block_size > sizeof( hmac->opad )`
+     * because that triggers -Wlogical-op on GCC 7.3. */
+    if( block_size > sizeof( ipad ) )
+        return( PSA_ERROR_NOT_SUPPORTED );
+    if( block_size > sizeof( hmac->opad ) )
+        return( PSA_ERROR_NOT_SUPPORTED );
+    if( block_size < hash_size )
         return( PSA_ERROR_NOT_SUPPORTED );
 
-    if( key_type != PSA_KEY_TYPE_HMAC )
-        return( PSA_ERROR_INVALID_ARGUMENT );
-
-    operation->mac_size = digest_size;
-
-    /* The hash was started earlier in psa_mac_init. */
     if( key_length > block_size )
     {
-        status = psa_hash_update( &operation->ctx.hmac.hash_ctx,
-                                  slot->data.raw.data, slot->data.raw.bytes );
+        status = psa_hash_setup( &hmac->hash_ctx, hash_alg );
         if( status != PSA_SUCCESS )
-            return( status );
-        status = psa_hash_finish( &operation->ctx.hmac.hash_ctx,
+            goto cleanup;
+        status = psa_hash_update( &hmac->hash_ctx, key, key_length );
+        if( status != PSA_SUCCESS )
+            goto cleanup;
+        status = psa_hash_finish( &hmac->hash_ctx,
                                   ipad, sizeof( ipad ), &key_length );
         if( status != PSA_SUCCESS )
-            return( status );
+            goto cleanup;
     }
-    else
-        memcpy( ipad, slot->data.raw.data, slot->data.raw.bytes );
+    /* A 0-length key is not commonly used in HMAC when used as a MAC,
+     * but it is permitted. It is common when HMAC is used in HKDF, for
+     * example. Don't call `memcpy` in the 0-length because `key` could be
+     * an invalid pointer which would make the behavior undefined. */
+    else if( key_length != 0 )
+        memcpy( ipad, key, key_length );
 
     /* ipad contains the key followed by garbage. Xor and fill with 0x36
      * to create the ipad value. */
@@ -1447,22 +1473,17 @@
     /* Copy the key material from ipad to opad, flipping the requisite bits,
      * and filling the rest of opad with the requisite constant. */
     for( i = 0; i < key_length; i++ )
-        opad[i] = ipad[i] ^ 0x36 ^ 0x5C;
-    memset( opad + key_length, 0x5C, block_size - key_length );
+        hmac->opad[i] = ipad[i] ^ 0x36 ^ 0x5C;
+    memset( hmac->opad + key_length, 0x5C, block_size - key_length );
 
-    status = psa_hash_setup( &operation->ctx.hmac.hash_ctx,
-                             PSA_ALG_HMAC_HASH( alg ) );
+    status = psa_hash_setup( &hmac->hash_ctx, hash_alg );
     if( status != PSA_SUCCESS )
         goto cleanup;
 
-    status = psa_hash_update( &operation->ctx.hmac.hash_ctx, ipad,
-                              block_size );
+    status = psa_hash_update( &hmac->hash_ctx, ipad, block_size );
 
 cleanup:
     mbedtls_zeroize( ipad, key_length );
-    /* opad is in the context. It needs to stay in memory if this function
-     * succeeds, and it will be wiped by psa_mac_abort() called from
-     * psa_mac_setup in the error case. */
 
     return( status );
 }
@@ -1510,7 +1531,32 @@
 #if defined(MBEDTLS_MD_C)
     if( PSA_ALG_IS_HMAC( alg ) )
     {
-        status = psa_hmac_setup( operation, slot->type, slot, alg );
+        psa_algorithm_t hash_alg = PSA_ALG_HMAC_HASH( alg );
+        if( hash_alg == 0 )
+        {
+            status = PSA_ERROR_NOT_SUPPORTED;
+            goto exit;
+        }
+
+        operation->mac_size = PSA_HASH_SIZE( hash_alg );
+        /* Sanity check. This shouldn't fail on a valid configuration. */
+        if( operation->mac_size == 0 ||
+            operation->mac_size > sizeof( operation->ctx.hmac.opad ) )
+        {
+            status = PSA_ERROR_NOT_SUPPORTED;
+            goto exit;
+        }
+
+        if( slot->type != PSA_KEY_TYPE_HMAC )
+        {
+            status = PSA_ERROR_INVALID_ARGUMENT;
+            goto exit;
+        }
+
+        status = psa_hmac_setup_internal( &operation->ctx.hmac,
+                                          slot->data.raw.data,
+                                          slot->data.raw.bytes,
+                                          hash_alg );
     }
     else
 #endif /* MBEDTLS_MD_C */
@@ -1584,12 +1630,46 @@
     return( status );
 }
 
+#if defined(MBEDTLS_MD_C)
+static psa_status_t psa_hmac_finish_internal( psa_hmac_internal_data *hmac,
+                                              uint8_t *mac,
+                                              size_t mac_size )
+{
+    unsigned char tmp[MBEDTLS_MD_MAX_SIZE];
+    psa_algorithm_t hash_alg = hmac->hash_ctx.alg;
+    size_t hash_size = 0;
+    size_t block_size = psa_get_hash_block_size( hash_alg );
+    psa_status_t status;
+
+    status = psa_hash_finish( &hmac->hash_ctx, tmp, sizeof( tmp ), &hash_size );
+    if( status != PSA_SUCCESS )
+        return( status );
+    /* From here on, tmp needs to be wiped. */
+
+    status = psa_hash_setup( &hmac->hash_ctx, hash_alg );
+    if( status != PSA_SUCCESS )
+        goto exit;
+
+    status = psa_hash_update( &hmac->hash_ctx, hmac->opad, block_size );
+    if( status != PSA_SUCCESS )
+        goto exit;
+
+    status = psa_hash_update( &hmac->hash_ctx, tmp, hash_size );
+    if( status != PSA_SUCCESS )
+        goto exit;
+
+    status = psa_hash_finish( &hmac->hash_ctx, mac, mac_size, &hash_size );
+
+exit:
+    mbedtls_zeroize( tmp, hash_size );
+    return( status );
+}
+#endif /* MBEDTLS_MD_C */
+
 static psa_status_t psa_mac_finish_internal( psa_mac_operation_t *operation,
                                              uint8_t *mac,
                                              size_t mac_size )
 {
-    psa_status_t status;
-
     if( ! operation->key_set )
         return( PSA_ERROR_BAD_STATE );
     if( operation->iv_required && ! operation->iv_set )
@@ -1609,41 +1689,8 @@
 #if defined(MBEDTLS_MD_C)
     if( PSA_ALG_IS_HMAC( operation->alg ) )
     {
-        unsigned char tmp[MBEDTLS_MD_MAX_SIZE];
-        unsigned char *opad = operation->ctx.hmac.opad;
-        size_t hash_size = 0;
-        size_t block_size =
-            psa_get_hash_block_size( PSA_ALG_HMAC_HASH( operation->alg ) );
-
-        if( block_size == 0 )
-            return( PSA_ERROR_NOT_SUPPORTED );
-
-        status = psa_hash_finish( &operation->ctx.hmac.hash_ctx, tmp,
-                                  sizeof( tmp ), &hash_size );
-        if( status != PSA_SUCCESS )
-            return( status );
-        /* From here on, tmp needs to be wiped. */
-
-        status = psa_hash_setup( &operation->ctx.hmac.hash_ctx,
-                                 PSA_ALG_HMAC_HASH( operation->alg ) );
-        if( status != PSA_SUCCESS )
-            goto hmac_cleanup;
-
-        status = psa_hash_update( &operation->ctx.hmac.hash_ctx, opad,
-                                  block_size );
-        if( status != PSA_SUCCESS )
-            goto hmac_cleanup;
-
-        status = psa_hash_update( &operation->ctx.hmac.hash_ctx, tmp,
-                                  hash_size );
-        if( status != PSA_SUCCESS )
-            goto hmac_cleanup;
-
-        status = psa_hash_finish( &operation->ctx.hmac.hash_ctx, mac,
-                                  mac_size, &hash_size );
-    hmac_cleanup:
-        mbedtls_zeroize( tmp, hash_size );
-        return( status );
+        return( psa_hmac_finish_internal( &operation->ctx.hmac,
+                                          mac, mac_size ) );
     }
     else
 #endif /* MBEDTLS_MD_C */
@@ -1733,28 +1780,45 @@
 
 #if defined(MBEDTLS_RSA_C)
 /* Decode the hash algorithm from alg and store the mbedtls encoding in
- * md_alg. Verify that the hash length is consistent. */
+ * md_alg. Verify that the hash length is acceptable. */
 static psa_status_t psa_rsa_decode_md_type( psa_algorithm_t alg,
                                             size_t hash_length,
                                             mbedtls_md_type_t *md_alg )
 {
     psa_algorithm_t hash_alg = PSA_ALG_SIGN_GET_HASH( alg );
     const mbedtls_md_info_t *md_info = mbedtls_md_info_from_psa( hash_alg );
-    *md_alg = hash_alg == 0 ? MBEDTLS_MD_NONE : mbedtls_md_get_type( md_info );
-    if( *md_alg == MBEDTLS_MD_NONE )
-    {
+    *md_alg = mbedtls_md_get_type( md_info );
+
+    /* The Mbed TLS RSA module uses an unsigned int for hash length
+     * parameters. Validate that it fits so that we don't risk an
+     * overflow later. */
 #if SIZE_MAX > UINT_MAX
-        if( hash_length > UINT_MAX )
-            return( PSA_ERROR_INVALID_ARGUMENT );
+    if( hash_length > UINT_MAX )
+        return( PSA_ERROR_INVALID_ARGUMENT );
 #endif
-    }
-    else
+
+#if defined(MBEDTLS_PKCS1_V15)
+    /* For PKCS#1 v1.5 signature, if using a hash, the hash length
+     * must be correct. */
+    if( PSA_ALG_IS_RSA_PKCS1V15_SIGN( alg ) &&
+        alg != PSA_ALG_RSA_PKCS1V15_SIGN_RAW )
     {
+        if( md_info == NULL )
+            return( PSA_ERROR_NOT_SUPPORTED );
         if( mbedtls_md_get_size( md_info ) != hash_length )
             return( PSA_ERROR_INVALID_ARGUMENT );
+    }
+#endif /* MBEDTLS_PKCS1_V15 */
+
+#if defined(MBEDTLS_PKCS1_V21)
+    /* PSS requires a hash internally. */
+    if( PSA_ALG_IS_RSA_PSS( alg ) )
+    {
         if( md_info == NULL )
             return( PSA_ERROR_NOT_SUPPORTED );
     }
+#endif /* MBEDTLS_PKCS1_V21 */
+
     return( PSA_SUCCESS );
 }
 
@@ -1774,18 +1838,9 @@
     if( status != PSA_SUCCESS )
         return( status );
 
-    if( signature_size < rsa->len )
+    if( signature_size < mbedtls_rsa_get_len( rsa ) )
         return( PSA_ERROR_BUFFER_TOO_SMALL );
 
-    /* The Mbed TLS RSA module uses an unsigned int for hash_length. See if
-     * hash_length will fit and return an error if it doesn't. */
-#if defined(MBEDTLS_PKCS1_V15) || defined(MBEDTLS_PKCS1_V21)
-#if SIZE_MAX > UINT_MAX
-    if( hash_length > UINT_MAX )
-        return( PSA_ERROR_NOT_SUPPORTED );
-#endif
-#endif
-
 #if defined(MBEDTLS_PKCS1_V15)
     if( PSA_ALG_IS_RSA_PKCS1V15_SIGN( alg ) )
     {
@@ -1810,7 +1865,7 @@
                                            mbedtls_ctr_drbg_random,
                                            &global_data.ctr_drbg,
                                            MBEDTLS_RSA_PRIVATE,
-                                           md_alg,
+                                           MBEDTLS_MD_NONE,
                                            (unsigned int) hash_length,
                                            hash,
                                            signature );
@@ -1822,7 +1877,7 @@
     }
 
     if( ret == 0 )
-        *signature_length = rsa->len;
+        *signature_length = mbedtls_rsa_get_len( rsa );
     return( mbedtls_to_psa_error( ret ) );
 }
 
@@ -1841,18 +1896,9 @@
     if( status != PSA_SUCCESS )
         return( status );
 
-    if( signature_length < rsa->len )
+    if( signature_length < mbedtls_rsa_get_len( rsa ) )
         return( PSA_ERROR_BUFFER_TOO_SMALL );
 
-#if defined(MBEDTLS_PKCS1_V15) || defined(MBEDTLS_PKCS1_V21)
-#if SIZE_MAX > UINT_MAX
-    /* The Mbed TLS RSA module uses an unsigned int for hash_length. See if
-     * hash_length will fit and return an error if it doesn't. */
-    if( hash_length > UINT_MAX )
-        return( PSA_ERROR_NOT_SUPPORTED );
-#endif
-#endif
-
 #if defined(MBEDTLS_PKCS1_V15)
     if( PSA_ALG_IS_RSA_PKCS1V15_SIGN( alg ) )
     {
@@ -1877,7 +1923,7 @@
                                              mbedtls_ctr_drbg_random,
                                              &global_data.ctr_drbg,
                                              MBEDTLS_RSA_PUBLIC,
-                                             md_alg,
+                                             MBEDTLS_MD_NONE,
                                              (unsigned int) hash_length,
                                              hash,
                                              signature );
@@ -1983,8 +2029,6 @@
                                   psa_algorithm_t alg,
                                   const uint8_t *hash,
                                   size_t hash_length,
-                                  const uint8_t *salt,
-                                  size_t salt_length,
                                   uint8_t *signature,
                                   size_t signature_size,
                                   size_t *signature_length )
@@ -1994,9 +2038,6 @@
 
     *signature_length = signature_size;
 
-    (void) salt;
-    (void) salt_length;
-
     status = psa_get_key_from_slot( key, &slot, PSA_KEY_USAGE_SIGN, alg );
     if( status != PSA_SUCCESS )
         goto exit;
@@ -2058,24 +2099,18 @@
                                     psa_algorithm_t alg,
                                     const uint8_t *hash,
                                     size_t hash_length,
-                                    const uint8_t *salt,
-                                    size_t salt_length,
                                     const uint8_t *signature,
                                     size_t signature_length )
 {
     key_slot_t *slot;
     psa_status_t status;
 
-    (void) salt;
-    (void) salt_length;
-
     status = psa_get_key_from_slot( key, &slot, PSA_KEY_USAGE_VERIFY, alg );
     if( status != PSA_SUCCESS )
         return( status );
 
 #if defined(MBEDTLS_RSA_C)
-    if( slot->type == PSA_KEY_TYPE_RSA_KEYPAIR ||
-        slot->type == PSA_KEY_TYPE_RSA_PUBLIC_KEY )
+    if( PSA_KEY_TYPE_IS_RSA( slot->type ) )
     {
         return( psa_rsa_verify( slot->data.rsa,
                                 alg,
@@ -2105,6 +2140,17 @@
     }
 }
 
+#if defined(MBEDTLS_RSA_C) && defined(MBEDTLS_PKCS1_V21)
+static void psa_rsa_oaep_set_padding_mode( psa_algorithm_t alg,
+                                           mbedtls_rsa_context *rsa )
+{
+    psa_algorithm_t hash_alg = PSA_ALG_RSA_OAEP_GET_HASH( alg );
+    const mbedtls_md_info_t *md_info = mbedtls_md_info_from_psa( hash_alg );
+    mbedtls_md_type_t md_alg = mbedtls_md_get_type( md_info );
+    mbedtls_rsa_set_padding( rsa, MBEDTLS_RSA_PKCS_V21, md_alg );
+}
+#endif /* defined(MBEDTLS_RSA_C) && defined(MBEDTLS_PKCS1_V21) */
+
 psa_status_t psa_asymmetric_encrypt( psa_key_slot_t key,
                                      psa_algorithm_t alg,
                                      const uint8_t *input,
@@ -2118,23 +2164,24 @@
     key_slot_t *slot;
     psa_status_t status;
 
-    (void) salt;
-    (void) salt_length;
     *output_length = 0;
 
+    if( ! PSA_ALG_IS_RSA_OAEP( alg ) && salt_length != 0 )
+        return( PSA_ERROR_INVALID_ARGUMENT );
+
     status = psa_get_key_from_slot( key, &slot, PSA_KEY_USAGE_ENCRYPT, alg );
     if( status != PSA_SUCCESS )
         return( status );
-    if( ! PSA_KEY_TYPE_IS_KEYPAIR( slot->type ) )
+    if( ! ( PSA_KEY_TYPE_IS_PUBLIC_KEY( slot->type ) ||
+            PSA_KEY_TYPE_IS_KEYPAIR( slot->type ) ) )
         return( PSA_ERROR_INVALID_ARGUMENT );
 
 #if defined(MBEDTLS_RSA_C)
-    if( slot->type == PSA_KEY_TYPE_RSA_KEYPAIR ||
-        slot->type == PSA_KEY_TYPE_RSA_PUBLIC_KEY )
+    if( PSA_KEY_TYPE_IS_RSA( slot->type ) )
     {
         mbedtls_rsa_context *rsa = slot->data.rsa;
         int ret;
-        if( output_size < rsa->len )
+        if( output_size < mbedtls_rsa_get_len( rsa ) )
             return( PSA_ERROR_INVALID_ARGUMENT );
 #if defined(MBEDTLS_PKCS1_V15)
         if( alg == PSA_ALG_RSA_PKCS1V15_CRYPT )
@@ -2152,7 +2199,15 @@
 #if defined(MBEDTLS_PKCS1_V21)
         if( PSA_ALG_IS_RSA_OAEP( alg ) )
         {
-            return( PSA_ERROR_NOT_SUPPORTED );
+            psa_rsa_oaep_set_padding_mode( alg, rsa );
+            ret = mbedtls_rsa_rsaes_oaep_encrypt( rsa,
+                                                  mbedtls_ctr_drbg_random,
+                                                  &global_data.ctr_drbg,
+                                                  MBEDTLS_RSA_PUBLIC,
+                                                  salt, salt_length,
+                                                  input_length,
+                                                  input,
+                                                  output );
         }
         else
 #endif /* MBEDTLS_PKCS1_V21 */
@@ -2160,7 +2215,7 @@
             return( PSA_ERROR_INVALID_ARGUMENT );
         }
         if( ret == 0 )
-            *output_length = rsa->len;
+            *output_length = mbedtls_rsa_get_len( rsa );
         return( mbedtls_to_psa_error( ret ) );
     }
     else
@@ -2183,10 +2238,11 @@
     key_slot_t *slot;
     psa_status_t status;
 
-    (void) salt;
-    (void) salt_length;
     *output_length = 0;
 
+    if( ! PSA_ALG_IS_RSA_OAEP( alg ) && salt_length != 0 )
+        return( PSA_ERROR_INVALID_ARGUMENT );
+
     status = psa_get_key_from_slot( key, &slot, PSA_KEY_USAGE_DECRYPT, alg );
     if( status != PSA_SUCCESS )
         return( status );
@@ -2199,7 +2255,7 @@
         mbedtls_rsa_context *rsa = slot->data.rsa;
         int ret;
 
-        if( input_length != rsa->len )
+        if( input_length != mbedtls_rsa_get_len( rsa ) )
             return( PSA_ERROR_INVALID_ARGUMENT );
 
 #if defined(MBEDTLS_PKCS1_V15)
@@ -2219,7 +2275,16 @@
 #if defined(MBEDTLS_PKCS1_V21)
         if( PSA_ALG_IS_RSA_OAEP( alg ) )
         {
-            return( PSA_ERROR_NOT_SUPPORTED );
+            psa_rsa_oaep_set_padding_mode( alg, rsa );
+            ret = mbedtls_rsa_rsaes_oaep_decrypt( rsa,
+                                                  mbedtls_ctr_drbg_random,
+                                                  &global_data.ctr_drbg,
+                                                  MBEDTLS_RSA_PRIVATE,
+                                                  salt, salt_length,
+                                                  output_length,
+                                                  input,
+                                                  output,
+                                                  output_size );
         }
         else
 #endif /* MBEDTLS_PKCS1_V21 */
@@ -2613,7 +2678,8 @@
                              PSA_KEY_USAGE_ENCRYPT |
                              PSA_KEY_USAGE_DECRYPT |
                              PSA_KEY_USAGE_SIGN |
-                             PSA_KEY_USAGE_VERIFY ) ) != 0 )
+                             PSA_KEY_USAGE_VERIFY |
+                             PSA_KEY_USAGE_DERIVE ) ) != 0 )
         return( PSA_ERROR_INVALID_ARGUMENT );
 
     slot->policy = *policy;
@@ -2950,7 +3016,304 @@
 
 
 /****************************************************************/
-/* Key generation */
+/* Generators */
+/****************************************************************/
+
+psa_status_t psa_generator_abort( psa_crypto_generator_t *generator )
+{
+    psa_status_t status = PSA_SUCCESS;
+    if( generator->alg == 0 )
+    {
+        /* The object has (apparently) been initialized but it is not
+         * in use. It's ok to call abort on such an object, and there's
+         * nothing to do. */
+    }
+    else
+#if defined(MBEDTLS_MD_C)
+    if( PSA_ALG_IS_HKDF( generator->alg ) )
+    {
+        mbedtls_free( generator->ctx.hkdf.info );
+        status = psa_hmac_abort_internal( &generator->ctx.hkdf.hmac );
+    }
+    else
+#endif /* MBEDTLS_MD_C */
+    {
+        status = PSA_ERROR_BAD_STATE;
+    }
+    memset( generator, 0, sizeof( *generator ) );
+    return( status );
+}
+
+
+psa_status_t psa_get_generator_capacity(const psa_crypto_generator_t *generator,
+                                        size_t *capacity)
+{
+    *capacity = generator->capacity;
+    return( PSA_SUCCESS );
+}
+
+#if defined(MBEDTLS_MD_C)
+/* Read some bytes from an HKDF-based generator. This performs a chunk
+ * of the expand phase of the HKDF algorithm. */
+static psa_status_t psa_generator_hkdf_read( psa_hkdf_generator_t *hkdf,
+                                             psa_algorithm_t hash_alg,
+                                             uint8_t *output,
+                                             size_t output_length )
+{
+    uint8_t hash_length = PSA_HASH_SIZE( hash_alg );
+    psa_status_t status;
+
+    while( output_length != 0 )
+    {
+        /* Copy what remains of the current block */
+        uint8_t n = hash_length - hkdf->offset_in_block;
+        if( n > output_length )
+            n = (uint8_t) output_length;
+        memcpy( output, hkdf->output_block + hkdf->offset_in_block, n );
+        output += n;
+        output_length -= n;
+        hkdf->offset_in_block += n;
+        if( output_length == 0 )
+            break;
+        /* We can't be wanting more output after block 0xff, otherwise
+         * the capacity check in psa_generator_read() would have
+         * prevented this call. It could happen only if the generator
+         * object was corrupted or if this function is called directly
+         * inside the library. */
+        if( hkdf->block_number == 0xff )
+            return( PSA_ERROR_BAD_STATE );
+
+        /* We need a new block */
+        ++hkdf->block_number;
+        hkdf->offset_in_block = 0;
+        status = psa_hmac_setup_internal( &hkdf->hmac,
+                                          hkdf->prk, hash_length,
+                                          hash_alg );
+        if( status != PSA_SUCCESS )
+            return( status );
+        if( hkdf->block_number != 1 )
+        {
+            status = psa_hash_update( &hkdf->hmac.hash_ctx,
+                                      hkdf->output_block,
+                                      hash_length );
+            if( status != PSA_SUCCESS )
+                return( status );
+        }
+        status = psa_hash_update( &hkdf->hmac.hash_ctx,
+                                  hkdf->info,
+                                  hkdf->info_length );
+        if( status != PSA_SUCCESS )
+            return( status );
+        status = psa_hash_update( &hkdf->hmac.hash_ctx,
+                                  &hkdf->block_number, 1 );
+        if( status != PSA_SUCCESS )
+            return( status );
+        status = psa_hmac_finish_internal( &hkdf->hmac,
+                                           hkdf->output_block,
+                                           sizeof( hkdf->output_block ) );
+        if( status != PSA_SUCCESS )
+            return( status );
+    }
+
+    return( PSA_SUCCESS );
+}
+#endif /* MBEDTLS_MD_C */
+
+psa_status_t psa_generator_read( psa_crypto_generator_t *generator,
+                                 uint8_t *output,
+                                 size_t output_length )
+{
+    psa_status_t status;
+
+    if( output_length > generator->capacity )
+    {
+        generator->capacity = 0;
+        /* Go through the error path to wipe all confidential data now
+         * that the generator object is useless. */
+        status = PSA_ERROR_INSUFFICIENT_CAPACITY;
+        goto exit;
+    }
+    if( output_length == 0 &&
+        generator->capacity == 0 && generator->alg == 0 )
+    {
+        /* Edge case: this is a blank or finished generator, and 0
+         * bytes were requested. The right error in this case could
+         * be either INSUFFICIENT_CAPACITY or BAD_STATE. Return
+         * INSUFFICIENT_CAPACITY, which is right for a finished
+         * generator, for consistency with the case when
+         * output_length > 0. */
+        return( PSA_ERROR_INSUFFICIENT_CAPACITY );
+    }
+    generator->capacity -= output_length;
+
+#if defined(MBEDTLS_MD_C)
+    if( PSA_ALG_IS_HKDF( generator->alg ) )
+    {
+        psa_algorithm_t hash_alg = PSA_ALG_HKDF_GET_HASH( generator->alg );
+        status = psa_generator_hkdf_read( &generator->ctx.hkdf, hash_alg,
+                                          output, output_length );
+    }
+    else
+#endif /* MBEDTLS_MD_C */
+    {
+        return( PSA_ERROR_BAD_STATE );
+    }
+
+exit:
+    if( status != PSA_SUCCESS )
+    {
+        psa_generator_abort( generator );
+        memset( output, '!', output_length );
+    }
+    return( status );
+}
+
+#if defined(MBEDTLS_DES_C)
+static void psa_des_set_key_parity( uint8_t *data, size_t data_size )
+{
+    if( data_size >= 8 )
+        mbedtls_des_key_set_parity( data );
+    if( data_size >= 16 )
+        mbedtls_des_key_set_parity( data + 8 );
+    if( data_size >= 24 )
+        mbedtls_des_key_set_parity( data + 16 );
+}
+#endif /* MBEDTLS_DES_C */
+
+psa_status_t psa_generator_import_key( psa_key_slot_t key,
+                                       psa_key_type_t type,
+                                       size_t bits,
+                                       psa_crypto_generator_t *generator )
+{
+    uint8_t *data = NULL;
+    size_t bytes = PSA_BITS_TO_BYTES( bits );
+    psa_status_t status;
+
+    if( ! key_type_is_raw_bytes( type ) )
+        return( PSA_ERROR_INVALID_ARGUMENT );
+    if( bits % 8 != 0 )
+        return( PSA_ERROR_INVALID_ARGUMENT );
+    data = mbedtls_calloc( 1, bytes );
+    if( data == NULL )
+        return( PSA_ERROR_INSUFFICIENT_MEMORY );
+
+    status = psa_generator_read( generator, data, bytes );
+    if( status != PSA_SUCCESS )
+        goto exit;
+#if defined(MBEDTLS_DES_C)
+    if( type == PSA_KEY_TYPE_DES )
+        psa_des_set_key_parity( data, bytes );
+#endif /* MBEDTLS_DES_C */
+    status = psa_import_key( key, type, data, bytes );
+
+exit:
+    mbedtls_free( data );
+    return( status );
+}
+
+
+
+/****************************************************************/
+/* Key derivation */
+/****************************************************************/
+
+/* Set up an HKDF-based generator. This is exactly the extract phase
+ * of the HKDF algorithm. */
+static psa_status_t psa_generator_hkdf_setup( psa_hkdf_generator_t *hkdf,
+                                              key_slot_t *slot,
+                                              psa_algorithm_t hash_alg,
+                                              const uint8_t *salt,
+                                              size_t salt_length,
+                                              const uint8_t *label,
+                                              size_t label_length )
+{
+    psa_status_t status;
+    status = psa_hmac_setup_internal( &hkdf->hmac,
+                                      salt, salt_length,
+                                      PSA_ALG_HMAC_HASH( hash_alg ) );
+    if( status != PSA_SUCCESS )
+        return( status );
+    status = psa_hash_update( &hkdf->hmac.hash_ctx,
+                              slot->data.raw.data,
+                              slot->data.raw.bytes );
+    if( status != PSA_SUCCESS )
+        return( status );
+    status = psa_hmac_finish_internal( &hkdf->hmac,
+                                       hkdf->prk,
+                                       sizeof( hkdf->prk ) );
+    if( status != PSA_SUCCESS )
+        return( status );
+    hkdf->offset_in_block = PSA_HASH_SIZE( hash_alg );
+    hkdf->block_number = 0;
+    hkdf->info_length = label_length;
+    if( label_length != 0 )
+    {
+        hkdf->info = mbedtls_calloc( 1, label_length );
+        if( hkdf->info == NULL )
+            return( PSA_ERROR_INSUFFICIENT_MEMORY );
+        memcpy( hkdf->info, label, label_length );
+    }
+    return( PSA_SUCCESS );
+}
+
+psa_status_t psa_key_derivation( psa_crypto_generator_t *generator,
+                                 psa_key_type_t key,
+                                 psa_algorithm_t alg,
+                                 const uint8_t *salt,
+                                 size_t salt_length,
+                                 const uint8_t *label,
+                                 size_t label_length,
+                                 size_t capacity )
+{
+    key_slot_t *slot;
+    psa_status_t status;
+
+    if( generator->alg != 0 )
+        return( PSA_ERROR_BAD_STATE );
+
+    status = psa_get_key_from_slot( key, &slot, PSA_KEY_USAGE_DERIVE, alg );
+    if( status != PSA_SUCCESS )
+        return( status );
+    if( slot->type != PSA_KEY_TYPE_DERIVE )
+        return( PSA_ERROR_INVALID_ARGUMENT );
+
+    if( ! PSA_ALG_IS_KEY_DERIVATION( alg ) )
+        return( PSA_ERROR_INVALID_ARGUMENT );
+
+#if defined(MBEDTLS_MD_C)
+    if( PSA_ALG_IS_HKDF( alg ) )
+    {
+        psa_algorithm_t hash_alg = PSA_ALG_HKDF_GET_HASH( alg );
+        size_t hash_size = PSA_HASH_SIZE( hash_alg );
+        if( hash_size == 0 )
+            return( PSA_ERROR_NOT_SUPPORTED );
+        if( capacity > 255 * hash_size )
+            return( PSA_ERROR_INVALID_ARGUMENT );
+        status = psa_generator_hkdf_setup( &generator->ctx.hkdf,
+                                           slot,
+                                           hash_alg,
+                                           salt, salt_length,
+                                           label, label_length );
+    }
+    else
+#endif
+    {
+        return( PSA_ERROR_NOT_SUPPORTED );
+    }
+
+    /* Set generator->alg even on failure so that abort knows what to do. */
+    generator->alg = alg;
+    if( status == PSA_SUCCESS )
+        generator->capacity = capacity;
+    else
+        psa_generator_abort( generator );
+    return( status );
+}
+
+
+
+/****************************************************************/
+/* Random generation */
 /****************************************************************/
 
 psa_status_t psa_generate_random( uint8_t *output,
@@ -2991,13 +3354,8 @@
         }
 #if defined(MBEDTLS_DES_C)
         if( type == PSA_KEY_TYPE_DES )
-        {
-            mbedtls_des_key_set_parity( slot->data.raw.data );
-            if( slot->data.raw.bytes >= 16 )
-                mbedtls_des_key_set_parity( slot->data.raw.data + 8 );
-            if( slot->data.raw.bytes == 24 )
-                mbedtls_des_key_set_parity( slot->data.raw.data + 16 );
-        }
+            psa_des_set_key_parity( slot->data.raw.data,
+                                    slot->data.raw.bytes );
 #endif /* MBEDTLS_DES_C */
     }
     else
diff --git a/programs/.gitignore b/programs/.gitignore
index 0241896..d58253d 100644
--- a/programs/.gitignore
+++ b/programs/.gitignore
@@ -29,6 +29,9 @@
 pkey/rsa_sign_pss
 pkey/rsa_verify
 pkey/rsa_verify_pss
+psa/psa_constant_names
+psa/psa_constant_names_generated.c
+psa/key_ladder_demo
 random/gen_entropy
 random/gen_random_ctr_drbg
 random/gen_random_havege
diff --git a/programs/Makefile b/programs/Makefile
index b6d1fa2..9e1a527 100644
--- a/programs/Makefile
+++ b/programs/Makefile
@@ -60,6 +60,7 @@
 	pkey/rsa_decrypt$(EXEXT)	pkey/rsa_encrypt$(EXEXT)	\
 	pkey/rsa_sign$(EXEXT)		pkey/rsa_verify$(EXEXT)		\
 	pkey/rsa_sign_pss$(EXEXT)	pkey/rsa_verify_pss$(EXEXT)	\
+	psa/key_ladder_demo$(EXEXT)	psa/psa_constant_names$(EXEXT)	\
 	ssl/dtls_client$(EXEXT)		ssl/dtls_server$(EXEXT)		\
 	ssl/ssl_client1$(EXEXT)		ssl/ssl_client2$(EXEXT)		\
 	ssl/ssl_server$(EXEXT)		ssl/ssl_server2$(EXEXT)		\
@@ -83,6 +84,8 @@
 APPS += test/cpp_dummy_build$(EXEXT)
 endif
 
+EXTRA_GENERATED =
+
 .SILENT:
 
 .PHONY: all clean list
@@ -92,6 +95,11 @@
 $(DEP):
 	$(MAKE) -C ../library
 
+EXTRA_GENERATED += psa/psa_constant_names_generated.c
+psa/psa_constant_names$(EXEXT): psa/psa_constant_names_generated.c
+psa/psa_constant_names_generated.c: ../scripts/generate_psa_constants.py ../include/psa/crypto.h
+	../scripts/generate_psa_constants.py
+
 aes/aescrypt2$(EXEXT): aes/aescrypt2.c $(DEP)
 	echo "  CC    aes/aescrypt2.c"
 	$(CC) $(LOCAL_CFLAGS) $(CFLAGS) aes/aescrypt2.c    $(LOCAL_LDFLAGS) $(LDFLAGS) -o $@
@@ -188,6 +196,14 @@
 	echo "  CC    pkey/rsa_encrypt.c"
 	$(CC) $(LOCAL_CFLAGS) $(CFLAGS) pkey/rsa_encrypt.c    $(LOCAL_LDFLAGS) $(LDFLAGS) -o $@
 
+psa/key_ladder_demo$(EXEXT): psa/key_ladder_demo.c $(DEP)
+	echo "  CC    psa/key_ladder_demo.c"
+	$(CC) $(LOCAL_CFLAGS) $(CFLAGS) psa/key_ladder_demo.c    $(LOCAL_LDFLAGS) $(LDFLAGS) -o $@
+
+psa/psa_constant_names$(EXEXT): psa/psa_constant_names.c $(DEP)
+	echo "  CC    psa/psa_constant_names.c"
+	$(CC) $(LOCAL_CFLAGS) $(CFLAGS) psa/psa_constant_names.c    $(LOCAL_LDFLAGS) $(LDFLAGS) -o $@
+
 random/gen_entropy$(EXEXT): random/gen_entropy.c $(DEP)
 	echo "  CC    random/gen_entropy.c"
 	$(CC) $(LOCAL_CFLAGS) $(CFLAGS) random/gen_entropy.c $(LOCAL_LDFLAGS) $(LDFLAGS) -o $@
@@ -294,9 +310,9 @@
 
 clean:
 ifndef WINDOWS
-	rm -f $(APPS)
+	rm -f $(APPS) $(EXTRA_GENERATED)
 else
-	del /S /Q /F *.o *.exe
+	del /S /Q /F *.o *.exe $(EXTRA_GENERATED)
 endif
 
 list:
diff --git a/programs/psa/key_ladder_demo.c b/programs/psa/key_ladder_demo.c
new file mode 100644
index 0000000..2c75ca4
--- /dev/null
+++ b/programs/psa/key_ladder_demo.c
@@ -0,0 +1,682 @@
+/**
+ * PSA API key derivation demonstration
+ *
+ * This program calculates a key ladder: a chain of secret material, each
+ * derived from the previous one in a deterministic way based on a label.
+ * Two keys are identical if and only if they are derived from the same key
+ * using the same label.
+ *
+ * The initial key is called the master key. The master key is normally
+ * randomly generated, but it could itself be derived from another key.
+ *
+ * This program derives a series of keys called intermediate keys.
+ * The first intermediate key is derived from the master key using the
+ * first label passed on the command line. Each subsequent intermediate
+ * key is derived from the previous one using the next label passed
+ * on the command line.
+ *
+ * This program has four modes of operation:
+ *
+ * - "generate": generate a random master key.
+ * - "wrap": derive a wrapping key from the last intermediate key,
+ *           and use that key to encrypt-and-authenticate some data.
+ * - "unwrap": derive a wrapping key from the last intermediate key,
+ *             and use that key to decrypt-and-authenticate some
+ *             ciphertext created by wrap mode.
+ * - "save": save the last intermediate key so that it can be reused as
+ *           the master key in another run of the program.
+ *
+ * See the usage() output for the command line usage. See the file
+ * `key_ladder_demo.sh` for an example run.
+ */
+
+/*  Copyright (C) 2018, ARM Limited, All Rights Reserved
+ *  SPDX-License-Identifier: Apache-2.0
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License"); you may
+ *  not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ *  WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ *  This file is part of mbed TLS (https://tls.mbed.org)
+ */
+
+/* First include Mbed TLS headers to get the Mbed TLS configuration and
+ * platform definitions that we'll use in this program. Also include
+ * standard C headers for functions we'll use here. */
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "mbedtls/config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#if defined(MBEDTLS_PLATFORM_C)
+#include "mbedtls/platform.h"
+#else
+#include <stdlib.h>
+#define MBEDTLS_EXIT_SUCCESS EXIT_SUCCESS
+#define MBEDTLS_EXIT_FAILURE EXIT_FAILURE
+#define mbedtls_calloc       calloc
+#define mbedtls_free         free
+#define mbedtls_printf       printf
+#endif
+#include <stdio.h>
+#include <string.h>
+
+#include "mbedtls/platform_util.h" // for mbedtls_platform_zeroize
+
+/* If the build options we need are not enabled, compile a placeholder. */
+#if !defined(MBEDTLS_SHA256_C) || !defined(MBEDTLS_MD_C) ||     \
+    !defined(MBEDTLS_AES_C) || !defined(MBEDTLS_CCM_C) ||       \
+    !defined(MBEDTLS_PSA_CRYPTO_C) || !defined(MBEDTLS_FS_IO)
+int main( void )
+{
+    mbedtls_printf("MBEDTLS_SHA256_C and/or MBEDTLS_MD_C and/or "
+                   "MBEDTLS_AES_C and/or MBEDTLS_CCM_C and/or "
+                   "MBEDTLS_PSA_CRYPTO_C and/or MBEDTLS_FS_IO not defined.\n");
+    return( 0 );
+}
+#else
+
+/* The real program starts here. */
+
+
+
+#include <psa/crypto.h>
+
+/* Run a system function and bail out if it fails. */
+#define SYS_CHECK( expr )                                       \
+    do                                                          \
+    {                                                           \
+        if( ! ( expr ) )                                        \
+        {                                                       \
+            perror( #expr );                                    \
+            status = DEMO_ERROR;                                \
+            goto exit;                                          \
+        }                                                       \
+    }                                                           \
+    while( 0 )
+
+/* Run a PSA function and bail out if it fails. */
+#define PSA_CHECK( expr )                                       \
+    do                                                          \
+    {                                                           \
+        status = ( expr );                                      \
+        if( status != PSA_SUCCESS )                             \
+        {                                                       \
+            mbedtls_printf( "Error %d at line %u: %s\n",        \
+                            (int) status,                       \
+                            __LINE__,                           \
+                            #expr );                            \
+            goto exit;                                          \
+        }                                                       \
+    }                                                           \
+    while( 0 )
+
+/* To report operational errors in this program, use an error code that is
+ * different from every PSA error code. */
+#define DEMO_ERROR 120
+
+/* The maximum supported key ladder depth. */
+#define MAX_LADDER_DEPTH 10
+
+/* Salt to use when deriving an intermediate key. */
+#define DERIVE_KEY_SALT ( (uint8_t *) "key_ladder_demo.derive" )
+#define DERIVE_KEY_SALT_LENGTH ( strlen( (const char*) DERIVE_KEY_SALT ) )
+
+/* Salt to use when deriving a wrapping key. */
+#define WRAPPING_KEY_SALT ( (uint8_t *) "key_ladder_demo.wrap" )
+#define WRAPPING_KEY_SALT_LENGTH ( strlen( (const char*) WRAPPING_KEY_SALT ) )
+
+/* Size of the key derivation keys (applies both to the master key and
+ * to intermediate keys). */
+#define KEY_SIZE_BYTES 40
+
+/* Algorithm for key derivation. */
+#define KDF_ALG PSA_ALG_HKDF( PSA_ALG_SHA_256 )
+
+/* Type and size of the key used to wrap data. */
+#define WRAPPING_KEY_TYPE PSA_KEY_TYPE_AES
+#define WRAPPING_KEY_BITS 128
+
+/* Cipher mode used to wrap data. */
+#define WRAPPING_ALG PSA_ALG_CCM
+
+/* Nonce size used to wrap data. */
+#define WRAPPING_IV_SIZE 13
+
+/* Header used in files containing wrapped data. We'll save this header
+ * directly without worrying about data representation issues such as
+ * integer sizes and endianness, because the data is meant to be read
+ * back by the same program on the same machine. */
+#define WRAPPED_DATA_MAGIC "key_ladder_demo" // including trailing null byte
+#define WRAPPED_DATA_MAGIC_LENGTH ( sizeof( WRAPPED_DATA_MAGIC ) )
+typedef struct
+{
+    char magic[WRAPPED_DATA_MAGIC_LENGTH];
+    size_t ad_size; /* Size of the additional data, which is this header. */
+    size_t payload_size; /* Size of the encrypted data. */
+    /* Store the IV inside the additional data. It's convenient. */
+    uint8_t iv[WRAPPING_IV_SIZE];
+} wrapped_data_header_t;
+
+/* This program uses three key slots: one for the master key, one to
+ * derive intermediate keys, and one for the wrapping key. We use a
+ * single slot for all the intermediate keys because they are only
+ * needed successively, so each time we derive an intermediate key,
+ * we destroy the previous one. */
+static const psa_key_slot_t master_key_slot = 1;
+static const psa_key_slot_t derived_key_slot = 2;
+static const psa_key_slot_t wrapping_key_slot = 3;
+
+/* The modes that this program can operate in (see usage). */
+enum program_mode
+{
+    MODE_GENERATE,
+    MODE_SAVE,
+    MODE_UNWRAP,
+    MODE_WRAP
+};
+
+/* Save a key to a file. In the real world, you may want to export a derived
+ * key sometimes, to share it with another party. */
+static psa_status_t save_key( psa_key_slot_t key_slot,
+                              const char *output_file_name )
+{
+    psa_status_t status = PSA_SUCCESS;
+    uint8_t key_data[KEY_SIZE_BYTES];
+    size_t key_size;
+    FILE *key_file = NULL;
+
+    PSA_CHECK( psa_export_key( key_slot,
+                               key_data, sizeof( key_data ),
+                               &key_size ) );
+    SYS_CHECK( ( key_file = fopen( output_file_name, "wb" ) ) != NULL );
+    SYS_CHECK( fwrite( key_data, 1, key_size, key_file ) == key_size );
+    SYS_CHECK( fclose( key_file ) == 0 );
+    key_file = NULL;
+
+exit:
+    if( key_file != NULL)
+        fclose( key_file );
+    return( status );
+}
+
+/* Generate a master key for use in this demo.
+ *
+ * Normally a master key would be non-exportable. For the purpose of this
+ * demo, we want to save it to a file, to avoid relying on the keystore
+ * capability of the PSA crypto library. */
+static psa_status_t generate( const char *key_file_name )
+{
+    psa_status_t status = PSA_SUCCESS;
+    psa_key_policy_t policy;
+
+    psa_key_policy_init( &policy );
+    psa_key_policy_set_usage( &policy,
+                              PSA_KEY_USAGE_DERIVE | PSA_KEY_USAGE_EXPORT,
+                              KDF_ALG );
+    PSA_CHECK( psa_set_key_policy( master_key_slot, &policy ) );
+
+    PSA_CHECK( psa_generate_key( master_key_slot,
+                                 PSA_KEY_TYPE_DERIVE,
+                                 PSA_BYTES_TO_BITS( KEY_SIZE_BYTES ),
+                                 NULL, 0 ) );
+
+    PSA_CHECK( save_key( master_key_slot, key_file_name ) );
+
+exit:
+    return( status );
+}
+
+/* Load the master key from a file.
+ *
+ * In the real world, this master key would be stored in an internal memory
+ * and the storage would be managed by the keystore capability of the PSA
+ * crypto library. */
+static psa_status_t import_key_from_file( psa_key_slot_t key_slot,
+                                          psa_key_usage_t usage,
+                                          psa_algorithm_t alg,
+                                          const char *key_file_name )
+{
+    psa_status_t status = PSA_SUCCESS;
+    psa_key_policy_t policy;
+    uint8_t key_data[KEY_SIZE_BYTES];
+    size_t key_size;
+    FILE *key_file = NULL;
+    unsigned char extra_byte;
+
+    SYS_CHECK( ( key_file = fopen( key_file_name, "rb" ) ) != NULL );
+    SYS_CHECK( ( key_size = fread( key_data, 1, sizeof( key_data ),
+                                   key_file ) ) != 0 );
+    if( fread( &extra_byte, 1, 1, key_file ) != 0 )
+    {
+        mbedtls_printf( "Key file too large (max: %u).\n",
+                        (unsigned) sizeof( key_data ) );
+        status = DEMO_ERROR;
+        goto exit;
+    }
+    SYS_CHECK( fclose( key_file ) == 0 );
+    key_file = NULL;
+
+    psa_key_policy_init( &policy );
+    psa_key_policy_set_usage( &policy, usage, alg );
+    PSA_CHECK( psa_set_key_policy( key_slot, &policy ) );
+    PSA_CHECK( psa_import_key( key_slot,
+                               PSA_KEY_TYPE_DERIVE,
+                               key_data, key_size ) );
+exit:
+    if( key_file != NULL )
+        fclose( key_file );
+    mbedtls_platform_zeroize( key_data, sizeof( key_data ) );
+    return( status );
+}
+
+/* Derive the intermediate keys, using the list of labels provided on
+ * the command line. */
+static psa_status_t derive_key_ladder( const char *ladder[],
+                                       size_t ladder_depth )
+{
+    psa_status_t status = PSA_SUCCESS;
+    psa_key_policy_t policy;
+    psa_crypto_generator_t generator = PSA_CRYPTO_GENERATOR_INIT;
+    /* We'll derive the first intermediate key from the master key, then
+     * each subsequent intemediate key from the previous intemediate key. */
+    psa_key_slot_t parent_key_slot = master_key_slot;
+    size_t i;
+    psa_key_policy_init( &policy );
+    psa_key_policy_set_usage( &policy,
+                              PSA_KEY_USAGE_DERIVE | PSA_KEY_USAGE_EXPORT,
+                              KDF_ALG );
+
+    /* For each label in turn, ... */
+    for( i = 0; i < ladder_depth; i++ )
+    {
+        /* Start deriving material from the master key (if i=0) or from
+         * the current intermediate key (if i>0). */
+        PSA_CHECK( psa_key_derivation(
+                       &generator,
+                       parent_key_slot,
+                       KDF_ALG,
+                       DERIVE_KEY_SALT, DERIVE_KEY_SALT_LENGTH,
+                       (uint8_t*) ladder[i], strlen( ladder[i] ),
+                       KEY_SIZE_BYTES ) );
+        /* When the parent key is not the master key, destroy it,
+         * since it is no longer needed. */
+        if( i != 0 )
+            PSA_CHECK( psa_destroy_key( derived_key_slot ) );
+        PSA_CHECK( psa_set_key_policy( derived_key_slot, &policy ) );
+        /* Use the generator obtained from the parent key to create
+         * the next intermediate key. */
+        PSA_CHECK( psa_generator_import_key(
+                       derived_key_slot,
+                       PSA_KEY_TYPE_DERIVE,
+                       PSA_BYTES_TO_BITS( KEY_SIZE_BYTES ),
+                       &generator ) );
+        PSA_CHECK( psa_generator_abort( &generator ) );
+        parent_key_slot = derived_key_slot;
+    }
+
+exit:
+    psa_generator_abort( &generator );
+    return( status );
+}
+
+/* Derive a wrapping key from the last intermediate key. */
+static psa_status_t derive_wrapping_key( psa_key_usage_t usage )
+{
+    psa_status_t status = PSA_SUCCESS;
+    psa_key_policy_t policy;
+    psa_crypto_generator_t generator = PSA_CRYPTO_GENERATOR_INIT;
+
+    psa_key_policy_init( &policy );
+    psa_key_policy_set_usage( &policy, usage, WRAPPING_ALG );
+    PSA_CHECK( psa_set_key_policy( wrapping_key_slot, &policy ) );
+
+    PSA_CHECK( psa_key_derivation(
+                   &generator,
+                   derived_key_slot,
+                   KDF_ALG,
+                   WRAPPING_KEY_SALT, WRAPPING_KEY_SALT_LENGTH,
+                   NULL, 0,
+                   PSA_BITS_TO_BYTES( WRAPPING_KEY_BITS ) ) );
+    PSA_CHECK( psa_generator_import_key(
+                   wrapping_key_slot,
+                   PSA_KEY_TYPE_AES,
+                   WRAPPING_KEY_BITS,
+                   &generator ) );
+
+exit:
+    psa_generator_abort( &generator );
+    return( status );
+}
+
+static psa_status_t wrap_data( const char *input_file_name,
+                               const char *output_file_name )
+{
+    psa_status_t status;
+    FILE *input_file = NULL;
+    FILE *output_file = NULL;
+    long input_position;
+    size_t input_size;
+    size_t buffer_size;
+    unsigned char *buffer = NULL;
+    size_t ciphertext_size;
+    wrapped_data_header_t header;
+
+    /* Find the size of the data to wrap. */
+    SYS_CHECK( ( input_file = fopen( input_file_name, "rb" ) ) != NULL );
+    SYS_CHECK( fseek( input_file, 0, SEEK_END ) == 0 );
+    SYS_CHECK( ( input_position = ftell( input_file ) ) != -1 );
+#if LONG_MAX > SIZE_MAX
+    if( input_position > SIZE_MAX )
+    {
+        mbedtls_printf( "Input file too large.\n" );
+        status = DEMO_ERROR;
+        goto exit;
+    }
+#endif
+    input_size = input_position;
+    buffer_size = PSA_AEAD_ENCRYPT_OUTPUT_SIZE( WRAPPING_ALG, input_size );
+    /* Check for integer overflow. */
+    if( buffer_size < input_size )
+    {
+        mbedtls_printf( "Input file too large.\n" );
+        status = DEMO_ERROR;
+        goto exit;
+    }
+
+    /* Load the data to wrap. */
+    SYS_CHECK( fseek( input_file, 0, SEEK_SET ) == 0 );
+    SYS_CHECK( ( buffer = mbedtls_calloc( 1, buffer_size ) ) != NULL );
+    SYS_CHECK( fread( buffer, 1, input_size, input_file ) == input_size );
+    SYS_CHECK( fclose( input_file ) == 0 );
+    input_file = NULL;
+
+    /* Construct a header. */
+    memcpy( &header.magic, WRAPPED_DATA_MAGIC, WRAPPED_DATA_MAGIC_LENGTH );
+    header.ad_size = sizeof( header );
+    header.payload_size = input_size;
+
+    /* Wrap the data. */
+    PSA_CHECK( psa_generate_random( header.iv, WRAPPING_IV_SIZE ) );
+    PSA_CHECK( psa_aead_encrypt( wrapping_key_slot, WRAPPING_ALG,
+                                 header.iv, WRAPPING_IV_SIZE,
+                                 (uint8_t *) &header, sizeof( header ),
+                                 buffer, input_size,
+                                 buffer, buffer_size,
+                                 &ciphertext_size ) );
+
+    /* Write the output. */
+    SYS_CHECK( ( output_file = fopen( output_file_name, "wb" ) ) != NULL );
+    SYS_CHECK( fwrite( &header, 1, sizeof( header ),
+                       output_file ) == sizeof( header ) );
+    SYS_CHECK( fwrite( buffer, 1, ciphertext_size,
+                       output_file ) == ciphertext_size );
+    SYS_CHECK( fclose( output_file ) == 0 );
+    output_file = NULL;
+
+exit:
+    if( input_file != NULL )
+        fclose( input_file );
+    if( output_file != NULL )
+        fclose( output_file );
+    if( buffer != NULL )
+        mbedtls_platform_zeroize( buffer, buffer_size );
+    mbedtls_free( buffer );
+    return( status );
+}
+
+static psa_status_t unwrap_data( const char *input_file_name,
+                                 const char *output_file_name )
+{
+    psa_status_t status;
+    FILE *input_file = NULL;
+    FILE *output_file = NULL;
+    unsigned char *buffer = NULL;
+    size_t ciphertext_size;
+    size_t plaintext_size;
+    wrapped_data_header_t header;
+    unsigned char extra_byte;
+
+    /* Load and validate the header. */
+    SYS_CHECK( ( input_file = fopen( input_file_name, "rb" ) ) != NULL );
+    SYS_CHECK( fread( &header, 1, sizeof( header ),
+                      input_file ) == sizeof( header ) );
+    if( memcmp( &header.magic, WRAPPED_DATA_MAGIC,
+                WRAPPED_DATA_MAGIC_LENGTH ) != 0 )
+    {
+        mbedtls_printf( "The input does not start with a valid magic header.\n" );
+        status = DEMO_ERROR;
+        goto exit;
+    }
+    if( header.ad_size != sizeof( header ) )
+    {
+        mbedtls_printf( "The header size is not correct.\n" );
+        status = DEMO_ERROR;
+        goto exit;
+    }
+    ciphertext_size =
+        PSA_AEAD_ENCRYPT_OUTPUT_SIZE( WRAPPING_ALG, header.payload_size );
+    /* Check for integer overflow. */
+    if( ciphertext_size < header.payload_size )
+    {
+        mbedtls_printf( "Input file too large.\n" );
+        status = DEMO_ERROR;
+        goto exit;
+    }
+
+    /* Load the payload data. */
+    SYS_CHECK( ( buffer = mbedtls_calloc( 1, ciphertext_size ) ) != NULL );
+    SYS_CHECK( fread( buffer, 1, ciphertext_size,
+                      input_file ) == ciphertext_size );
+    if( fread( &extra_byte, 1, 1, input_file ) != 0 )
+    {
+        mbedtls_printf( "Extra garbage after ciphertext\n" );
+        status = DEMO_ERROR;
+        goto exit;
+    }
+    SYS_CHECK( fclose( input_file ) == 0 );
+    input_file = NULL;
+
+    /* Unwrap the data. */
+    PSA_CHECK( psa_aead_decrypt( wrapping_key_slot, WRAPPING_ALG,
+                                 header.iv, WRAPPING_IV_SIZE,
+                                 (uint8_t *) &header, sizeof( header ),
+                                 buffer, ciphertext_size,
+                                 buffer, ciphertext_size,
+                                 &plaintext_size ) );
+    if( plaintext_size != header.payload_size )
+    {
+        mbedtls_printf( "Incorrect payload size in the header.\n" );
+        status = DEMO_ERROR;
+        goto exit;
+    }
+
+    /* Write the output. */
+    SYS_CHECK( ( output_file = fopen( output_file_name, "wb" ) ) != NULL );
+    SYS_CHECK( fwrite( buffer, 1, plaintext_size,
+                       output_file ) == plaintext_size );
+    SYS_CHECK( fclose( output_file ) == 0 );
+    output_file = NULL;
+
+exit:
+    if( input_file != NULL )
+        fclose( input_file );
+    if( output_file != NULL )
+        fclose( output_file );
+    if( buffer != NULL )
+        mbedtls_platform_zeroize( buffer, ciphertext_size );
+    mbedtls_free( buffer );
+    return( status );
+}
+
+static psa_status_t run( enum program_mode mode,
+                         const char *key_file_name,
+                         const char *ladder[], size_t ladder_depth,
+                         const char *input_file_name,
+                         const char *output_file_name )
+{
+    psa_status_t status = PSA_SUCCESS;
+
+    /* Initialize the PSA crypto library. */
+    PSA_CHECK( psa_crypto_init( ) );
+
+    /* Generate mode is unlike the others. Generate the master key and exit. */
+    if( mode == MODE_GENERATE )
+        return( generate( key_file_name ) );
+
+    /* Read the master key. */
+    PSA_CHECK( import_key_from_file( master_key_slot,
+                                     PSA_KEY_USAGE_DERIVE | PSA_KEY_USAGE_EXPORT,
+                                     KDF_ALG,
+                                     key_file_name ) );
+
+    /* Calculate the derived key for this session. */
+    PSA_CHECK( derive_key_ladder( ladder, ladder_depth ) );
+
+    switch( mode )
+    {
+        case MODE_SAVE:
+            PSA_CHECK( save_key( derived_key_slot, output_file_name ) );
+            break;
+        case MODE_UNWRAP:
+            PSA_CHECK( derive_wrapping_key( PSA_KEY_USAGE_DECRYPT ) );
+            PSA_CHECK( unwrap_data( input_file_name, output_file_name ) );
+            break;
+        case MODE_WRAP:
+            PSA_CHECK( derive_wrapping_key( PSA_KEY_USAGE_ENCRYPT ) );
+            PSA_CHECK( wrap_data( input_file_name, output_file_name ) );
+            break;
+        default:
+            /* Unreachable but some compilers don't realize it. */
+            break;
+    }
+
+exit:
+    /* Deinitialize the PSA crypto library. */
+    mbedtls_psa_crypto_free( );
+    return( status );
+}
+
+static void usage( void )
+{
+    mbedtls_printf( "Usage: key_ladder_demo MODE [OPTION=VALUE]...\n" );
+    mbedtls_printf( "Demonstrate the usage of a key derivation ladder.\n" );
+    mbedtls_printf( "\n" );
+    mbedtls_printf( "Modes:\n" );
+    mbedtls_printf( "  generate  Generate the master key\n" );
+    mbedtls_printf( "  save      Save the derived key\n" );
+    mbedtls_printf( "  unwrap    Unwrap (decrypt) input with the derived key\n" );
+    mbedtls_printf( "  wrap      Wrap (encrypt) input with the derived key\n" );
+    mbedtls_printf( "\n" );
+    mbedtls_printf( "Options:\n" );
+    mbedtls_printf( "  input=FILENAME    Input file (required for wrap/unwrap)\n" );
+    mbedtls_printf( "  master=FILENAME   File containing the master key (default: master.key)\n" );
+    mbedtls_printf( "  output=FILENAME   Output file (required for save/wrap/unwrap)\n" );
+    mbedtls_printf( "  label=TEXT        Label for the key derivation.\n" );
+    mbedtls_printf( "                    This may be repeated multiple times.\n" );
+    mbedtls_printf( "                    To get the same key, you must use the same master key\n" );
+    mbedtls_printf( "                    and the same sequence of labels.\n" );
+}
+
+int main( int argc, char *argv[] )
+{
+    char *key_file_name = "master.key";
+    char *input_file_name = NULL;
+    char *output_file_name = NULL;
+    const char *ladder[MAX_LADDER_DEPTH];
+    size_t ladder_depth = 0;
+    int i;
+    enum program_mode mode;
+    psa_status_t status;
+
+    if( argc <= 1 ||
+        strcmp( argv[1], "help" ) == 0 ||
+        strcmp( argv[1], "-help" ) == 0 ||
+        strcmp( argv[1], "--help" ) == 0 )
+    {
+        usage( );
+        return( MBEDTLS_EXIT_SUCCESS );
+    }
+
+    for( i = 2; i < argc; i++ )
+    {
+        char *q = strchr( argv[i], '=' );
+        if( q == NULL )
+        {
+            mbedtls_printf( "Missing argument to option %s\n", argv[i] );
+            goto usage_failure;
+        }
+        *q = 0;
+        ++q;
+        if( strcmp( argv[i], "input" ) == 0 )
+            input_file_name = q;
+        else if( strcmp( argv[i], "label" ) == 0 )
+        {
+            if( ladder_depth == MAX_LADDER_DEPTH )
+            {
+                mbedtls_printf( "Maximum ladder depth %u exceeded.\n",
+                                (unsigned) MAX_LADDER_DEPTH );
+                return( MBEDTLS_EXIT_FAILURE );
+            }
+            ladder[ladder_depth] = q;
+            ++ladder_depth;
+        }
+        else if( strcmp( argv[i], "master" ) == 0 )
+            key_file_name = q;
+        else if( strcmp( argv[i], "output" ) == 0 )
+            output_file_name = q;
+        else
+        {
+            mbedtls_printf( "Unknown option: %s\n", argv[i] );
+            goto usage_failure;
+        }
+    }
+
+    if( strcmp( argv[1], "generate" ) == 0 )
+        mode = MODE_GENERATE;
+    else if( strcmp( argv[1], "save" ) == 0 )
+        mode = MODE_SAVE;
+    else if( strcmp( argv[1], "unwrap" ) == 0 )
+        mode = MODE_UNWRAP;
+    else if( strcmp( argv[1], "wrap" ) == 0 )
+        mode = MODE_WRAP;
+    else
+    {
+        mbedtls_printf( "Unknown action: %s\n", argv[1] );
+        goto usage_failure;
+    }
+
+    if( input_file_name == NULL &&
+        ( mode == MODE_WRAP || mode == MODE_UNWRAP ) )
+    {
+        mbedtls_printf( "Required argument missing: input\n" );
+        return( DEMO_ERROR );
+    }
+    if( output_file_name == NULL &&
+        ( mode == MODE_SAVE || mode == MODE_WRAP || mode == MODE_UNWRAP ) )
+    {
+        mbedtls_printf( "Required argument missing: output\n" );
+        return( DEMO_ERROR );
+    }
+
+    status = run( mode, key_file_name,
+                  ladder, ladder_depth,
+                  input_file_name, output_file_name );
+    return( status == PSA_SUCCESS ?
+            MBEDTLS_EXIT_SUCCESS :
+            MBEDTLS_EXIT_FAILURE );
+
+usage_failure:
+    usage( );
+    return( MBEDTLS_EXIT_FAILURE );
+}
+#endif /* MBEDTLS_SHA256_C && MBEDTLS_MD_C && MBEDTLS_AES_C && MBEDTLS_CCM_C && MBEDTLS_PSA_CRYPTO_C && MBEDTLS_FS_IO */
diff --git a/programs/psa/key_ladder_demo.sh b/programs/psa/key_ladder_demo.sh
new file mode 100755
index 0000000..2cec945
--- /dev/null
+++ b/programs/psa/key_ladder_demo.sh
@@ -0,0 +1,49 @@
+#!/bin/sh
+set -e -u
+
+program="${0%/*}"/key_ladder_demo
+files_to_clean=
+
+run () {
+    echo
+    echo "# $1"
+    shift
+    echo "+ $*"
+    "$@"
+}
+
+if [ -e master.key ]; then
+    echo "# Reusing the existing master.key file."
+else
+    files_to_clean="$files_to_clean master.key"
+    run "Generate a master key." \
+        "$program" generate master=master.key
+fi
+
+files_to_clean="$files_to_clean input.txt hello_world.wrap"
+echo "Here is some input. See it wrapped." >input.txt
+run "Derive a key and wrap some data with it." \
+    "$program" wrap master=master.key label=hello label=world \
+               input=input.txt output=hello_world.wrap
+
+files_to_clean="$files_to_clean hello_world.txt"
+run "Derive the same key again and unwrap the data." \
+    "$program" unwrap master=master.key label=hello label=world \
+               input=hello_world.wrap output=hello_world.txt
+run "Compare the unwrapped data with the original input." \
+    cmp input.txt hello_world.txt
+
+files_to_clean="$files_to_clean hellow_orld.txt"
+! run "Derive a different key and attempt to unwrap the data. This must fail." \
+  "$program" unwrap master=master.key input=hello_world.wrap output=hellow_orld.txt label=hellow label=orld
+
+files_to_clean="$files_to_clean hello.key"
+run "Save the first step of the key ladder, then load it as a master key and construct the rest of the ladder." \
+    "$program" save master=master.key label=hello \
+               input=hello_world.wrap output=hello.key
+run "Check that we get the same key by unwrapping data made by the other key." \
+    "$program" unwrap master=hello.key label=world \
+               input=hello_world.wrap output=hello_world.txt
+
+# Cleanup
+rm -f $files_to_clean
diff --git a/programs/psa/psa_constant_names.c b/programs/psa/psa_constant_names.c
new file mode 100644
index 0000000..d422e14
--- /dev/null
+++ b/programs/psa/psa_constant_names.c
@@ -0,0 +1,157 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "psa/crypto.h"
+
+/* There are different GET_HASH macros for different kinds of algorithms
+ * built from hashes, but the values are all constructed on the
+ * same model. */
+#define PSA_ALG_GET_HASH(alg)                                   \
+    (((alg) & PSA_ALG_HASH_MASK) | PSA_ALG_CATEGORY_HASH)
+
+static void append(char **buffer, size_t buffer_size,
+                   size_t *required_size,
+                   const char *string, size_t length)
+{
+    *required_size += length;
+    if (*required_size < buffer_size) {
+        memcpy(*buffer, string, length);
+        *buffer += length;
+    }
+}
+
+/* The code of these function is automatically generated and included below. */
+static const char *psa_ecc_curve_name(psa_ecc_curve_t curve);
+static const char *psa_hash_algorithm_name(psa_algorithm_t hash_alg);
+
+static void append_with_curve(char **buffer, size_t buffer_size,
+                              size_t *required_size,
+                              const char *string, size_t length,
+                              psa_ecc_curve_t curve)
+{
+    const char *curve_name = psa_ecc_curve_name(curve);
+    append(buffer, buffer_size, required_size, string, length);
+    append(buffer, buffer_size, required_size, "(", 1);
+    if (curve_name != NULL) {
+        append(buffer, buffer_size, required_size,
+               curve_name, strlen(curve_name));
+    } else {
+        size_t n = snprintf(*buffer, buffer_size - *required_size,
+                            "0x%04x", (unsigned) curve);
+        if (n < buffer_size - *required_size) *buffer += n;
+        *required_size += n;
+    }
+    append(buffer, buffer_size, required_size, ")", 1);
+}
+
+static void append_with_hash(char **buffer, size_t buffer_size,
+                             size_t *required_size,
+                             const char *string, size_t length,
+                             psa_algorithm_t hash_alg)
+{
+    const char *hash_name = psa_hash_algorithm_name(hash_alg);
+    append(buffer, buffer_size, required_size, string, length);
+    append(buffer, buffer_size, required_size, "(", 1);
+    if (hash_name != NULL) {
+        append(buffer, buffer_size, required_size,
+               hash_name, strlen(hash_name));
+    } else {
+        size_t n = snprintf(*buffer, buffer_size - *required_size,
+                            "0x%08lx", (unsigned long) hash_alg);
+        if (n < buffer_size - *required_size) *buffer += n;
+        *required_size += n;
+    }
+    append(buffer, buffer_size, required_size, ")", 1);
+}
+
+#include "psa_constant_names_generated.c"
+
+static int psa_snprint_status(char *buffer, size_t buffer_size,
+                              psa_status_t status)
+{
+    const char *name = psa_strerror(status);
+    if (name == NULL) {
+        return snprintf(buffer, buffer_size, "%ld", (long) status);
+    } else {
+        size_t length = strlen(name);
+        if (length < buffer_size) {
+            memcpy(buffer, name, length + 1);
+            return length;
+        } else {
+            return buffer_size;
+        }
+    }
+}
+
+static int psa_snprint_ecc_curve(char *buffer, size_t buffer_size,
+                                 psa_ecc_curve_t curve)
+{
+    const char *name = psa_ecc_curve_name(curve);
+    if (name == NULL) {
+        return snprintf(buffer, buffer_size, "0x%04x", (unsigned) curve);
+    } else {
+        size_t length = strlen(name);
+        if (length < buffer_size) {
+            memcpy(buffer, name, length + 1);
+            return length;
+        } else {
+            return buffer_size;
+        }
+    }
+}
+
+static void usage(const char *program_name)
+{
+    printf("Usage: %s TYPE VALUE\n",
+           program_name == NULL ? "psa_constant_names" : program_name);
+    printf("Print the symbolic name whose numerical value is VALUE in TYPE.\n");
+    printf("Supported types (with = between aliases):\n");
+    printf("  alg=algorithm         Status code (psa_algorithm_t)\n");
+    printf("  curve=ecc_curve       Elliptic curve identifier (psa_ecc_curve_t)\n");
+    printf("  type=key_type         Status code (psa_key_type_t)\n");
+    printf("  usage=key_usage       Key usage (psa_key_usage_t)\n");
+    printf("  error=status          Status code (psa_status_t)\n");
+}
+
+int main(int argc, char *argv[])
+{
+    char buffer[200];
+    unsigned long value;
+    char *end;
+
+    if (argc <= 1 ||
+        !strcmp(argv[1], "help") ||
+        !strcmp(argv[1], "--help"))
+    {
+        usage(argv[0]);
+        return EXIT_FAILURE;
+    }
+    if (argc != 3) {
+        usage(argv[0]);
+        return EXIT_FAILURE;
+    }
+    value = strtoul(argv[2], &end, 0);
+    if (*end) {
+        printf("Non-numeric value: %s\n", argv[2]);
+        return EXIT_FAILURE;
+    }
+
+    if (!strcmp(argv[1], "error") || !strcmp(argv[1], "status"))
+        psa_snprint_status(buffer, sizeof(buffer), value);
+    else if (!strcmp(argv[1], "alg") || !strcmp(argv[1], "algorithm"))
+        psa_snprint_algorithm(buffer, sizeof(buffer), value);
+    else if (!strcmp(argv[1], "curve") || !strcmp(argv[1], "ecc_curve"))
+        psa_snprint_ecc_curve(buffer, sizeof(buffer), value);
+    else if (!strcmp(argv[1], "type") || !strcmp(argv[1], "key_type"))
+        psa_snprint_key_type(buffer, sizeof(buffer), value);
+    else if (!strcmp(argv[1], "usage") || !strcmp(argv[1], "key_usage"))
+        psa_snprint_key_usage(buffer, sizeof(buffer), value);
+    else {
+        printf("Unknown type: %s\n", argv[1]);
+        return EXIT_FAILURE;
+    }
+
+    puts(buffer);
+    return EXIT_SUCCESS;
+}
diff --git a/scripts/generate_psa_constants.py b/scripts/generate_psa_constants.py
new file mode 100755
index 0000000..e4cb45b
--- /dev/null
+++ b/scripts/generate_psa_constants.py
@@ -0,0 +1,301 @@
+#!/usr/bin/env python
+import os
+import re
+import sys
+
+output_template = '''\
+/* Automatically generated by generate_psa_constant.py. DO NOT EDIT. */
+
+static const char *psa_strerror(psa_status_t status)
+{
+    switch (status) {
+    %(status_cases)s
+    default: return NULL;
+    }
+}
+
+static const char *psa_ecc_curve_name(psa_ecc_curve_t curve)
+{
+    switch (curve) {
+    %(ecc_curve_cases)s
+    default: return NULL;
+    }
+}
+
+static const char *psa_hash_algorithm_name(psa_algorithm_t hash_alg)
+{
+    switch (hash_alg) {
+    %(hash_algorithm_cases)s
+    default: return NULL;
+    }
+}
+
+static int psa_snprint_key_type(char *buffer, size_t buffer_size,
+                                psa_key_type_t type)
+{
+    size_t required_size = 0;
+    switch (type) {
+    %(key_type_cases)s
+    default:
+        %(key_type_code)s{
+            return snprintf(buffer, buffer_size,
+                            "0x%%08lx", (unsigned long) type);
+        }
+        break;
+    }
+    buffer[0] = 0;
+    return required_size;
+}
+
+static void append_padding_mode(char **buffer, size_t buffer_size,
+                                size_t *required_size,
+                                psa_algorithm_t padding_mode)
+{
+    size_t n;
+    append(buffer, buffer_size, required_size, " | ", 3);
+    switch (padding_mode) {
+    %(padding_mode_cases)s
+    default:
+        n = snprintf(*buffer, buffer_size - *required_size,
+                     "0x%%08lx", (unsigned long) padding_mode);
+        if (n < buffer_size - *required_size) *buffer += n;
+        *required_size += n;
+        break;
+    }
+}
+
+static int psa_snprint_algorithm(char *buffer, size_t buffer_size,
+                                 psa_algorithm_t alg)
+{
+    size_t required_size = 0;
+    psa_algorithm_t padding_mode = -1;
+    psa_algorithm_t alg_without_padding = alg;
+    if (PSA_ALG_IS_CIPHER(alg) && PSA_ALG_IS_BLOCK_CIPHER(alg)) {
+            padding_mode = alg & PSA_ALG_BLOCK_CIPHER_PADDING_MASK;
+            alg_without_padding = alg & ~PSA_ALG_BLOCK_CIPHER_PADDING_MASK;
+    }
+    switch (alg_without_padding) {
+    %(algorithm_cases)s
+    default:
+        %(algorithm_code)s{
+            return snprintf(buffer, buffer_size,
+                            "0x%%08lx", (unsigned long) alg);
+        }
+        break;
+    }
+    if (padding_mode != (psa_algorithm_t) -1) {
+        append_padding_mode(&buffer, buffer_size, &required_size, padding_mode);
+    }
+    buffer[0] = 0;
+    return required_size;
+}
+
+static int psa_snprint_key_usage(char *buffer, size_t buffer_size,
+                                 psa_key_usage_t usage)
+{
+    size_t required_size = 0;
+    if (usage == 0) {
+        if (buffer_size > 1) {
+            buffer[0] = '0';
+            buffer[1] = 0;
+        } else if (buffer_size == 1) {
+            buffer[0] = 0;
+        }
+        return 1;
+    }
+%(key_usage_code)s
+    if (usage != 0) {
+        if (required_size != 0) {
+            append(&buffer, buffer_size, &required_size, " | ", 3);
+        }
+        required_size += snprintf(buffer, buffer_size - required_size,
+                                  "0x%%08x", usage);
+    } else {
+        buffer[0] = 0;
+    }
+    return required_size;
+}
+
+/* End of automatically generated file. */
+'''
+
+key_type_from_curve_template = '''if (%(tester)s(type)) {
+        append_with_curve(&buffer, buffer_size, &required_size,
+                          "%(builder)s", %(builder_length)s,
+                          PSA_KEY_TYPE_GET_CURVE(type));
+    } else '''
+
+algorithm_from_hash_template = '''if (%(tester)s(alg_without_padding)) {
+        append_with_hash(&buffer, buffer_size, &required_size,
+                         "%(builder)s", %(builder_length)s,
+                         PSA_ALG_GET_HASH(alg_without_padding));
+    } else '''
+
+bit_test_template = '''\
+    if (%(var)s & %(flag)s) {
+        if (required_size != 0) {
+            append(&buffer, buffer_size, &required_size, " | ", 3);
+        }
+        append(&buffer, buffer_size, &required_size, "%(flag)s", %(length)d);
+        %(var)s ^= %(flag)s;
+    }\
+'''
+
+class MacroCollector:
+    def __init__(self):
+        self.statuses = set()
+        self.key_types = set()
+        self.key_types_from_curve = {}
+        self.ecc_curves = set()
+        self.algorithms = set()
+        self.hash_algorithms = set()
+        self.block_cipher_padding_modes = set()
+        self.algorithms_from_hash = {}
+        self.key_usages = set()
+
+    # "#define" followed by a macro name with either no parameters
+    # or a single parameter. Grab the macro name in group 1, the
+    # parameter name if any in group 2 and the definition in group 3.
+    definition_re = re.compile(r'\s*#\s*define\s+(\w+)(?:\s+|\((\w+)\)\s*)(.+)(?:/[*/])?')
+
+    def read_line(self, line):
+        m = re.match(self.definition_re, line)
+        if not m:
+            return
+        name, parameter, definition = m.groups()
+        if name.endswith('_FLAG') or name.endswith('MASK'):
+            # Macro only to build actual values
+            return
+        elif (name.startswith('PSA_ERROR_') or name == 'PSA_SUCCESS') \
+           and not parameter:
+            self.statuses.add(name)
+        elif name.startswith('PSA_KEY_TYPE_') and not parameter:
+            self.key_types.add(name)
+        elif name.startswith('PSA_KEY_TYPE_') and parameter == 'curve':
+            self.key_types_from_curve[name] = name[:13] + 'IS_' + name[13:]
+        elif name.startswith('PSA_ECC_CURVE_') and not parameter:
+            self.ecc_curves.add(name)
+        elif name.startswith('PSA_ALG_BLOCK_CIPHER_PAD_') and not parameter:
+            self.block_cipher_padding_modes.add(name)
+        elif name.startswith('PSA_ALG_') and not parameter:
+            if name in ['PSA_ALG_BLOCK_CIPHER_BASE',
+                        'PSA_ALG_ECDSA_BASE',
+                        'PSA_ALG_RSA_PKCS1V15_SIGN_BASE']:
+                # Ad hoc skipping of duplicate names for some numerical values
+                return
+            self.algorithms.add(name)
+            # Ad hoc detection of hash algorithms
+            if re.search(r'0x010000[0-9A-Fa-f]{2}', definition):
+                self.hash_algorithms.add(name)
+        elif name.startswith('PSA_ALG_') and parameter == 'hash_alg':
+            if name in ['PSA_ALG_DSA', 'PSA_ALG_ECDSA']:
+                # A naming irregularity
+                tester = name[:8] + 'IS_RANDOMIZED_' + name[8:]
+            else:
+                tester = name[:8] + 'IS_' + name[8:]
+            self.algorithms_from_hash[name] = tester
+        elif name.startswith('PSA_KEY_USAGE_') and not parameter:
+            self.key_usages.add(name)
+        else:
+            # Other macro without parameter
+            return
+
+    def read_file(self, header_file):
+        for line in header_file:
+            self.read_line(line)
+
+    def make_return_case(self, name):
+        return 'case %(name)s: return "%(name)s";' % {'name': name}
+
+    def make_append_case(self, name):
+        template = ('case %(name)s: '
+                    'append(&buffer, buffer_size, &required_size, "%(name)s", %(length)d); '
+                    'break;')
+        return template % {'name': name, 'length': len(name)}
+
+    def make_inner_append_case(self, name):
+        template = ('case %(name)s: '
+                    'append(buffer, buffer_size, required_size, "%(name)s", %(length)d); '
+                    'break;')
+        return template % {'name': name, 'length': len(name)}
+
+    def make_bit_test(self, var, flag):
+        return bit_test_template % {'var': var,
+                                    'flag': flag,
+                                    'length': len(flag)}
+
+    def make_status_cases(self):
+        return '\n    '.join(map(self.make_return_case,
+                                 sorted(self.statuses)))
+
+    def make_ecc_curve_cases(self):
+        return '\n    '.join(map(self.make_return_case,
+                                 sorted(self.ecc_curves)))
+
+    def make_key_type_cases(self):
+        return '\n    '.join(map(self.make_append_case,
+                                 sorted(self.key_types)))
+
+    def make_key_type_from_curve_code(self, builder, tester):
+        return key_type_from_curve_template % {'builder': builder,
+                                               'builder_length': len(builder),
+                                               'tester': tester}
+
+    def make_key_type_code(self):
+        d = self.key_types_from_curve
+        make = self.make_key_type_from_curve_code
+        return '\n        '.join([make(k, d[k]) for k in sorted(d.keys())])
+
+    def make_hash_algorithm_cases(self):
+        return '\n    '.join(map(self.make_return_case,
+                                 sorted(self.hash_algorithms)))
+
+    def make_padding_mode_cases(self):
+        return '\n    '.join(map(self.make_inner_append_case,
+                                 sorted(self.block_cipher_padding_modes)))
+
+    def make_algorithm_cases(self):
+        return '\n    '.join(map(self.make_append_case,
+                                 sorted(self.algorithms)))
+
+    def make_algorithm_from_hash_code(self, builder, tester):
+        return algorithm_from_hash_template % {'builder': builder,
+                                               'builder_length': len(builder),
+                                               'tester': tester}
+
+    def make_algorithm_code(self):
+        d = self.algorithms_from_hash
+        make = self.make_algorithm_from_hash_code
+        return '\n        '.join([make(k, d[k]) for k in sorted(d.keys())])
+
+    def make_key_usage_code(self):
+        return '\n'.join([self.make_bit_test('usage', bit)
+                          for bit in sorted(self.key_usages)])
+
+    def write_file(self, output_file):
+        data = {}
+        data['status_cases'] = self.make_status_cases()
+        data['ecc_curve_cases'] = self.make_ecc_curve_cases()
+        data['key_type_cases'] = self.make_key_type_cases()
+        data['key_type_code'] = self.make_key_type_code()
+        data['hash_algorithm_cases'] = self.make_hash_algorithm_cases()
+        data['padding_mode_cases'] = self.make_padding_mode_cases()
+        data['algorithm_cases'] = self.make_algorithm_cases()
+        data['algorithm_code'] = self.make_algorithm_code()
+        data['key_usage_code'] = self.make_key_usage_code()
+        output_file.write(output_template % data)
+
+def generate_psa_constants(header_file_name, output_file_name):
+    collector = MacroCollector()
+    with open(header_file_name) as header_file:
+        collector.read_file(header_file)
+    temp_file_name = output_file_name + '.tmp'
+    with open(temp_file_name, 'w') as output_file:
+        collector.write_file(output_file)
+    os.rename(temp_file_name, output_file_name)
+
+if __name__ == '__main__':
+    if not os.path.isdir('programs') and os.path.isdir('../programs'):
+        os.chdir('..')
+    generate_psa_constants('include/psa/crypto.h',
+                           'programs/psa/psa_constant_names_generated.c')
diff --git a/tests/suites/test_suite_psa_crypto.data b/tests/suites/test_suite_psa_crypto.data
index 19348bd..894317e 100644
--- a/tests/suites/test_suite_psa_crypto.data
+++ b/tests/suites/test_suite_psa_crypto.data
@@ -85,6 +85,14 @@
 depends_on:MBEDTLS_PK_PARSE_C:MBEDTLS_RSA_C
 import:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b":PSA_KEY_TYPE_RSA_KEYPAIR:PSA_ERROR_INVALID_ARGUMENT
 
+PSA import RSA keypair: public key
+depends_on:MBEDTLS_PK_PARSE_C:MBEDTLS_RSA_C
+import:"30819f300d06092a864886f70d010101050003818d0030818902818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc30203010001":PSA_KEY_TYPE_RSA_KEYPAIR:PSA_ERROR_INVALID_ARGUMENT
+
+PSA import RSA public key: key pair
+depends_on:MBEDTLS_PK_PARSE_C:MBEDTLS_RSA_C
+import:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b":PSA_KEY_TYPE_RSA_PUBLIC_KEY:PSA_ERROR_INVALID_ARGUMENT
+
 PSA import RSA keypair: valid key but EC
 depends_on:MBEDTLS_PK_PARSE_C:MBEDTLS_RSA_C
 import:"3077020101042049c9a8c18c4b885638c431cf1df1c994131609b580d4fd43a0cab17db2f13eeea00a06082a8648ce3d030107a144034200047772656f814b399279d5e1f1781fac6f099a3c5ca1b0e35351834b08b65e0b572590cdaf8f769361bcf34acfc11e5e074e8426bdde04be6e653945449617de45":PSA_KEY_TYPE_RSA_KEYPAIR:PSA_ERROR_INVALID_ARGUMENT
@@ -97,7 +105,7 @@
 depends_on:MBEDTLS_PK_PARSE_C:MBEDTLS_PK_WRITE_C:MBEDTLS_RSA_C
 import_export_public_key:"30819f300d06092a864886f70d010101050003818d0030818902818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc30203010001":PSA_KEY_TYPE_RSA_PUBLIC_KEY:PSA_ALG_RSA_PKCS1V15_SIGN_RAW:1024:162:PSA_SUCCESS
 
-PSA import/export-public PSA keypair: good, 1024-bit
+PSA import/export-public RSA keypair: good, 1024-bit
 depends_on:MBEDTLS_PK_PARSE_C:MBEDTLS_PK_WRITE_C:MBEDTLS_RSA_C
 import_export_public_key:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":PSA_KEY_TYPE_RSA_KEYPAIR:PSA_ALG_RSA_PKCS1V15_SIGN_RAW:1024:162:PSA_SUCCESS
 
@@ -137,6 +145,18 @@
 depends_on:MBEDTLS_PK_PARSE_C:MBEDTLS_ECP_C:MBEDTLS_ECP_DP_BP384R1_ENABLED:MBEDTLS_ECP_DP_SECP384R1_ENABLED
 import:"3077020101042049c9a8c18c4b885638c431cf1df1c994131609b580d4fd43a0cab17db2f13eeea00a06082a8648ce3d030107a144034200047772656f814b399279d5e1f1781fac6f099a3c5ca1b0e35351834b08b65e0b572590cdaf8f769361bcf34acfc11e5e074e8426bdde04be6e653945449617de45":PSA_KEY_TYPE_ECC_KEYPAIR(PSA_ECC_CURVE_BRAINPOOL_P384R1):PSA_ERROR_INVALID_ARGUMENT
 
+PSA import EC keypair: public key
+depends_on:MBEDTLS_PK_PARSE_C:MBEDTLS_ECP_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED
+import:"3059301306072a8648ce3d020106082a8648ce3d03010703420004dea5e45d0ea37fc566232a508f4ad20ea13d47e4bf5fa4d54a57a0ba012042087097496efc583fed8b24a5b9be9a51de063f5a00a8b698a16fd7f29b5485f320":PSA_KEY_TYPE_ECC_KEYPAIR(PSA_ECC_CURVE_SECP256R1):PSA_ERROR_INVALID_ARGUMENT
+
+PSA import EC public key: key pair
+depends_on:MBEDTLS_PK_PARSE_C:MBEDTLS_ECP_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED
+# For consistency with ECpub as ECpair, RSApub as RSApair and RSApair as RSApub,
+# one would expect the status to be PSA_ERROR_INVALID_ARGUMENT. But the
+# Mbed TLS pkparse module returns MBEDTLS_ERR_PK_INVALID_ALG, I think because
+# it's looking for an OID where there is no OID.
+import:"3078020101042100ab45435712649cb30bbddac49197eebf2740ffc7f874d9244c3460f54f322d3aa00a06082a8648ce3d030107a14403420004dea5e45d0ea37fc566232a508f4ad20ea13d47e4bf5fa4d54a57a0ba012042087097496efc583fed8b24a5b9be9a51de063f5a00a8b698a16fd7f29b5485f320":PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_CURVE_SECP256R1):PSA_ERROR_NOT_SUPPORTED
+
 PSA import EC keypair: valid key but RSA
 depends_on:MBEDTLS_PK_PARSE_C:MBEDTLS_ECP_C:MBEDTLS_ECP_DP_BP512R1_ENABLED:MBEDTLS_RSA_C
 import:"3082013b020100024100ee2b131d6b1818a94ca8e91c42387eb15a7c271f57b89e7336b144d4535b16c83097ecdefbbb92d1b5313b5a37214d0e8f25922dca778b424b25295fc8a1a7070203010001024100978ac8eadb0dc6035347d6aba8671215ff21283385396f7897c04baf5e2a835f3b53ef80a82ed36ae687a925380b55a0c73eb85656e989dcf0ed7fb4887024e1022100fdad8e1c6853563f8b921d2d112462ae7d6b176082d2ba43e87e1a37fc1a8b33022100f0592cf4c55ba44307b18981bcdbda376c51e590ffa5345ba866f6962dca94dd02201995f1a967d44ff4a4cd1de837bc65bf97a2bf7eda730a9a62cea53254591105022027f96cf4b8ee68ff8d04062ec1ce7f18c0b74e4b3379b29f9bfea3fc8e592731022100cefa6d220496b43feb83194255d8fb930afcf46f36606e3aa0eb7a93ad88c10c":PSA_KEY_TYPE_ECC_KEYPAIR(PSA_ECC_CURVE_BRAINPOOL_P512R1):PSA_ERROR_INVALID_ARGUMENT
@@ -252,6 +272,18 @@
 depends_on:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V15
 asymmetric_signature_key_policy:0:PSA_ALG_RSA_PKCS1V15_SIGN_RAW:PSA_KEY_TYPE_RSA_KEYPAIR:"3082013b020100024100ee2b131d6b1818a94ca8e91c42387eb15a7c271f57b89e7336b144d4535b16c83097ecdefbbb92d1b5313b5a37214d0e8f25922dca778b424b25295fc8a1a7070203010001024100978ac8eadb0dc6035347d6aba8671215ff21283385396f7897c04baf5e2a835f3b53ef80a82ed36ae687a925380b55a0c73eb85656e989dcf0ed7fb4887024e1022100fdad8e1c6853563f8b921d2d112462ae7d6b176082d2ba43e87e1a37fc1a8b33022100f0592cf4c55ba44307b18981bcdbda376c51e590ffa5345ba866f6962dca94dd02201995f1a967d44ff4a4cd1de837bc65bf97a2bf7eda730a9a62cea53254591105022027f96cf4b8ee68ff8d04062ec1ce7f18c0b74e4b3379b29f9bfea3fc8e592731022100cefa6d220496b43feb83194255d8fb930afcf46f36606e3aa0eb7a93ad88c10c":PSA_ALG_RSA_PKCS1V15_SIGN_RAW
 
+PSA key policy: derive, permitted
+depends_on:MBEDTLS_MD_C:MBEDTLS_SHA256_C
+derive_key_policy:PSA_KEY_USAGE_DERIVE:PSA_ALG_HKDF(PSA_ALG_SHA_256):PSA_KEY_TYPE_DERIVE:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":PSA_ALG_HKDF(PSA_ALG_SHA_256)
+
+PSA key policy: derive, not permitted
+depends_on:MBEDTLS_MD_C:MBEDTLS_SHA256_C
+derive_key_policy:0:PSA_ALG_HKDF(PSA_ALG_SHA_256):PSA_KEY_TYPE_DERIVE:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":PSA_ALG_HKDF(PSA_ALG_SHA_256)
+
+PSA key policy: derive, wrong algorithm
+depends_on:MBEDTLS_MD_C:MBEDTLS_SHA256_C
+derive_key_policy:PSA_KEY_USAGE_DERIVE:PSA_ALG_HKDF(PSA_ALG_SHA_256):PSA_KEY_TYPE_DERIVE:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":PSA_ALG_HKDF(PSA_ALG_SHA_224)
+
 PSA key lifetime: set and get volatile
 key_lifetime:PSA_KEY_LIFETIME_VOLATILE
 
@@ -294,7 +326,7 @@
 
 PSA MAC setup: bad algorithm (unknown MAC algorithm)
 depends_on:MBEDTLS_MD_C
-mac_setup:PSA_KEY_TYPE_RAW_DATA:"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f":PSA_ALG_HMAC(0):PSA_ERROR_NOT_SUPPORTED
+mac_setup:PSA_KEY_TYPE_HMAC:"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f":PSA_ALG_HMAC(0):PSA_ERROR_NOT_SUPPORTED
 
 PSA MAC setup: bad algorithm (not a MAC algorithm)
 depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CBC
@@ -669,6 +701,10 @@
 depends_on:MBEDTLS_PK_PARSE_C:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V15:MBEDTLS_SHA256_C
 sign_fail:PSA_KEY_TYPE_RSA_KEYPAIR:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_SHA_256):"ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015":128:PSA_ERROR_INVALID_ARGUMENT
 
+PSA sign: RSA PKCS#1 v1.5 raw, input too large
+depends_on:MBEDTLS_PK_PARSE_C:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V15
+sign_fail:PSA_KEY_TYPE_RSA_KEYPAIR:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":PSA_ALG_RSA_PKCS1V15_SIGN_RAW:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":128:PSA_ERROR_INVALID_ARGUMENT
+
 PSA sign: RSA PKCS#1 v1.5 SHA-256, output buffer too small
 depends_on:MBEDTLS_PK_PARSE_C:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V15:MBEDTLS_SHA256_C
 sign_fail:PSA_KEY_TYPE_RSA_KEYPAIR:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_SHA_256):"ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad":127:PSA_ERROR_BUFFER_TOO_SMALL
@@ -681,69 +717,369 @@
 depends_on:MBEDTLS_PK_PARSE_C:MBEDTLS_ECP_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_ECDSA_DETERMINISTIC:MBEDTLS_SHA256_C
 sign_fail:PSA_KEY_TYPE_ECC_KEYPAIR(PSA_ECC_CURVE_SECP256R1):"3078020101042100ab45435712649cb30bbddac49197eebf2740ffc7f874d9244c3460f54f322d3aa00a06082a8648ce3d030107a14403420004dea5e45d0ea37fc566232a508f4ad20ea13d47e4bf5fa4d54a57a0ba012042087097496efc583fed8b24a5b9be9a51de063f5a00a8b698a16fd7f29b5485f320":PSA_ALG_DETERMINISTIC_ECDSA( 0 ):"9ac4335b469bbd791439248504dd0d49c71349a295fee5a1c68507f45a9e1c7b":72:PSA_ERROR_INVALID_ARGUMENT
 
+PSA sign/verify: RSA PKCS#1 v1.5, raw
+depends_on:MBEDTLS_PK_PARSE_C:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V15
+sign_verify:PSA_KEY_TYPE_RSA_KEYPAIR:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":PSA_ALG_RSA_PKCS1V15_SIGN_RAW:"616263"
+
+PSA sign/verify: RSA PKCS#1 v1.5 SHA-256
+depends_on:MBEDTLS_PK_PARSE_C:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V15:MBEDTLS_SHA256_C
+sign_verify:PSA_KEY_TYPE_RSA_KEYPAIR:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_SHA_256):"ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad"
+
+PSA sign/verify: RSA PSS SHA-256, 0 bytes
+depends_on:MBEDTLS_PK_PARSE_C:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V21:MBEDTLS_SHA256_C
+sign_verify:PSA_KEY_TYPE_RSA_KEYPAIR:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":PSA_ALG_RSA_PSS(PSA_ALG_SHA_256):""
+
+PSA sign/verify: RSA PSS SHA-256, 32 bytes (hash size)
+depends_on:MBEDTLS_PK_PARSE_C:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V21:MBEDTLS_SHA256_C
+sign_verify:PSA_KEY_TYPE_RSA_KEYPAIR:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":PSA_ALG_RSA_PSS(PSA_ALG_SHA_256):"ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad"
+
+PSA sign/verify: RSA PSS SHA-256, 129 bytes
+depends_on:MBEDTLS_PK_PARSE_C:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V21:MBEDTLS_SHA256_C
+sign_verify:PSA_KEY_TYPE_RSA_KEYPAIR:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":PSA_ALG_RSA_PSS(PSA_ALG_SHA_256):"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+
+PSA sign/verify: randomized ECDSA SECP256R1 SHA-256
+depends_on:MBEDTLS_PK_PARSE_C:MBEDTLS_ECP_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED
+sign_verify:PSA_KEY_TYPE_ECC_KEYPAIR(PSA_ECC_CURVE_SECP256R1):"3078020101042100ab45435712649cb30bbddac49197eebf2740ffc7f874d9244c3460f54f322d3aa00a06082a8648ce3d030107a14403420004dea5e45d0ea37fc566232a508f4ad20ea13d47e4bf5fa4d54a57a0ba012042087097496efc583fed8b24a5b9be9a51de063f5a00a8b698a16fd7f29b5485f320":PSA_ALG_ECDSA( PSA_ALG_SHA_256 ):"9ac4335b469bbd791439248504dd0d49c71349a295fee5a1c68507f45a9e1c7b"
+
+PSA sign/verify: deterministic ECDSA SECP256R1 SHA-256
+depends_on:MBEDTLS_PK_PARSE_C:MBEDTLS_ECP_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_ECDSA_DETERMINISTIC
+sign_verify:PSA_KEY_TYPE_ECC_KEYPAIR(PSA_ECC_CURVE_SECP256R1):"3078020101042100ab45435712649cb30bbddac49197eebf2740ffc7f874d9244c3460f54f322d3aa00a06082a8648ce3d030107a14403420004dea5e45d0ea37fc566232a508f4ad20ea13d47e4bf5fa4d54a57a0ba012042087097496efc583fed8b24a5b9be9a51de063f5a00a8b698a16fd7f29b5485f320":PSA_ALG_DETERMINISTIC_ECDSA( PSA_ALG_SHA_256 ):"9ac4335b469bbd791439248504dd0d49c71349a295fee5a1c68507f45a9e1c7b"
+
 PSA verify: RSA PKCS#1 v1.5 SHA-256, good signature
 depends_on:MBEDTLS_PK_PARSE_C:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V15:MBEDTLS_SHA256_C
+asymmetric_verify:PSA_KEY_TYPE_RSA_PUBLIC_KEY:"30819f300d06092a864886f70d010101050003818d0030818902818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc30203010001":PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_SHA_256):"ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad":"a73664d55b39c7ea6c1e5b5011724a11e1d7073d3a68f48c836fad153a1d91b6abdbc8f69da13b206cc96af6363b114458b026af14b24fab8929ed634c6a2acace0bcc62d9bb6a984afbcbfcd3a0608d32a2bae535b9cd1ecdf9dd281db1e0025c3bfb5512963ec3b98ddaa69e38bc3c84b1b61a04e5648640856aacc6fc7311"
+
+PSA verify with keypair: RSA PKCS#1 v1.5 SHA-256, good signature
+depends_on:MBEDTLS_PK_PARSE_C:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V15:MBEDTLS_SHA256_C
 asymmetric_verify:PSA_KEY_TYPE_RSA_KEYPAIR:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_SHA_256):"ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad":"a73664d55b39c7ea6c1e5b5011724a11e1d7073d3a68f48c836fad153a1d91b6abdbc8f69da13b206cc96af6363b114458b026af14b24fab8929ed634c6a2acace0bcc62d9bb6a984afbcbfcd3a0608d32a2bae535b9cd1ecdf9dd281db1e0025c3bfb5512963ec3b98ddaa69e38bc3c84b1b61a04e5648640856aacc6fc7311"
 
 PSA verify: RSA PKCS#1 v1.5 SHA-256, wrong hash
 depends_on:MBEDTLS_PK_PARSE_C:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V15:MBEDTLS_SHA1_C
-asymmetric_verify_fail:PSA_KEY_TYPE_RSA_KEYPAIR:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_SHA_1):"ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad":"a73664d55b39c7ea6c1e5b5011724a11e1d7073d3a68f48c836fad153a1d91b6abdbc8f69da13b206cc96af6363b114458b026af14b24fab8929ed634c6a2acace0bcc62d9bb6a984afbcbfcd3a0608d32a2bae535b9cd1ecdf9dd281db1e0025c3bfb5512963ec3b98ddaa69e38bc3c84b1b61a04e5648640856aacc6fc7311":PSA_ERROR_INVALID_ARGUMENT
+asymmetric_verify_fail:PSA_KEY_TYPE_RSA_PUBLIC_KEY:"30819f300d06092a864886f70d010101050003818d0030818902818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc30203010001":PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_SHA_1):"ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad":"a73664d55b39c7ea6c1e5b5011724a11e1d7073d3a68f48c836fad153a1d91b6abdbc8f69da13b206cc96af6363b114458b026af14b24fab8929ed634c6a2acace0bcc62d9bb6a984afbcbfcd3a0608d32a2bae535b9cd1ecdf9dd281db1e0025c3bfb5512963ec3b98ddaa69e38bc3c84b1b61a04e5648640856aacc6fc7311":PSA_ERROR_INVALID_ARGUMENT
 
 PSA verify: RSA PKCS#1 v1.5 SHA-256, wrong signature
 depends_on:MBEDTLS_PK_PARSE_C:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V15:MBEDTLS_SHA256_C
-asymmetric_verify_fail:PSA_KEY_TYPE_RSA_KEYPAIR:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_SHA_256):"ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad":"111164d55b39c7ea6c1e5b5011724a11e1d7073d3a68f48c836fad153a1d91b6abdbc8f69da13b206cc96af6363b114458b026af14b24fab8929ed634c6a2acace0bcc62d9bb6a984afbcbfcd3a0608d32a2bae535b9cd1ecdf9dd281db1e0025c3bfb5512963ec3b98ddaa69e38bc3c84b1b61a04e5648640856aacc6fc7311":PSA_ERROR_INVALID_SIGNATURE
+asymmetric_verify_fail:PSA_KEY_TYPE_RSA_PUBLIC_KEY:"30819f300d06092a864886f70d010101050003818d0030818902818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc30203010001":PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_SHA_256):"ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad":"111164d55b39c7ea6c1e5b5011724a11e1d7073d3a68f48c836fad153a1d91b6abdbc8f69da13b206cc96af6363b114458b026af14b24fab8929ed634c6a2acace0bcc62d9bb6a984afbcbfcd3a0608d32a2bae535b9cd1ecdf9dd281db1e0025c3bfb5512963ec3b98ddaa69e38bc3c84b1b61a04e5648640856aacc6fc7311":PSA_ERROR_INVALID_SIGNATURE
+
+PSA verify: RSA PSS SHA-256, good signature, 0 bytes
+depends_on:MBEDTLS_PK_PARSE_C:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V21:MBEDTLS_SHA256_C
+asymmetric_verify:PSA_KEY_TYPE_RSA_PUBLIC_KEY:"30819f300d06092a864886f70d010101050003818d0030818902818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc30203010001":PSA_ALG_RSA_PSS(PSA_ALG_SHA_256):"":"34c011b625c32d992f4ab8fcfa52b616ea66270b5b75a4fc71af712f9b8806bcdd374ce50eafcbb489562b93347885f93c2de1d404c45cacccefceb112ff6ffdfe4264f91d66320bbbe09304b851b8ad6280bbccc571eebcd49c7db5dfa399a6289e1978407904598751613d9870770cdd8507e3dc7b46851dbf05ae1df2988d"
+
+PSA verify: RSA PSS SHA-256, good signature, 32 bytes (hash size)
+depends_on:MBEDTLS_PK_PARSE_C:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V21:MBEDTLS_SHA256_C
+asymmetric_verify:PSA_KEY_TYPE_RSA_PUBLIC_KEY:"30819f300d06092a864886f70d010101050003818d0030818902818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc30203010001":PSA_ALG_RSA_PSS(PSA_ALG_SHA_256):"ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad":"1967ae568cc071dfebeeca76b11d40bd1ec5af241c50b3dcceff21f4536c0693a7179a8d5d163a7625fefd37c161127800edeebc24fa73ca772096827bd3f75e8ccf2c64f07b7171b5c99022a4d73b760f34a385ccff0bd5ed7997d2a29d2847acb0767f93a2a404bc046c97de66d95dc9f7646fdb216b627b2ea0de8afcefb7"
+
+PSA verify: RSA PSS SHA-256, good signature, 129 bytes
+depends_on:MBEDTLS_PK_PARSE_C:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V21:MBEDTLS_SHA256_C
+asymmetric_verify:PSA_KEY_TYPE_RSA_PUBLIC_KEY:"30819f300d06092a864886f70d010101050003818d0030818902818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc30203010001":PSA_ALG_RSA_PSS(PSA_ALG_SHA_256):"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":"1491cead330b4ad5b092f8351518141ac11d0888591572669c1e79d6e932c488acd62d44479b0e14cd91a048778bc02398a772ad6bdb4f7764780cf0afe70293d0cac86f2695a1dcb54568bb37d7086f9e86f95a6802d2ee5a4facaa762beff5261bb2816b62cb5af86404974c3f6b67985ac1fbfdf46d6de54f6e29d9274308"
 
 PSA verify: ECDSA SECP256R1, good
+depends_on:MBEDTLS_PK_PARSE_C:MBEDTLS_ECP_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_SHA256_C
+asymmetric_verify:PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_CURVE_SECP256R1):"3059301306072a8648ce3d020106082a8648ce3d03010703420004dea5e45d0ea37fc566232a508f4ad20ea13d47e4bf5fa4d54a57a0ba012042087097496efc583fed8b24a5b9be9a51de063f5a00a8b698a16fd7f29b5485f320":PSA_ALG_ECDSA_ANY:"9ac4335b469bbd791439248504dd0d49c71349a295fee5a1c68507f45a9e1c7b":"6a3399f69421ffe1490377adf2ea1f117d81a63cf5bf22e918d51175eb259151ce95d7c26cc04e25503e2f7a1ec3573e3c2412534bb4a19b3a7811742f49f50f"
+
+PSA verify with keypair: ECDSA SECP256R1, good
 depends_on:MBEDTLS_PK_PARSE_C:MBEDTLS_ECP_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED
 asymmetric_verify:PSA_KEY_TYPE_ECC_KEYPAIR(PSA_ECC_CURVE_SECP256R1):"3078020101042100ab45435712649cb30bbddac49197eebf2740ffc7f874d9244c3460f54f322d3aa00a06082a8648ce3d030107a14403420004dea5e45d0ea37fc566232a508f4ad20ea13d47e4bf5fa4d54a57a0ba012042087097496efc583fed8b24a5b9be9a51de063f5a00a8b698a16fd7f29b5485f320":PSA_ALG_ECDSA_ANY:"9ac4335b469bbd791439248504dd0d49c71349a295fee5a1c68507f45a9e1c7b":"6a3399f69421ffe1490377adf2ea1f117d81a63cf5bf22e918d51175eb259151ce95d7c26cc04e25503e2f7a1ec3573e3c2412534bb4a19b3a7811742f49f50f"
 
 PSA verify: ECDSA SECP256R1, wrong signature size (correct but ASN1-encoded)
 depends_on:MBEDTLS_PK_PARSE_C:MBEDTLS_ECP_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED
-asymmetric_verify_fail:PSA_KEY_TYPE_ECC_KEYPAIR(PSA_ECC_CURVE_SECP256R1):"3078020101042100ab45435712649cb30bbddac49197eebf2740ffc7f874d9244c3460f54f322d3aa00a06082a8648ce3d030107a14403420004dea5e45d0ea37fc566232a508f4ad20ea13d47e4bf5fa4d54a57a0ba012042087097496efc583fed8b24a5b9be9a51de063f5a00a8b698a16fd7f29b5485f320":PSA_ALG_ECDSA_ANY:"9ac4335b469bbd791439248504dd0d49c71349a295fee5a1c68507f45a9e1c7b":"304502206a3399f69421ffe1490377adf2ea1f117d81a63cf5bf22e918d51175eb259151022100ce95d7c26cc04e25503e2f7a1ec3573e3c2412534bb4a19b3a7811742f49f50f":PSA_ERROR_INVALID_SIGNATURE
+asymmetric_verify_fail:PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_CURVE_SECP256R1):"3059301306072a8648ce3d020106082a8648ce3d03010703420004dea5e45d0ea37fc566232a508f4ad20ea13d47e4bf5fa4d54a57a0ba012042087097496efc583fed8b24a5b9be9a51de063f5a00a8b698a16fd7f29b5485f320":PSA_ALG_ECDSA_ANY:"9ac4335b469bbd791439248504dd0d49c71349a295fee5a1c68507f45a9e1c7b":"304502206a3399f69421ffe1490377adf2ea1f117d81a63cf5bf22e918d51175eb259151022100ce95d7c26cc04e25503e2f7a1ec3573e3c2412534bb4a19b3a7811742f49f50f":PSA_ERROR_INVALID_SIGNATURE
 
 PSA verify: ECDSA SECP256R1, wrong signature of correct size
 depends_on:MBEDTLS_PK_PARSE_C:MBEDTLS_ECP_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED
-asymmetric_verify_fail:PSA_KEY_TYPE_ECC_KEYPAIR(PSA_ECC_CURVE_SECP256R1):"3078020101042100ab45435712649cb30bbddac49197eebf2740ffc7f874d9244c3460f54f322d3aa00a06082a8648ce3d030107a14403420004dea5e45d0ea37fc566232a508f4ad20ea13d47e4bf5fa4d54a57a0ba012042087097496efc583fed8b24a5b9be9a51de063f5a00a8b698a16fd7f29b5485f320":PSA_ALG_ECDSA_ANY:"9ac4335b469bbd791439248504dd0d49c71349a295fee5a1c68507f45a9e1c7b":"6a3399f69421ffe1490377adf2ea1f117d81a63cf5bf22e918d51175eb259151ce95d7c26cc04e25503e2f7a1ec3573e3c2412534bb4a19b3a7811742f49f50e":PSA_ERROR_INVALID_SIGNATURE
+asymmetric_verify_fail:PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_CURVE_SECP256R1):"3059301306072a8648ce3d020106082a8648ce3d03010703420004dea5e45d0ea37fc566232a508f4ad20ea13d47e4bf5fa4d54a57a0ba012042087097496efc583fed8b24a5b9be9a51de063f5a00a8b698a16fd7f29b5485f320":PSA_ALG_ECDSA_ANY:"9ac4335b469bbd791439248504dd0d49c71349a295fee5a1c68507f45a9e1c7b":"6a3399f69421ffe1490377adf2ea1f117d81a63cf5bf22e918d51175eb259151ce95d7c26cc04e25503e2f7a1ec3573e3c2412534bb4a19b3a7811742f49f50e":PSA_ERROR_INVALID_SIGNATURE
 
-PSA encrypt-decrypt: RSA PKCS#1 v1.5 vector #1
+PSA encrypt: RSA PKCS#1 v1.5, good
 depends_on:MBEDTLS_PK_PARSE_C:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V15
-asymmetric_encrypt_decrypt:PSA_KEY_TYPE_RSA_KEYPAIR:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":PSA_ALG_RSA_PKCS1V15_CRYPT:"ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad"
+asymmetric_encrypt:PSA_KEY_TYPE_RSA_PUBLIC_KEY:"30819f300d06092a864886f70d010101050003818d0030818902818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc30203010001":PSA_ALG_RSA_PKCS1V15_CRYPT:"ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad":"":128:PSA_SUCCESS
 
-PSA encrypt-decrypt: RSA PKCS#1 v1.5 vector #2
+PSA encrypt: RSA OAEP-SHA-256, good
+depends_on:MBEDTLS_PK_PARSE_C:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V21:MBEDTLS_SHA256_C
+asymmetric_encrypt:PSA_KEY_TYPE_RSA_PUBLIC_KEY:"30819f300d06092a864886f70d010101050003818d0030818902818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc30203010001":PSA_ALG_RSA_OAEP(PSA_ALG_SHA_256):"ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad":"":128:PSA_SUCCESS
+
+PSA encrypt: RSA OAEP-SHA-256, good, with label
+depends_on:MBEDTLS_PK_PARSE_C:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V21:MBEDTLS_SHA256_C
+asymmetric_encrypt:PSA_KEY_TYPE_RSA_PUBLIC_KEY:"30819f300d06092a864886f70d010101050003818d0030818902818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc30203010001":PSA_ALG_RSA_OAEP(PSA_ALG_SHA_256):"ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad":"746869730069730061006c6162656c00":128:PSA_SUCCESS
+
+PSA encrypt: RSA OAEP-SHA-384, good
+depends_on:MBEDTLS_PK_PARSE_C:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V21:MBEDTLS_SHA512_C
+asymmetric_encrypt:PSA_KEY_TYPE_RSA_PUBLIC_KEY:"30819f300d06092a864886f70d010101050003818d0030818902818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc30203010001":PSA_ALG_RSA_OAEP(PSA_ALG_SHA_384):"0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e":"":128:PSA_SUCCESS
+
+PSA encrypt: RSA OAEP-SHA-384, good
+depends_on:MBEDTLS_PK_PARSE_C:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V21:MBEDTLS_SHA512_C
+asymmetric_encrypt:PSA_KEY_TYPE_RSA_PUBLIC_KEY:"30819f300d06092a864886f70d010101050003818d0030818902818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc30203010001":PSA_ALG_RSA_OAEP(PSA_ALG_SHA_384):"0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e":"":128:PSA_SUCCESS
+
+PSA encrypt: RSA PKCS#1 v1.5, key pair
 depends_on:MBEDTLS_PK_PARSE_C:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V15
-asymmetric_encrypt_decrypt:PSA_KEY_TYPE_RSA_KEYPAIR:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":PSA_ALG_RSA_PKCS1V15_CRYPT:"99e8a6144bcb9a29660303bdc4305bb5eca8c64b96788cad062be9967bdab2f7ffff"
+asymmetric_encrypt:PSA_KEY_TYPE_RSA_KEYPAIR:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":PSA_ALG_RSA_PKCS1V15_CRYPT:"ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad":"":128:PSA_SUCCESS
+
+PSA encrypt: RSA OAEP-SHA-256, key pair
+depends_on:MBEDTLS_PK_PARSE_C:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V21:MBEDTLS_SHA256_C
+asymmetric_encrypt:PSA_KEY_TYPE_RSA_KEYPAIR:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":PSA_ALG_RSA_OAEP(PSA_ALG_SHA_256):"ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad":"":128:PSA_SUCCESS
+
+PSA encrypt: RSA PKCS#1 v1.5, input too large
+depends_on:MBEDTLS_PK_PARSE_C:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V15
+asymmetric_encrypt:PSA_KEY_TYPE_RSA_PUBLIC_KEY:"30819f300d06092a864886f70d010101050003818d0030818902818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc30203010001":PSA_ALG_RSA_PKCS1V15_CRYPT:"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff":"":0:PSA_ERROR_INVALID_ARGUMENT
+
+PSA encrypt: RSA PKCS#1 v1.5: salt not allowed
+depends_on:MBEDTLS_PK_PARSE_C:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V15
+asymmetric_encrypt:PSA_KEY_TYPE_RSA_PUBLIC_KEY:"30819f300d06092a864886f70d010101050003818d0030818902818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc30203010001":PSA_ALG_RSA_PKCS1V15_CRYPT:"ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad":"eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee":0:PSA_ERROR_INVALID_ARGUMENT
+
+PSA encrypt: RSA OAEP-SHA-384, input too large
+depends_on:MBEDTLS_PK_PARSE_C:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V21:MBEDTLS_SHA512_C
+asymmetric_encrypt:PSA_KEY_TYPE_RSA_PUBLIC_KEY:"30819f300d06092a864886f70d010101050003818d0030818902818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc30203010001":PSA_ALG_RSA_OAEP(PSA_ALG_SHA_384):"0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f":"":0:PSA_ERROR_INVALID_ARGUMENT
 
 PSA encrypt: invalid algorithm
 depends_on:MBEDTLS_PK_PARSE_C:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V15
-asymmetric_encrypt_fail:PSA_KEY_TYPE_RSA_KEYPAIR:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":PSA_ALG_SHA_256:"ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad":PSA_ERROR_INVALID_ARGUMENT
+asymmetric_encrypt:PSA_KEY_TYPE_RSA_PUBLIC_KEY:"30819f300d06092a864886f70d010101050003818d0030818902818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc30203010001":PSA_ALG_SHA_256:"ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad":"":0:PSA_ERROR_INVALID_ARGUMENT
 
 PSA encrypt: RSA PKCS#1 v1.5: invalid key type
 depends_on:MBEDTLS_PK_PARSE_C:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V15
-asymmetric_encrypt_fail:PSA_KEY_TYPE_AES:"3082025e02010002818100af057d396e":PSA_ALG_RSA_PKCS1V15_CRYPT:"ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad":PSA_ERROR_INVALID_ARGUMENT
+asymmetric_encrypt:PSA_KEY_TYPE_AES:"3082025e02010002818100af057d396e":PSA_ALG_RSA_PKCS1V15_CRYPT:"ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad":"":0:PSA_ERROR_INVALID_ARGUMENT
+
+PSA encrypt-decrypt: RSA PKCS#1 v1.5 vector #1
+depends_on:MBEDTLS_PK_PARSE_C:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V15
+asymmetric_encrypt_decrypt:PSA_KEY_TYPE_RSA_KEYPAIR:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":PSA_ALG_RSA_PKCS1V15_CRYPT:"ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad":""
+
+PSA encrypt-decrypt: RSA PKCS#1 v1.5 vector #2
+depends_on:MBEDTLS_PK_PARSE_C:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V15
+asymmetric_encrypt_decrypt:PSA_KEY_TYPE_RSA_KEYPAIR:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":PSA_ALG_RSA_PKCS1V15_CRYPT:"99e8a6144bcb9a29660303bdc4305bb5eca8c64b96788cad062be9967bdab2f7ffff":""
+
+PSA encrypt-decrypt: RSA OAEP-SHA-256
+depends_on:MBEDTLS_PK_PARSE_C:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V21:MBEDTLS_SHA256_C
+asymmetric_encrypt_decrypt:PSA_KEY_TYPE_RSA_KEYPAIR:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":PSA_ALG_RSA_OAEP(PSA_ALG_SHA_256):"ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad":""
+
+PSA encrypt-decrypt: RSA OAEP-SHA-256, with label
+depends_on:MBEDTLS_PK_PARSE_C:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V21:MBEDTLS_SHA256_C
+asymmetric_encrypt_decrypt:PSA_KEY_TYPE_RSA_KEYPAIR:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":PSA_ALG_RSA_OAEP(PSA_ALG_SHA_256):"ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad":"746869730069730061006c6162656c00"
+
+PSA encrypt-decrypt: RSA OAEP-SHA-384
+depends_on:MBEDTLS_PK_PARSE_C:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V21:MBEDTLS_SHA512_C
+asymmetric_encrypt_decrypt:PSA_KEY_TYPE_RSA_KEYPAIR:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":PSA_ALG_RSA_OAEP(PSA_ALG_SHA_384):"0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e":""
 
 PSA decrypt: RSA PKCS#1 v1.5: good #1
 depends_on:MBEDTLS_PK_PARSE_C:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V15
-asymmetric_decrypt:PSA_KEY_TYPE_RSA_KEYPAIR:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":PSA_ALG_RSA_PKCS1V15_CRYPT:"99ffde2fcc00c9cc01972ebfa7779b298dbbaf7f50707a7405296dd2783456fc792002f462e760500e02afa25a859ace8701cb5d3b0262116431c43af8eb08f5a88301057cf1c156a2a5193c143e7a5b03fac132b7e89e6dcd8f4c82c9b28452329c260d30bc39b3816b7c46b41b37b4850d2ae74e729f99c6621fbbe2e46872":"ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad":32
+asymmetric_decrypt:PSA_KEY_TYPE_RSA_KEYPAIR:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":PSA_ALG_RSA_PKCS1V15_CRYPT:"99ffde2fcc00c9cc01972ebfa7779b298dbbaf7f50707a7405296dd2783456fc792002f462e760500e02afa25a859ace8701cb5d3b0262116431c43af8eb08f5a88301057cf1c156a2a5193c143e7a5b03fac132b7e89e6dcd8f4c82c9b28452329c260d30bc39b3816b7c46b41b37b4850d2ae74e729f99c6621fbbe2e46872":"":"ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad"
 
 PSA decrypt: RSA PKCS#1 v1.5: good #2
 depends_on:MBEDTLS_PK_PARSE_C:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V15
-asymmetric_decrypt:PSA_KEY_TYPE_RSA_KEYPAIR:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":PSA_ALG_RSA_PKCS1V15_CRYPT:"adeecba2db7f867a733853f0136c554e5e01c7a2015721a9bfe30c3ad163b93a9c7589170311209f91420ad8a1a8280c7e890a6d7bca3c500b4da4f53a17bd84a21d58f979a9b4b8f2246b482d930804f12b3aeb2ac8b5ac7938d452ca13be8eb8e973c4e2b19fd454058cbae037bcef7ef68a5fbabf050de5f283cf1998c695":"99e8a6144bcb9a29660303bdc4305bb5eca8c64b96788cad062be9967bdab2f7ffff":34
+asymmetric_decrypt:PSA_KEY_TYPE_RSA_KEYPAIR:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":PSA_ALG_RSA_PKCS1V15_CRYPT:"adeecba2db7f867a733853f0136c554e5e01c7a2015721a9bfe30c3ad163b93a9c7589170311209f91420ad8a1a8280c7e890a6d7bca3c500b4da4f53a17bd84a21d58f979a9b4b8f2246b482d930804f12b3aeb2ac8b5ac7938d452ca13be8eb8e973c4e2b19fd454058cbae037bcef7ef68a5fbabf050de5f283cf1998c695":"":"99e8a6144bcb9a29660303bdc4305bb5eca8c64b96788cad062be9967bdab2f7ffff"
+
+PSA decrypt: RSA OAEP-SHA-256, 0 bytes
+depends_on:MBEDTLS_PK_PARSE_C:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V21:MBEDTLS_SHA256_C
+asymmetric_decrypt:PSA_KEY_TYPE_RSA_KEYPAIR:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":PSA_ALG_RSA_OAEP(PSA_ALG_SHA_256):"3d3146b1c982004273a9ebb9b063e6ae53b1a85bfc802324bcdd04faa0f7211fb2bdeea40358095554df9c250866c7361e738f0d270eaa27738e87928c5e31815506346727900ff03cef0be6f9dd6bba63ce89074e8194fe68b5a5739422d4f138bbbb61f49b76cf1f18def2c993e3113b08c191ea1da0feb94f8fd9b30109a1":"":""
+
+PSA decrypt: RSA OAEP-SHA-256, 0 bytes, with label
+depends_on:MBEDTLS_PK_PARSE_C:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V21:MBEDTLS_SHA256_C
+asymmetric_decrypt:PSA_KEY_TYPE_RSA_KEYPAIR:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":PSA_ALG_RSA_OAEP(PSA_ALG_SHA_256):"14e57648fbbd3c2c195d71fcb9b6c332e2ad9e3402aa701e7270b05775e9ddd025e2330d7b84e67866524c67f9c38b11e4679e28a38574b47f8d218a1a04a7466754d6ea7f959ab1f5b85d066d3f90076e8219f66653f7b78a9789d76213505b4e75ec28081608ed2f1ea1238e3eeab011ce4ec147327cd0ca029c2818133cb6":"746869730069730061006c6162656c00":""
+
+PSA decrypt: RSA OAEP-SHA-256, 30 bytes
+depends_on:MBEDTLS_PK_PARSE_C:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V21:MBEDTLS_SHA256_C
+asymmetric_decrypt:PSA_KEY_TYPE_RSA_KEYPAIR:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":PSA_ALG_RSA_OAEP(PSA_ALG_SHA_256):"3fd3c81e3919a19014400d91098090f273312e0150e09eff7f66fb9624d2ec9764fc80befcb592e9d102493c882b8bc0334a257e73aba23a0ee13f826cbc64f8200b9150784d004ccb2955c877c95ab888e3917f423dd52f3c8a49cb61c1966ec04f336068729ae0bce7d7fb3e680f9d15d658db9b906efcbf2c2fae45e75429":"":"74686973206973206e6f2073717565616d697368206f7373696672616765"
+
+PSA decrypt: RSA OAEP-SHA-256, 30 bytes, with label
+depends_on:MBEDTLS_PK_PARSE_C:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V21:MBEDTLS_SHA256_C
+asymmetric_decrypt:PSA_KEY_TYPE_RSA_KEYPAIR:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":PSA_ALG_RSA_OAEP(PSA_ALG_SHA_256):"46edc9984a6d4b7c7fd88fda9ea91ddbd30b28a0793cc75a9fcdd94d867c69090a697d46a6f336a3e48a122dd3ee3b51566b445ff78adb613d09b7d8c59c25a27d8cf7f5e36455f2e71ff6c6ee98d5740e66b23794acc72906561951c2be5064f6a250646ab627ecbfa48c02f82c29fe9b8c8e6be8eb752432124974373b542c":"746869730069730061006c6162656c00":"74686973206973206e6f2073717565616d697368206f7373696672616765"
+
+PSA decrypt: RSA OAEP-SHA-384, 30 bytes
+depends_on:MBEDTLS_PK_PARSE_C:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V21:MBEDTLS_SHA512_C
+asymmetric_decrypt:PSA_KEY_TYPE_RSA_KEYPAIR:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":PSA_ALG_RSA_OAEP(PSA_ALG_SHA_384):"0df6750b8fed749359c016887d2cf097cc512c065526a91a7ee9b345a1bfff833737e7326e54d03f6bb65971962885a7661a16858d53ea55821052f4c7798d395b5c5495332fd4174451a1a437f36c27f446b96f309ff1cb6837274aa8ae2b51a8a479d736d25b8d2ca8ab96fe589553a3e52818b7df75544eb5469977b29aa4":"":"74686973206973206e6f2073717565616d697368206f7373696672616765"
+
+PSA decrypt: RSA OAEP-SHA-256, 30 bytes, wrong label (should be empty)
+depends_on:MBEDTLS_PK_PARSE_C:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V21:MBEDTLS_SHA256_C
+asymmetric_decrypt_fail:PSA_KEY_TYPE_RSA_KEYPAIR:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":PSA_ALG_RSA_OAEP(PSA_ALG_SHA_256):"3fd3c81e3919a19014400d91098090f273312e0150e09eff7f66fb9624d2ec9764fc80befcb592e9d102493c882b8bc0334a257e73aba23a0ee13f826cbc64f8200b9150784d004ccb2955c877c95ab888e3917f423dd52f3c8a49cb61c1966ec04f336068729ae0bce7d7fb3e680f9d15d658db9b906efcbf2c2fae45e75429":"00":PSA_ERROR_INVALID_PADDING
+
+PSA decrypt: RSA OAEP-SHA-256, 30 bytes, wrong label (empty)
+depends_on:MBEDTLS_PK_PARSE_C:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V21:MBEDTLS_SHA256_C
+asymmetric_decrypt_fail:PSA_KEY_TYPE_RSA_KEYPAIR:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":PSA_ALG_RSA_OAEP(PSA_ALG_SHA_256):"46edc9984a6d4b7c7fd88fda9ea91ddbd30b28a0793cc75a9fcdd94d867c69090a697d46a6f336a3e48a122dd3ee3b51566b445ff78adb613d09b7d8c59c25a27d8cf7f5e36455f2e71ff6c6ee98d5740e66b23794acc72906561951c2be5064f6a250646ab627ecbfa48c02f82c29fe9b8c8e6be8eb752432124974373b542c":"":PSA_ERROR_INVALID_PADDING
+
+PSA decrypt: RSA OAEP-SHA-256, 30 bytes, wrong label (same length)
+depends_on:MBEDTLS_PK_PARSE_C:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V21:MBEDTLS_SHA256_C
+asymmetric_decrypt_fail:PSA_KEY_TYPE_RSA_KEYPAIR:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":PSA_ALG_RSA_OAEP(PSA_ALG_SHA_256):"46edc9984a6d4b7c7fd88fda9ea91ddbd30b28a0793cc75a9fcdd94d867c69090a697d46a6f336a3e48a122dd3ee3b51566b445ff78adb613d09b7d8c59c25a27d8cf7f5e36455f2e71ff6c6ee98d5740e66b23794acc72906561951c2be5064f6a250646ab627ecbfa48c02f82c29fe9b8c8e6be8eb752432124974373b542c":"746869730069730061006c6162656c01":PSA_ERROR_INVALID_PADDING
+
+PSA decrypt: RSA PKCS#1 v1.5, invalid padding
+depends_on:MBEDTLS_PK_PARSE_C:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V15
+asymmetric_decrypt_fail:PSA_KEY_TYPE_RSA_KEYPAIR:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":PSA_ALG_RSA_PKCS1V15_CRYPT:"99ffde2fcc00c9cc01972ebfa7779b298dbbaf7f50707a7405296dd2783456fc792002f462e760500e02afa25a859ace8701cb5d3b0262116431c43af8eb08f5a88301057cf1c156a2a5193c143e7a5b03fac132b7e89e6dcd8f4c82c9b28452329c260d30bc39b3816b7c46b41b37b4850d2ae74e729f99c6621fbbe2e46873":"":PSA_ERROR_INVALID_PADDING
+
+PSA decrypt: RSA PKCS#1 v1.5: salt not allowed
+depends_on:MBEDTLS_PK_PARSE_C:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V15
+asymmetric_decrypt_fail:PSA_KEY_TYPE_RSA_KEYPAIR:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":PSA_ALG_RSA_PKCS1V15_CRYPT:"99ffde2fcc00c9cc01972ebfa7779b298dbbaf7f50707a7405296dd2783456fc792002f462e760500e02afa25a859ace8701cb5d3b0262116431c43af8eb08f5a88301057cf1c156a2a5193c143e7a5b03fac132b7e89e6dcd8f4c82c9b28452329c260d30bc39b3816b7c46b41b37b4850d2ae74e729f99c6621fbbe2e46872":"eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee":PSA_ERROR_INVALID_ARGUMENT
+
+PSA decrypt: RSA OAEP-SHA-256, invalid padding
+depends_on:MBEDTLS_PK_PARSE_C:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V21:MBEDTLS_SHA256_C
+asymmetric_decrypt_fail:PSA_KEY_TYPE_RSA_KEYPAIR:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":PSA_ALG_RSA_OAEP(PSA_ALG_SHA_256):"3fd3c81e3919a19014400d91098090f273312e0150e09eff7f66fb9624d2ec9764fc80befcb592e9d102493c882b8bc0334a257e73aba23a0ee13f826cbc64f8200b9150784d004ccb2955c877c95ab888e3917f423dd52f3c8a49cb61c1966ec04f336068729ae0bce7d7fb3e680f9d15d658db9b906efcbf2c2fae45e75428":"":PSA_ERROR_INVALID_PADDING
 
 PSA decrypt: invalid algorithm
 depends_on:MBEDTLS_PK_PARSE_C:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V15
-asymmetric_decrypt_fail:PSA_KEY_TYPE_RSA_KEYPAIR:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":PSA_ALG_SHA_256:"ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad":PSA_ERROR_INVALID_ARGUMENT
+asymmetric_decrypt_fail:PSA_KEY_TYPE_RSA_KEYPAIR:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":PSA_ALG_SHA_256:"adeecba2db7f867a733853f0136c554e5e01c7a2015721a9bfe30c3ad163b93a9c7589170311209f91420ad8a1a8280c7e890a6d7bca3c500b4da4f53a17bd84a21d58f979a9b4b8f2246b482d930804f12b3aeb2ac8b5ac7938d452ca13be8eb8e973c4e2b19fd454058cbae037bcef7ef68a5fbabf050de5f283cf1998c695":"":PSA_ERROR_INVALID_ARGUMENT
 
-PSA decrypt: RSA PKCS#1 v1.5: invalid key type
+PSA decrypt: RSA PKCS#1 v1.5, invalid key type (RSA public key)
 depends_on:MBEDTLS_PK_PARSE_C:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V15
-asymmetric_decrypt_fail:PSA_KEY_TYPE_AES:"3082025e02010002818100af057d396e":PSA_ALG_RSA_PKCS1V15_CRYPT:"ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad":PSA_ERROR_INVALID_ARGUMENT
+asymmetric_decrypt_fail:PSA_KEY_TYPE_RSA_PUBLIC_KEY:"30819f300d06092a864886f70d010101050003818d0030818902818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc30203010001":PSA_ALG_RSA_PKCS1V15_CRYPT:"adeecba2db7f867a733853f0136c554e5e01c7a2015721a9bfe30c3ad163b93a9c7589170311209f91420ad8a1a8280c7e890a6d7bca3c500b4da4f53a17bd84a21d58f979a9b4b8f2246b482d930804f12b3aeb2ac8b5ac7938d452ca13be8eb8e973c4e2b19fd454058cbae037bcef7ef68a5fbabf050de5f283cf1998c695":"":PSA_ERROR_INVALID_ARGUMENT
+
+PSA decrypt: RSA OAEP, invalid key type (RSA public key)
+depends_on:MBEDTLS_PK_PARSE_C:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V21:MBEDTLS_SHA256_C
+asymmetric_decrypt_fail:PSA_KEY_TYPE_RSA_PUBLIC_KEY:"30819f300d06092a864886f70d010101050003818d0030818902818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc30203010001":PSA_ALG_RSA_OAEP(PSA_ALG_SHA_256):"adeecba2db7f867a733853f0136c554e5e01c7a2015721a9bfe30c3ad163b93a9c7589170311209f91420ad8a1a8280c7e890a6d7bca3c500b4da4f53a17bd84a21d58f979a9b4b8f2246b482d930804f12b3aeb2ac8b5ac7938d452ca13be8eb8e973c4e2b19fd454058cbae037bcef7ef68a5fbabf050de5f283cf1998c695":"":PSA_ERROR_INVALID_ARGUMENT
+
+PSA decrypt: RSA PKCS#1 v1.5: invalid key type (AES)
+depends_on:MBEDTLS_PK_PARSE_C:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V15
+asymmetric_decrypt_fail:PSA_KEY_TYPE_AES:"3082025e02010002818100af057d396e":PSA_ALG_RSA_PKCS1V15_CRYPT:"3082025e02010002818100af057d396e":"":PSA_ERROR_INVALID_ARGUMENT
 
 PSA decrypt: RSA PKCS#1 v1.5, input too small
 depends_on:MBEDTLS_PK_PARSE_C:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V15
-asymmetric_decrypt_fail:PSA_KEY_TYPE_RSA_KEYPAIR:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":PSA_ALG_RSA_PKCS1V15_CRYPT:"ffde2fcc00c9cc01972ebfa7779b298dbbaf7f50707a7405296dd2783456fc792002f462e760500e02afa25a859ace8701cb5d3b0262116431c43af8eb08f5a88301057cf1c156a2a5193c143e7a5b03fac132b7e89e6dcd8f4c82c9b28452329c260d30bc39b3816b7c46b41b37b4850d2ae74e729f99c6621fbbe2e46872":PSA_ERROR_INVALID_ARGUMENT
+asymmetric_decrypt_fail:PSA_KEY_TYPE_RSA_KEYPAIR:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":PSA_ALG_RSA_PKCS1V15_CRYPT:"ffde2fcc00c9cc01972ebfa7779b298dbbaf7f50707a7405296dd2783456fc792002f462e760500e02afa25a859ace8701cb5d3b0262116431c43af8eb08f5a88301057cf1c156a2a5193c143e7a5b03fac132b7e89e6dcd8f4c82c9b28452329c260d30bc39b3816b7c46b41b37b4850d2ae74e729f99c6621fbbe2e46872":"":PSA_ERROR_INVALID_ARGUMENT
 
 PSA decrypt: RSA PKCS#1 v1.5, input too large
 depends_on:MBEDTLS_PK_PARSE_C:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V15
-asymmetric_decrypt_fail:PSA_KEY_TYPE_RSA_KEYPAIR:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":PSA_ALG_RSA_PKCS1V15_CRYPT:"0099ffde2fcc00c9cc01972ebfa7779b298dbbaf7f50707a7405296dd2783456fc792002f462e760500e02afa25a859ace8701cb5d3b0262116431c43af8eb08f5a88301057cf1c156a2a5193c143e7a5b03fac132b7e89e6dcd8f4c82c9b28452329c260d30bc39b3816b7c46b41b37b4850d2ae74e729f99c6621fbbe2e46872":PSA_ERROR_INVALID_ARGUMENT
+asymmetric_decrypt_fail:PSA_KEY_TYPE_RSA_KEYPAIR:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":PSA_ALG_RSA_PKCS1V15_CRYPT:"0099ffde2fcc00c9cc01972ebfa7779b298dbbaf7f50707a7405296dd2783456fc792002f462e760500e02afa25a859ace8701cb5d3b0262116431c43af8eb08f5a88301057cf1c156a2a5193c143e7a5b03fac132b7e89e6dcd8f4c82c9b28452329c260d30bc39b3816b7c46b41b37b4850d2ae74e729f99c6621fbbe2e46872":"":PSA_ERROR_INVALID_ARGUMENT
+
+PSA decrypt: RSA OAEP-SHA-256, input too small
+depends_on:MBEDTLS_PK_PARSE_C:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V21:MBEDTLS_SHA256_C
+asymmetric_decrypt_fail:PSA_KEY_TYPE_RSA_KEYPAIR:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":PSA_ALG_RSA_OAEP(PSA_ALG_SHA_256):"ffde2fcc00c9cc01972ebfa7779b298dbbaf7f50707a7405296dd2783456fc792002f462e760500e02afa25a859ace8701cb5d3b0262116431c43af8eb08f5a88301057cf1c156a2a5193c143e7a5b03fac132b7e89e6dcd8f4c82c9b28452329c260d30bc39b3816b7c46b41b37b4850d2ae74e729f99c6621fbbe2e46872":"":PSA_ERROR_INVALID_ARGUMENT
+
+PSA decrypt: RSA OAEP-SHA-256, input too large
+depends_on:MBEDTLS_PK_PARSE_C:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V21:MBEDTLS_SHA256_C
+asymmetric_decrypt_fail:PSA_KEY_TYPE_RSA_KEYPAIR:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":PSA_ALG_RSA_OAEP(PSA_ALG_SHA_256):"0099ffde2fcc00c9cc01972ebfa7779b298dbbaf7f50707a7405296dd2783456fc792002f462e760500e02afa25a859ace8701cb5d3b0262116431c43af8eb08f5a88301057cf1c156a2a5193c143e7a5b03fac132b7e89e6dcd8f4c82c9b28452329c260d30bc39b3816b7c46b41b37b4850d2ae74e729f99c6621fbbe2e46872":"":PSA_ERROR_INVALID_ARGUMENT
+
+PSA key derivation: HKDF-SHA-256, good case
+depends_on:MBEDTLS_MD_C:MBEDTLS_SHA256_C
+derive_setup:PSA_KEY_TYPE_DERIVE:"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":PSA_ALG_HKDF(PSA_ALG_SHA_256):"":"":42:PSA_SUCCESS
+
+PSA key derivation: bad key type
+depends_on:MBEDTLS_MD_C:MBEDTLS_SHA256_C
+derive_setup:PSA_KEY_TYPE_RAW_DATA:"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":PSA_ALG_HKDF(PSA_ALG_SHA_256):"":"":42:PSA_ERROR_INVALID_ARGUMENT
+
+PSA key derivation: not a key derivation algorithm
+depends_on:MBEDTLS_MD_C:MBEDTLS_SHA256_C
+derive_setup:PSA_KEY_TYPE_DERIVE:"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":PSA_ALG_HMAC(PSA_ALG_SHA_256):"":"":42:PSA_ERROR_INVALID_ARGUMENT
+
+PSA key derivation: unsupported key derivation algorithm
+depends_on:MBEDTLS_MD_C:MBEDTLS_SHA256_C
+derive_setup:PSA_KEY_TYPE_DERIVE:"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":PSA_ALG_HKDF(PSA_ALG_CATEGORY_HASH):"":"":42:PSA_ERROR_NOT_SUPPORTED
+
+PSA key derivation: HKDF SHA-256, RFC5869 #1, output 42+0
+depends_on:MBEDTLS_MD_C:MBEDTLS_SHA256_C
+derive_output:PSA_ALG_HKDF(PSA_ALG_SHA_256):"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":"000102030405060708090a0b0c":"f0f1f2f3f4f5f6f7f8f9":42:"3cb25f25faacd57a90434f64d0362f2a2d2d0a90cf1a5a4c5db02d56ecc4c5bf34007208d5b887185865":""
+
+PSA key derivation: HKDF SHA-256, RFC5869 #1, output 32+10
+depends_on:MBEDTLS_MD_C:MBEDTLS_SHA256_C
+derive_output:PSA_ALG_HKDF(PSA_ALG_SHA_256):"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":"000102030405060708090a0b0c":"f0f1f2f3f4f5f6f7f8f9":42:"3cb25f25faacd57a90434f64d0362f2a2d2d0a90cf1a5a4c5db02d56ecc4c5bf":"34007208d5b887185865"
+
+PSA key derivation: HKDF SHA-256, RFC5869 #1, output 0+42
+depends_on:MBEDTLS_MD_C:MBEDTLS_SHA256_C
+derive_output:PSA_ALG_HKDF(PSA_ALG_SHA_256):"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":"000102030405060708090a0b0c":"f0f1f2f3f4f5f6f7f8f9":42:"":"3cb25f25faacd57a90434f64d0362f2a2d2d0a90cf1a5a4c5db02d56ecc4c5bf34007208d5b887185865"
+
+PSA key derivation: HKDF SHA-256, RFC5869 #1, output 1+41
+depends_on:MBEDTLS_MD_C:MBEDTLS_SHA256_C
+derive_output:PSA_ALG_HKDF(PSA_ALG_SHA_256):"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":"000102030405060708090a0b0c":"f0f1f2f3f4f5f6f7f8f9":42:"3c":"b25f25faacd57a90434f64d0362f2a2d2d0a90cf1a5a4c5db02d56ecc4c5bf34007208d5b887185865"
+
+PSA key derivation: HKDF SHA-256, RFC5869 #1, output 41+0
+depends_on:MBEDTLS_MD_C:MBEDTLS_SHA256_C
+derive_output:PSA_ALG_HKDF(PSA_ALG_SHA_256):"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":"000102030405060708090a0b0c":"f0f1f2f3f4f5f6f7f8f9":42:"3cb25f25faacd57a90434f64d0362f2a2d2d0a90cf1a5a4c5db02d56ecc4c5bf34007208d5b8871858":""
+
+PSA key derivation: HKDF SHA-256, RFC5869 #1, output 1+40
+depends_on:MBEDTLS_MD_C:MBEDTLS_SHA256_C
+derive_output:PSA_ALG_HKDF(PSA_ALG_SHA_256):"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":"000102030405060708090a0b0c":"f0f1f2f3f4f5f6f7f8f9":42:"3c":"b25f25faacd57a90434f64d0362f2a2d2d0a90cf1a5a4c5db02d56ecc4c5bf34007208d5b8871858"
+
+PSA key derivation: HKDF SHA-256, RFC5869 #2, output 82+0
+depends_on:MBEDTLS_MD_C:MBEDTLS_SHA256_C
+derive_output:PSA_ALG_HKDF(PSA_ALG_SHA_256):"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f":"606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeaf":"b0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff":82:"b11e398dc80327a1c8e7f78c596a49344f012eda2d4efad8a050cc4c19afa97c59045a99cac7827271cb41c65e590e09da3275600c2f09b8367793a9aca3db71cc30c58179ec3e87c14c01d5c1f3434f1d87":""
+
+PSA key derivation: HKDF SHA-256, RFC5869 #3, output 42+0
+depends_on:MBEDTLS_MD_C:MBEDTLS_SHA256_C
+derive_output:PSA_ALG_HKDF(PSA_ALG_SHA_256):"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":"":"":42:"8da4e775a563c18f715f802a063c5a31b8a11f5c5ee1879ec3454e5f3c738d2d9d201395faa4b61a96c8":""
+
+PSA key derivation: HKDF SHA-1, RFC5869 #4, output 42+0
+depends_on:MBEDTLS_MD_C:MBEDTLS_SHA1_C
+derive_output:PSA_ALG_HKDF(PSA_ALG_SHA_1):"0b0b0b0b0b0b0b0b0b0b0b":"000102030405060708090a0b0c":"f0f1f2f3f4f5f6f7f8f9":42:"085a01ea1b10f36933068b56efa5ad81a4f14b822f5b091568a9cdd4f155fda2c22e422478d305f3f896":""
+
+PSA key derivation: HKDF SHA-1, RFC5869 #5, output 82+0
+depends_on:MBEDTLS_MD_C:MBEDTLS_SHA1_C
+derive_output:PSA_ALG_HKDF(PSA_ALG_SHA_1):"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f":"606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeaf":"b0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff":82:"0bd770a74d1160f7c9f12cd5912a06ebff6adcae899d92191fe4305673ba2ffe8fa3f1a4e5ad79f3f334b3b202b2173c486ea37ce3d397ed034c7f9dfeb15c5e927336d0441f4c4300e2cff0d0900b52d3b4":""
+
+PSA key derivation: HKDF SHA-1, RFC5869 #6, output 42+0
+depends_on:MBEDTLS_MD_C:MBEDTLS_SHA1_C
+derive_output:PSA_ALG_HKDF(PSA_ALG_SHA_1):"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":"":"":42:"0ac1af7002b3d761d1e55298da9d0506b9ae52057220a306e07b6b87e8df21d0ea00033de03984d34918":""
+
+PSA key derivation: HKDF SHA-1, RFC5869 #7, output 42+0
+depends_on:MBEDTLS_MD_C:MBEDTLS_SHA1_C
+derive_output:PSA_ALG_HKDF(PSA_ALG_SHA_1):"0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c":"":"":42:"2c91117204d745f3500d636a62f64f0ab3bae548aa53d423b0d1f27ebba6f5e5673a081d70cce7acfc48":""
+
+PSA key derivation: HKDF SHA-256, request maximum capacity
+depends_on:MBEDTLS_MD_C:MBEDTLS_SHA256_C
+derive_output:PSA_ALG_HKDF(PSA_ALG_SHA_256):"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":"000102030405060708090a0b0c":"f0f1f2f3f4f5f6f7f8f9":255 * 32:"3cb25f25faacd57a90434f64d0362f2a2d2d0a90cf1a5a4c5db02d56ecc4c5bf34007208d5b887185865":""
+
+PSA key derivation: HKDF SHA-1, request maximum capacity
+depends_on:MBEDTLS_MD_C:MBEDTLS_SHA1_C
+derive_output:PSA_ALG_HKDF(PSA_ALG_SHA_1):"0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c":"":"":255 * 20:"2c91117204d745f3500d636a62f64f0ab3bae548aa53d423b0d1f27ebba6f5e5673a081d70cce7acfc48":""
+
+PSA key derivation: HKDF SHA-256, request too much capacity
+depends_on:MBEDTLS_MD_C:MBEDTLS_SHA256_C
+derive_setup:PSA_KEY_TYPE_DERIVE:"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":PSA_ALG_HKDF(PSA_ALG_SHA_256):"000102030405060708090a0b0c":"f0f1f2f3f4f5f6f7f8f9":255 * 32 + 1:PSA_ERROR_INVALID_ARGUMENT
+
+PSA key derivation: HKDF SHA-1, request too much capacity
+depends_on:MBEDTLS_MD_C:MBEDTLS_SHA1_C
+derive_setup:PSA_KEY_TYPE_DERIVE:"0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c":PSA_ALG_HKDF(PSA_ALG_SHA_1):"":"":255 * 20 + 1:PSA_ERROR_INVALID_ARGUMENT
+
+PSA key derivation: over capacity 42: output 42+1
+depends_on:MBEDTLS_MD_C:MBEDTLS_SHA256_C
+derive_output:PSA_ALG_HKDF(PSA_ALG_SHA_256):"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":"000102030405060708090a0b0c":"f0f1f2f3f4f5f6f7f8f9":42:"3cb25f25faacd57a90434f64d0362f2a2d2d0a90cf1a5a4c5db02d56ecc4c5bf34007208d5b887185865":"ff"
+
+PSA key derivation: over capacity 42: output 41+2
+depends_on:MBEDTLS_MD_C:MBEDTLS_SHA256_C
+derive_output:PSA_ALG_HKDF(PSA_ALG_SHA_256):"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":"000102030405060708090a0b0c":"f0f1f2f3f4f5f6f7f8f9":42:"3cb25f25faacd57a90434f64d0362f2a2d2d0a90cf1a5a4c5db02d56ecc4c5bf34007208d5b8871858":"65ff"
+
+PSA key derivation: over capacity 42: output 43+0
+depends_on:MBEDTLS_MD_C:MBEDTLS_SHA256_C
+derive_output:PSA_ALG_HKDF(PSA_ALG_SHA_256):"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":"000102030405060708090a0b0c":"f0f1f2f3f4f5f6f7f8f9":42:"3cb25f25faacd57a90434f64d0362f2a2d2d0a90cf1a5a4c5db02d56ecc4c5bf34007208d5b887185865ff":""
+
+PSA key derivation: over capacity 42: output 43+1
+depends_on:MBEDTLS_MD_C:MBEDTLS_SHA256_C
+derive_output:PSA_ALG_HKDF(PSA_ALG_SHA_256):"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":"000102030405060708090a0b0c":"f0f1f2f3f4f5f6f7f8f9":42:"3cb25f25faacd57a90434f64d0362f2a2d2d0a90cf1a5a4c5db02d56ecc4c5bf34007208d5b887185865ff":"ff"
+
+PSA key derivation: HKDF SHA-256, read maximum capacity minus 1
+depends_on:MBEDTLS_MD_C:MBEDTLS_SHA256_C
+derive_full:PSA_ALG_HKDF(PSA_ALG_SHA_256):"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":"000102030405060708090a0b0c":"f0f1f2f3f4f5f6f7f8f9":255 * 32 - 1
+
+PSA key derivation: HKDF SHA-256, read maximum capacity
+depends_on:MBEDTLS_MD_C:MBEDTLS_SHA256_C
+derive_full:PSA_ALG_HKDF(PSA_ALG_SHA_256):"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":"000102030405060708090a0b0c":"f0f1f2f3f4f5f6f7f8f9":255 * 32
+
+PSA key derivation: HKDF SHA-256, exercise AES128-CTR
+depends_on:MBEDTLS_MD_C:MBEDTLS_SHA256_C:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CTR
+derive_key_exercise:PSA_ALG_HKDF(PSA_ALG_SHA_256):"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":"000102030405060708090a0b0c":"f0f1f2f3f4f5f6f7f8f9":PSA_KEY_TYPE_AES:128:PSA_KEY_USAGE_ENCRYPT:PSA_ALG_CTR
+
+PSA key derivation: HKDF SHA-256, exercise AES256-CTR
+depends_on:MBEDTLS_MD_C:MBEDTLS_SHA256_C:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CTR
+derive_key_exercise:PSA_ALG_HKDF(PSA_ALG_SHA_256):"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":"000102030405060708090a0b0c":"f0f1f2f3f4f5f6f7f8f9":PSA_KEY_TYPE_AES:256:PSA_KEY_USAGE_ENCRYPT:PSA_ALG_CTR
+
+PSA key derivation: HKDF SHA-256, exercise DES-CBC
+depends_on:MBEDTLS_MD_C:MBEDTLS_SHA256_C:MBEDTLS_DES_C:MBEDTLS_CIPHER_MODE_CBC
+derive_key_exercise:PSA_ALG_HKDF(PSA_ALG_SHA_256):"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":"000102030405060708090a0b0c":"f0f1f2f3f4f5f6f7f8f9":PSA_KEY_TYPE_DES:64:PSA_KEY_USAGE_ENCRYPT:PSA_ALG_CBC_BASE | PSA_ALG_BLOCK_CIPHER_PAD_PKCS7
+
+PSA key derivation: HKDF SHA-256, exercise 2-key 3DES-CBC
+depends_on:MBEDTLS_MD_C:MBEDTLS_SHA256_C:MBEDTLS_DES_C:MBEDTLS_CIPHER_MODE_CBC
+derive_key_exercise:PSA_ALG_HKDF(PSA_ALG_SHA_256):"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":"000102030405060708090a0b0c":"f0f1f2f3f4f5f6f7f8f9":PSA_KEY_TYPE_DES:128:PSA_KEY_USAGE_ENCRYPT:PSA_ALG_CBC_BASE | PSA_ALG_BLOCK_CIPHER_PAD_PKCS7
+
+PSA key derivation: HKDF SHA-256, exercise 3-key 3DES-CBC
+depends_on:MBEDTLS_MD_C:MBEDTLS_SHA256_C:MBEDTLS_DES_C:MBEDTLS_CIPHER_MODE_CBC
+derive_key_exercise:PSA_ALG_HKDF(PSA_ALG_SHA_256):"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":"000102030405060708090a0b0c":"f0f1f2f3f4f5f6f7f8f9":PSA_KEY_TYPE_DES:192:PSA_KEY_USAGE_ENCRYPT:PSA_ALG_CBC_BASE | PSA_ALG_BLOCK_CIPHER_PAD_PKCS7
+
+PSA key derivation: HKDF SHA-256, exercise HMAC-SHA-256
+depends_on:MBEDTLS_MD_C:MBEDTLS_SHA256_C
+derive_key_exercise:PSA_ALG_HKDF(PSA_ALG_SHA_256):"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":"000102030405060708090a0b0c":"f0f1f2f3f4f5f6f7f8f9":PSA_KEY_TYPE_HMAC:256:PSA_KEY_USAGE_SIGN:PSA_ALG_HMAC(PSA_ALG_SHA_256)
+
+PSA key derivation: HKDF SHA-256, exercise HKDF-SHA-256
+depends_on:MBEDTLS_MD_C:MBEDTLS_SHA256_C
+derive_key_exercise:PSA_ALG_HKDF(PSA_ALG_SHA_256):"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":"000102030405060708090a0b0c":"f0f1f2f3f4f5f6f7f8f9":PSA_KEY_TYPE_DERIVE:400:PSA_KEY_USAGE_DERIVE:PSA_ALG_HKDF(PSA_ALG_SHA_256)
+
+PSA key derivation: HKDF SHA-256, derive key, 16+32
+depends_on:MBEDTLS_MD_C:MBEDTLS_SHA256_C
+derive_key_export:PSA_ALG_HKDF(PSA_ALG_SHA_256):"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":"000102030405060708090a0b0c":"f0f1f2f3f4f5f6f7f8f9":16:32
+
+PSA key derivation: HKDF SHA-256, derive key, 1+41
+depends_on:MBEDTLS_MD_C:MBEDTLS_SHA256_C
+derive_key_export:PSA_ALG_HKDF(PSA_ALG_SHA_256):"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":"000102030405060708090a0b0c":"f0f1f2f3f4f5f6f7f8f9":1:41
 
 PSA generate random: 0 bytes
 generate_random:0
@@ -802,18 +1138,22 @@
 depends_on:MBEDTLS_AES_C
 generate_key:PSA_KEY_TYPE_AES:64:PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT:PSA_ALG_CTR:PSA_ERROR_INVALID_ARGUMENT
 
-PSA generate key: RSA, 512 bits, good, sign
-depends_on:MBEDTLS_RSA_C:MBEDTLS_GENPRIME
+PSA generate key: RSA, 512 bits, good, sign (PKCS#1 v1.5)
+depends_on:MBEDTLS_RSA_C:MBEDTLS_GENPRIME:MBEDTLS_PKCS1_V15
 generate_key:PSA_KEY_TYPE_RSA_KEYPAIR:512:PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_SIGN | PSA_KEY_USAGE_VERIFY:PSA_ALG_RSA_PKCS1V15_SIGN_RAW:PSA_SUCCESS
 
-PSA generate key: RSA, 1024 bits, good, sign
-depends_on:MBEDTLS_RSA_C:MBEDTLS_GENPRIME
-generate_key:PSA_KEY_TYPE_RSA_KEYPAIR:1024:PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_SIGN | PSA_KEY_USAGE_VERIFY:PSA_ALG_RSA_PKCS1V15_SIGN_RAW:PSA_SUCCESS
+PSA generate key: RSA, 1024 bits, good, sign (PSS SHA-256)
+depends_on:MBEDTLS_RSA_C:MBEDTLS_GENPRIME:MBEDTLS_PKCS1_V21:MBEDTLS_SHA256_C
+generate_key:PSA_KEY_TYPE_RSA_KEYPAIR:1024:PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_SIGN | PSA_KEY_USAGE_VERIFY:PSA_ALG_RSA_PSS(PSA_ALG_SHA_256):PSA_SUCCESS
 
-PSA generate key: RSA, 512 bits, good, encrypt
-depends_on:MBEDTLS_RSA_C:MBEDTLS_GENPRIME
+PSA generate key: RSA, 512 bits, good, encrypt (PKCS#1 v1.5)
+depends_on:MBEDTLS_RSA_C:MBEDTLS_GENPRIME:MBEDTLS_PKCS1_V15
 generate_key:PSA_KEY_TYPE_RSA_KEYPAIR:512:PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT:PSA_ALG_RSA_PKCS1V15_CRYPT:PSA_SUCCESS
 
+PSA generate key: RSA, 1024 bits, good, encrypt (OAEP SHA-256)
+depends_on:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V21:MBEDTLS_SHA256_C
+generate_key:PSA_KEY_TYPE_RSA_KEYPAIR:1024:PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT:PSA_ALG_RSA_OAEP(PSA_ALG_SHA_256):PSA_SUCCESS
+
 PSA generate key: RSA, maximum size exceeded
 depends_on:MBEDTLS_RSA_C:MBEDTLS_GENPRIME
 generate_key:PSA_KEY_TYPE_RSA_KEYPAIR:PSA_VENDOR_RSA_MAX_KEY_BITS+1:PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT:PSA_ALG_RSA_PKCS1V15_CRYPT:PSA_ERROR_NOT_SUPPORTED
diff --git a/tests/suites/test_suite_psa_crypto.function b/tests/suites/test_suite_psa_crypto.function
index c94e4b0..2e0804b 100644
--- a/tests/suites/test_suite_psa_crypto.function
+++ b/tests/suites/test_suite_psa_crypto.function
@@ -8,6 +8,8 @@
 #include "mbedtls/asn1write.h"
 #include "psa/crypto.h"
 
+#define ARRAY_LENGTH( array ) ( sizeof( array ) / sizeof( *( array ) ) )
+
 #if(UINT32_MAX > SIZE_MAX)
 #define PSA_CRYPTO_TEST_SIZE_T_RANGE( x ) ( ( x ) <= SIZE_MAX )
 #else
@@ -143,7 +145,7 @@
         TEST_ASSERT( psa_mac_update( &operation,
                                      input, sizeof( input ) ) == PSA_SUCCESS );
         TEST_ASSERT( psa_mac_sign_finish( &operation,
-                                          mac, sizeof( input ),
+                                          mac, sizeof( mac ),
                                           &mac_length ) == PSA_SUCCESS );
     }
 
@@ -285,16 +287,21 @@
                                    psa_key_usage_t usage,
                                    psa_algorithm_t alg )
 {
-    unsigned char payload[16] = {1};
-    size_t payload_length = sizeof( payload );
+    unsigned char payload[PSA_HASH_MAX_SIZE] = {1};
+    size_t payload_length = 16;
     unsigned char signature[PSA_ASYMMETRIC_SIGNATURE_MAX_SIZE] = {0};
     size_t signature_length = sizeof( signature );
 
     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 );
         TEST_ASSERT( psa_asymmetric_sign( key, alg,
                                           payload, payload_length,
-                                          NULL, 0,
                                           signature, sizeof( signature ),
                                           &signature_length ) == PSA_SUCCESS );
     }
@@ -307,7 +314,6 @@
               PSA_ERROR_INVALID_SIGNATURE );
         TEST_ASSERT( psa_asymmetric_verify( key, alg,
                                             payload, payload_length,
-                                            NULL, 0,
                                             signature, signature_length ) ==
                      verify_status );
     }
@@ -357,6 +363,36 @@
     return( 0 );
 }
 
+static int exercise_key_derivation_key( psa_key_slot_t key,
+                                        psa_key_usage_t usage,
+                                        psa_algorithm_t alg )
+{
+    psa_crypto_generator_t generator = PSA_CRYPTO_GENERATOR_INIT;
+    unsigned char label[16] = "This is a label.";
+    size_t label_length = sizeof( label );
+    unsigned char seed[16] = "abcdefghijklmnop";
+    size_t seed_length = sizeof( seed );
+    unsigned char output[1];
+
+    if( usage & PSA_KEY_USAGE_DERIVE )
+    {
+        TEST_ASSERT( psa_key_derivation( &generator,
+                                         key, alg,
+                                         label, label_length,
+                                         seed, seed_length,
+                                         sizeof( output ) ) == PSA_SUCCESS );
+        TEST_ASSERT( psa_generator_read( &generator,
+                                         output,
+                                         sizeof( output ) ) == PSA_SUCCESS );
+        TEST_ASSERT( psa_generator_abort( &generator ) == PSA_SUCCESS );
+    }
+
+    return( 1 );
+
+exit:
+    return( 0 );
+}
+
 static int exercise_key( psa_key_slot_t slot,
                          psa_key_usage_t usage,
                          psa_algorithm_t alg )
@@ -374,6 +410,8 @@
         ok = exercise_signature_key( slot, usage, alg );
     else if( PSA_ALG_IS_ASYMMETRIC_ENCRYPTION( alg ) )
         ok = exercise_asymmetric_encryption_key( slot, usage, alg );
+    else if( PSA_ALG_IS_KEY_DERIVATION( alg ) )
+        ok = exercise_key_derivation_key( slot, usage, alg );
     else
     {
         char message[40];
@@ -657,6 +695,7 @@
           ( PSA_KEY_TYPE_IS_PUBLIC_KEY( type ) ?
             PSA_KEY_USAGE_ENCRYPT :
             PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT ) :
+          PSA_ALG_IS_KEY_DERIVATION( alg ) ? PSA_KEY_USAGE_DERIVE :
           0 );
     psa_key_policy_t policy;
     psa_key_type_t got_type;
@@ -965,7 +1004,6 @@
 
     status = psa_asymmetric_sign( key_slot, exercise_alg,
                                   payload, payload_length,
-                                  NULL, 0,
                                   signature, sizeof( signature ),
                                   &signature_length );
     if( policy_alg == exercise_alg &&
@@ -977,7 +1015,6 @@
     memset( signature, 0, sizeof( signature ) );
     status = psa_asymmetric_verify( key_slot, exercise_alg,
                                     payload, payload_length,
-                                    NULL, 0,
                                     signature, sizeof( signature ) );
     if( policy_alg == exercise_alg &&
         ( policy_usage & PSA_KEY_USAGE_VERIFY ) != 0 )
@@ -992,6 +1029,45 @@
 /* END_CASE */
 
 /* BEGIN_CASE */
+void derive_key_policy( int policy_usage,
+                        int policy_alg,
+                        int key_type,
+                        data_t *key_data,
+                        int exercise_alg )
+{
+    int key_slot = 1;
+    psa_key_policy_t policy;
+    psa_crypto_generator_t generator = PSA_CRYPTO_GENERATOR_INIT;
+    psa_status_t status;
+
+    TEST_ASSERT( psa_crypto_init( ) == PSA_SUCCESS );
+
+    psa_key_policy_init( &policy );
+    psa_key_policy_set_usage( &policy, policy_usage, policy_alg );
+    TEST_ASSERT( psa_set_key_policy( key_slot, &policy ) == PSA_SUCCESS );
+
+    TEST_ASSERT( psa_import_key( key_slot, key_type,
+                                 key_data->x, key_data->len ) == PSA_SUCCESS );
+
+    status = psa_key_derivation( &generator, key_slot,
+                                 exercise_alg,
+                                 NULL, 0,
+                                 NULL, 0,
+                                 1 );
+    if( policy_alg == exercise_alg &&
+        ( policy_usage & PSA_KEY_USAGE_DERIVE ) != 0 )
+        TEST_ASSERT( status == PSA_SUCCESS );
+    else
+        TEST_ASSERT( status == PSA_ERROR_NOT_PERMITTED );
+
+exit:
+    psa_generator_abort( &generator );
+    psa_destroy_key( key_slot );
+    mbedtls_psa_crypto_free( );
+}
+/* END_CASE */
+
+/* BEGIN_CASE */
 void key_lifetime( int lifetime_arg )
 {
     int key_slot = 1;
@@ -2011,10 +2087,9 @@
     /* Perform the signature. */
     TEST_ASSERT( psa_asymmetric_sign( slot, alg,
                                       input_data->x, input_data->len,
-                                      NULL, 0,
                                       signature, signature_size,
                                       &signature_length ) == PSA_SUCCESS );
-    /* Verify that the signature is correct. */
+    /* Verify that the signature is what is expected. */
     TEST_ASSERT( signature_length == output_data->len );
     TEST_ASSERT( memcmp( signature, output_data->x,
                          output_data->len ) == 0 );
@@ -2061,7 +2136,6 @@
 
     actual_status = psa_asymmetric_sign( slot, alg,
                                          input_data->x, input_data->len,
-                                         NULL, 0,
                                          signature, signature_size,
                                          &signature_length );
     TEST_ASSERT( actual_status == expected_status );
@@ -2079,6 +2153,78 @@
 /* END_CASE */
 
 /* BEGIN_CASE */
+void sign_verify( int key_type_arg, data_t *key_data,
+                  int alg_arg, data_t *input_data )
+{
+    int slot = 1;
+    psa_key_type_t key_type = key_type_arg;
+    psa_algorithm_t alg = alg_arg;
+    size_t key_bits;
+    unsigned char *signature = NULL;
+    size_t signature_size;
+    size_t signature_length = 0xdeadbeef;
+    psa_key_policy_t policy;
+
+    TEST_ASSERT( psa_crypto_init( ) == PSA_SUCCESS );
+
+    psa_key_policy_init( &policy );
+    psa_key_policy_set_usage( &policy,
+                              PSA_KEY_USAGE_SIGN | PSA_KEY_USAGE_VERIFY,
+                              alg );
+    TEST_ASSERT( psa_set_key_policy( slot, &policy ) == PSA_SUCCESS );
+
+    TEST_ASSERT( psa_import_key( slot, key_type,
+                                 key_data->x,
+                                 key_data->len ) == PSA_SUCCESS );
+    TEST_ASSERT( psa_get_key_information( slot,
+                                          NULL,
+                                          &key_bits ) == PSA_SUCCESS );
+
+    /* Allocate a buffer which has the size advertized by the
+     * library. */
+    signature_size = PSA_ASYMMETRIC_SIGN_OUTPUT_SIZE( key_type,
+                                                      key_bits, alg );
+    TEST_ASSERT( signature_size != 0 );
+    TEST_ASSERT( signature_size <= PSA_ASYMMETRIC_SIGNATURE_MAX_SIZE );
+    signature = mbedtls_calloc( 1, signature_size );
+    TEST_ASSERT( signature != NULL );
+
+    /* Perform the signature. */
+    TEST_ASSERT( psa_asymmetric_sign( slot, alg,
+                                      input_data->x, input_data->len,
+                                      signature, signature_size,
+                                      &signature_length ) == PSA_SUCCESS );
+    /* Check that the signature length looks sensible. */
+    TEST_ASSERT( signature_length <= signature_size );
+    TEST_ASSERT( signature_length > 0 );
+
+    /* Use the library to verify that the signature is correct. */
+    TEST_ASSERT( psa_asymmetric_verify(
+                     slot, alg,
+                     input_data->x, input_data->len,
+                     signature, signature_length ) == PSA_SUCCESS );
+
+    if( input_data->len != 0 )
+    {
+        /* Flip a bit in the input and verify that the signature is now
+         * detected as invalid. Flip a bit at the beginning, not at the end,
+         * because ECDSA may ignore the last few bits of the input. */
+        input_data->x[0] ^= 1;
+        TEST_ASSERT( psa_asymmetric_verify(
+                         slot, alg,
+                         input_data->x, input_data->len,
+                         signature,
+                         signature_length ) == PSA_ERROR_INVALID_SIGNATURE );
+    }
+
+exit:
+    psa_destroy_key( slot );
+    mbedtls_free( signature );
+    mbedtls_psa_crypto_free( );
+}
+/* END_CASE */
+
+/* BEGIN_CASE */
 void asymmetric_verify( int key_type_arg, data_t *key_data,
                         int alg_arg, data_t *hash_data,
                         data_t *signature_data )
@@ -2109,7 +2255,6 @@
 
     TEST_ASSERT( psa_asymmetric_verify( slot, alg,
                                         hash_data->x, hash_data->len,
-                                        NULL, 0,
                                         signature_data->x,
                                         signature_data->len ) == PSA_SUCCESS );
 exit:
@@ -2150,7 +2295,6 @@
 
     actual_status = psa_asymmetric_verify( slot, alg,
                                            hash_data->x, hash_data->len,
-                                           NULL, 0,
                                            signature_data->x,
                                            signature_data->len );
 
@@ -2163,18 +2307,92 @@
 /* END_CASE */
 
 /* BEGIN_CASE */
-void asymmetric_encrypt_decrypt( int key_type_arg, data_t *key_data,
-                                 int alg_arg, data_t *input_data )
+void asymmetric_encrypt( int key_type_arg,
+                         data_t *key_data,
+                         int alg_arg,
+                         data_t *input_data,
+                         data_t *label,
+                         int expected_output_length_arg,
+                         int expected_status_arg )
 {
     int slot = 1;
     psa_key_type_t key_type = key_type_arg;
     psa_algorithm_t alg = alg_arg;
+    size_t expected_output_length = expected_output_length_arg;
+    size_t key_bits;
     unsigned char *output = NULL;
-    size_t output_size = 0;
-    size_t output_length = 0;
+    size_t output_size;
+    size_t output_length = ~0;
+    psa_status_t actual_status;
+    psa_status_t expected_status = expected_status_arg;
+    psa_key_policy_t policy;
+
+    TEST_ASSERT( psa_crypto_init( ) == PSA_SUCCESS );
+
+    /* Import the key */
+    psa_key_policy_init( &policy );
+    psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_ENCRYPT, alg );
+    TEST_ASSERT( psa_set_key_policy( slot, &policy ) == PSA_SUCCESS );
+    TEST_ASSERT( psa_import_key( slot, key_type,
+                                 key_data->x,
+                                 key_data->len ) == PSA_SUCCESS );
+
+    /* Determine the maximum output length */
+    TEST_ASSERT( psa_get_key_information( slot,
+                                          NULL,
+                                          &key_bits ) == PSA_SUCCESS );
+    output_size = PSA_ASYMMETRIC_ENCRYPT_OUTPUT_SIZE( key_type, key_bits, alg );
+    output = mbedtls_calloc( 1, output_size );
+    TEST_ASSERT( output != NULL );
+
+    /* Encrypt the input */
+    actual_status = psa_asymmetric_encrypt( slot, alg,
+                                            input_data->x, input_data->len,
+                                            label->x, label->len,
+                                            output, output_size,
+                                            &output_length );
+    TEST_ASSERT( actual_status == expected_status );
+    TEST_ASSERT( output_length == expected_output_length );
+
+    /* If the label is empty, the test framework puts a non-null pointer
+     * in label->x. Test that a null pointer works as well. */
+    if( label->len == 0 )
+    {
+        output_length = ~0;
+        memset( output, 0, output_size );
+        actual_status = psa_asymmetric_encrypt( slot, alg,
+                                                input_data->x, input_data->len,
+                                                NULL, label->len,
+                                                output, output_size,
+                                                &output_length );
+        TEST_ASSERT( actual_status == expected_status );
+        TEST_ASSERT( output_length == expected_output_length );
+    }
+
+exit:
+    psa_destroy_key( slot );
+    mbedtls_free( output );
+    mbedtls_psa_crypto_free( );
+}
+/* END_CASE */
+
+/* BEGIN_CASE */
+void asymmetric_encrypt_decrypt( int key_type_arg,
+                                 data_t *key_data,
+                                 int alg_arg,
+                                 data_t *input_data,
+                                 data_t *label )
+{
+    int slot = 1;
+    psa_key_type_t key_type = key_type_arg;
+    psa_algorithm_t alg = alg_arg;
+    size_t key_bits;
+    unsigned char *output = NULL;
+    size_t output_size;
+    size_t output_length = ~0;
     unsigned char *output2 = NULL;
-    size_t output2_size = 0;
-    size_t output2_length = 0;
+    size_t output2_size;
+    size_t output2_length = ~0;
     psa_key_policy_t policy;
 
     TEST_ASSERT( key_data != NULL );
@@ -2182,13 +2400,6 @@
     TEST_ASSERT( PSA_CRYPTO_TEST_SIZE_T_RANGE( key_data->len ) );
     TEST_ASSERT( PSA_CRYPTO_TEST_SIZE_T_RANGE( input_data->len ) );
 
-    output_size = key_data->len;
-    output2_size = output_size;
-    output = mbedtls_calloc( 1, output_size );
-    TEST_ASSERT( output != NULL );
-    output2 = mbedtls_calloc( 1, output2_size );
-    TEST_ASSERT( output2 != NULL );
-
     TEST_ASSERT( psa_crypto_init( ) == PSA_SUCCESS );
 
     psa_key_policy_init( &policy );
@@ -2201,20 +2412,36 @@
                                  key_data->x,
                                  key_data->len ) == PSA_SUCCESS );
 
+
+    /* Determine the maximum ciphertext length */
+    TEST_ASSERT( psa_get_key_information( slot,
+                                          NULL,
+                                          &key_bits ) == PSA_SUCCESS );
+    output_size = PSA_ASYMMETRIC_ENCRYPT_OUTPUT_SIZE( key_type, key_bits, alg );
+    output = mbedtls_calloc( 1, output_size );
+    TEST_ASSERT( output != NULL );
+    output2_size = input_data->len;
+    output2 = mbedtls_calloc( 1, output2_size );
+    TEST_ASSERT( output2 != NULL );
+
     /* We test encryption by checking that encrypt-then-decrypt gives back
      * the original plaintext because of the non-optional random
      * part of encryption process which prevents using fixed vectors. */
     TEST_ASSERT( psa_asymmetric_encrypt( slot, alg,
                                          input_data->x, input_data->len,
-                                         NULL, 0,
+                                         label->x, label->len,
                                          output, output_size,
                                          &output_length ) == PSA_SUCCESS );
+    /* We don't know what ciphertext length to expect, but check that
+     * it looks sensible. */
+    TEST_ASSERT( output_length <= output_size );
 
     TEST_ASSERT( psa_asymmetric_decrypt( slot, alg,
                                          output, output_length,
-                                         NULL, 0,
+                                         label->x, label->len,
                                          output2, output2_size,
                                          &output2_length ) == PSA_SUCCESS );
+    TEST_ASSERT( output2_length == input_data->len );
     TEST_ASSERT( memcmp( input_data->x, output2,
                          input_data->len ) == 0 );
 
@@ -2227,64 +2454,19 @@
 /* END_CASE */
 
 /* BEGIN_CASE */
-void asymmetric_encrypt_fail( int key_type_arg, data_t *key_data,
-                              int alg_arg, data_t *input_data,
-                              int expected_status_arg )
+void asymmetric_decrypt( int key_type_arg,
+                         data_t *key_data,
+                         int alg_arg,
+                         data_t *input_data,
+                         data_t *label,
+                         data_t *expected_data )
 {
     int slot = 1;
     psa_key_type_t key_type = key_type_arg;
     psa_algorithm_t alg = alg_arg;
     unsigned char *output = NULL;
     size_t output_size = 0;
-    size_t output_length = 0;
-    psa_status_t actual_status;
-    psa_status_t expected_status = expected_status_arg;
-    psa_key_policy_t policy;
-
-    TEST_ASSERT( key_data != NULL );
-    TEST_ASSERT( input_data != NULL );
-    TEST_ASSERT( PSA_CRYPTO_TEST_SIZE_T_RANGE( key_data->len ) );
-    TEST_ASSERT( PSA_CRYPTO_TEST_SIZE_T_RANGE( input_data->len ) );
-
-    output_size = key_data->len;
-    output = mbedtls_calloc( 1, output_size );
-    TEST_ASSERT( output != NULL );
-
-    TEST_ASSERT( psa_crypto_init( ) == PSA_SUCCESS );
-
-    psa_key_policy_init( &policy );
-    psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_ENCRYPT, alg );
-    TEST_ASSERT( psa_set_key_policy( slot, &policy ) == PSA_SUCCESS );
-
-    TEST_ASSERT( psa_import_key( slot, key_type,
-                                 key_data->x,
-                                 key_data->len ) == PSA_SUCCESS );
-
-    actual_status = psa_asymmetric_encrypt( slot, alg,
-                                            input_data->x, input_data->len,
-                                            NULL, 0,
-                                            output, output_size,
-                                            &output_length );
-    TEST_ASSERT( actual_status == expected_status );
-
-exit:
-    psa_destroy_key( slot );
-    mbedtls_free( output );
-    mbedtls_psa_crypto_free( );
-}
-/* END_CASE */
-
-/* BEGIN_CASE */
-void asymmetric_decrypt( int key_type_arg, data_t *key_data,
-                         int alg_arg, data_t *input_data,
-                         data_t *expected_data, int expected_size )
-{
-    int slot = 1;
-    psa_key_type_t key_type = key_type_arg;
-    psa_algorithm_t alg = alg_arg;
-    unsigned char *output = NULL;
-    size_t output_size = 0;
-    size_t output_length = 0;
+    size_t output_length = ~0;
     psa_key_policy_t policy;
 
     TEST_ASSERT( key_data != NULL );
@@ -2310,13 +2492,29 @@
 
     TEST_ASSERT( psa_asymmetric_decrypt( slot, alg,
                                          input_data->x, input_data->len,
-                                         NULL, 0,
+                                         label->x, label->len,
                                          output,
                                          output_size,
                                          &output_length ) == PSA_SUCCESS );
-    TEST_ASSERT( (size_t) expected_size == output_length );
+    TEST_ASSERT( expected_data->len == output_length );
     TEST_ASSERT( memcmp( expected_data->x, output, output_length ) == 0 );
 
+    /* If the label is empty, the test framework puts a non-null pointer
+     * in label->x. Test that a null pointer works as well. */
+    if( label->len == 0 )
+    {
+        output_length = ~0;
+        memset( output, 0, output_size );
+        TEST_ASSERT( psa_asymmetric_decrypt( slot, alg,
+                                             input_data->x, input_data->len,
+                                             NULL, label->len,
+                                             output,
+                                             output_size,
+                                             &output_length ) == PSA_SUCCESS );
+        TEST_ASSERT( expected_data->len == output_length );
+        TEST_ASSERT( memcmp( expected_data->x, output, output_length ) == 0 );
+    }
+
 exit:
     psa_destroy_key( slot );
     mbedtls_free( output );
@@ -2325,8 +2523,11 @@
 /* END_CASE */
 
 /* BEGIN_CASE */
-void asymmetric_decrypt_fail( int key_type_arg, data_t *key_data,
-                              int alg_arg, data_t *input_data,
+void asymmetric_decrypt_fail( int key_type_arg,
+                              data_t *key_data,
+                              int alg_arg,
+                              data_t *input_data,
+                              data_t *label,
                               int expected_status_arg  )
 {
     int slot = 1;
@@ -2334,7 +2535,7 @@
     psa_algorithm_t alg = alg_arg;
     unsigned char *output = NULL;
     size_t output_size = 0;
-    size_t output_length = 0;
+    size_t output_length = ~0;
     psa_status_t actual_status;
     psa_status_t expected_status = expected_status_arg;
     psa_key_policy_t policy;
@@ -2360,10 +2561,26 @@
 
     actual_status = psa_asymmetric_decrypt( slot, alg,
                                             input_data->x, input_data->len,
-                                            NULL, 0,
+                                            label->x, label->len,
                                             output, output_size,
                                             &output_length );
     TEST_ASSERT( actual_status == expected_status );
+    TEST_ASSERT( output_length <= output_size );
+
+    /* If the label is empty, the test framework puts a non-null pointer
+     * in label->x. Test that a null pointer works as well. */
+    if( label->len == 0 )
+    {
+        output_length = ~0;
+        memset( output, 0, output_size );
+        actual_status = psa_asymmetric_decrypt( slot, alg,
+                                                input_data->x, input_data->len,
+                                                NULL, label->len,
+                                                output, output_size,
+                                                &output_length );
+        TEST_ASSERT( actual_status == expected_status );
+        TEST_ASSERT( output_length <= output_size );
+    }
 
 exit:
     psa_destroy_key( slot );
@@ -2373,6 +2590,352 @@
 /* END_CASE */
 
 /* BEGIN_CASE */
+void derive_setup( int key_type_arg,
+                   data_t *key_data,
+                   int alg_arg,
+                   data_t *salt,
+                   data_t *label,
+                   int requested_capacity_arg,
+                   int expected_status_arg )
+{
+    psa_key_slot_t slot = 1;
+    size_t key_type = key_type_arg;
+    psa_algorithm_t alg = alg_arg;
+    size_t requested_capacity = requested_capacity_arg;
+    psa_status_t expected_status = expected_status_arg;
+    psa_crypto_generator_t generator = PSA_CRYPTO_GENERATOR_INIT;
+    psa_key_policy_t policy;
+
+    TEST_ASSERT( psa_crypto_init( ) == PSA_SUCCESS );
+
+    psa_key_policy_init( &policy );
+    psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_DERIVE, alg );
+    TEST_ASSERT( psa_set_key_policy( slot, &policy ) == PSA_SUCCESS );
+
+    TEST_ASSERT( psa_import_key( slot, key_type,
+                                 key_data->x,
+                                 key_data->len ) == PSA_SUCCESS );
+
+    TEST_ASSERT( psa_key_derivation( &generator, slot, alg,
+                                     salt->x, salt->len,
+                                     label->x, label->len,
+                                     requested_capacity ) == expected_status );
+
+exit:
+    psa_generator_abort( &generator );
+    psa_destroy_key( slot );
+    mbedtls_psa_crypto_free( );
+}
+/* END_CASE */
+
+/* BEGIN_CASE */
+void derive_output( int alg_arg,
+                    data_t *key_data,
+                    data_t *salt,
+                    data_t *label,
+                    int requested_capacity_arg,
+                    data_t *expected_output1,
+                    data_t *expected_output2 )
+{
+    psa_key_slot_t slot = 1;
+    psa_algorithm_t alg = alg_arg;
+    size_t requested_capacity = requested_capacity_arg;
+    psa_crypto_generator_t generator = PSA_CRYPTO_GENERATOR_INIT;
+    uint8_t *expected_outputs[2] =
+        {expected_output1->x, expected_output2->x};
+    size_t output_sizes[2] =
+        {expected_output1->len, expected_output2->len};
+    size_t output_buffer_size = 0;
+    uint8_t *output_buffer = NULL;
+    size_t expected_capacity;
+    size_t current_capacity;
+    psa_key_policy_t policy;
+    psa_status_t status;
+    unsigned i;
+
+    for( i = 0; i < ARRAY_LENGTH( expected_outputs ); i++ )
+    {
+        if( output_sizes[i] > output_buffer_size )
+            output_buffer_size = output_sizes[i];
+        if( output_sizes[i] == 0 )
+            expected_outputs[i] = NULL;
+    }
+    output_buffer = mbedtls_calloc( 1, output_buffer_size );
+    TEST_ASSERT( output_buffer != NULL );
+    TEST_ASSERT( psa_crypto_init( ) == PSA_SUCCESS );
+
+    psa_key_policy_init( &policy );
+    psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_DERIVE, alg );
+    TEST_ASSERT( psa_set_key_policy( slot, &policy ) == PSA_SUCCESS );
+
+    TEST_ASSERT( psa_import_key( slot, PSA_KEY_TYPE_DERIVE,
+                                 key_data->x,
+                                 key_data->len ) == PSA_SUCCESS );
+
+    /* Extraction phase. */
+    TEST_ASSERT( psa_key_derivation( &generator, slot, alg,
+                                     salt->x, salt->len,
+                                     label->x, label->len,
+                                     requested_capacity ) == PSA_SUCCESS );
+    TEST_ASSERT( psa_get_generator_capacity( &generator,
+                                             &current_capacity ) ==
+                 PSA_SUCCESS );
+    TEST_ASSERT( current_capacity == requested_capacity );
+    expected_capacity = requested_capacity;
+
+    /* Expansion phase. */
+    for( i = 0; i < ARRAY_LENGTH( expected_outputs ); i++ )
+    {
+        /* Read some bytes. */
+        status = psa_generator_read( &generator,
+                                     output_buffer, output_sizes[i] );
+        if( expected_capacity == 0 && output_sizes[i] == 0 )
+        {
+            /* Reading 0 bytes when 0 bytes are available can go either way. */
+            TEST_ASSERT( status == PSA_SUCCESS ||
+                         status == PSA_ERROR_INSUFFICIENT_CAPACITY );
+            continue;
+        }
+        else if( expected_capacity == 0 ||
+                 output_sizes[i] > expected_capacity )
+        {
+            /* Capacity exceeded. */
+            TEST_ASSERT( status == PSA_ERROR_INSUFFICIENT_CAPACITY );
+            expected_capacity = 0;
+            continue;
+        }
+        /* Success. Check the read data. */
+        TEST_ASSERT( status == PSA_SUCCESS );
+        if( output_sizes[i] != 0 )
+            TEST_ASSERT( memcmp( output_buffer, expected_outputs[i],
+                                 output_sizes[i] ) == 0 );
+        /* Check the generator status. */
+        expected_capacity -= output_sizes[i];
+        TEST_ASSERT( psa_get_generator_capacity( &generator,
+                                                 &current_capacity ) ==
+                     PSA_SUCCESS );
+        TEST_ASSERT( expected_capacity == current_capacity );
+    }
+    TEST_ASSERT( psa_generator_abort( &generator ) == PSA_SUCCESS );
+
+exit:
+    mbedtls_free( output_buffer );
+    psa_generator_abort( &generator );
+    psa_destroy_key( slot );
+    mbedtls_psa_crypto_free( );
+}
+/* END_CASE */
+
+/* BEGIN_CASE */
+void derive_full( int alg_arg,
+                  data_t *key_data,
+                  data_t *salt,
+                  data_t *label,
+                  int requested_capacity_arg )
+{
+    psa_key_slot_t slot = 1;
+    psa_algorithm_t alg = alg_arg;
+    size_t requested_capacity = requested_capacity_arg;
+    psa_crypto_generator_t generator = PSA_CRYPTO_GENERATOR_INIT;
+    unsigned char output_buffer[16];
+    size_t expected_capacity = requested_capacity;
+    size_t current_capacity;
+    psa_key_policy_t policy;
+
+    TEST_ASSERT( psa_crypto_init( ) == PSA_SUCCESS );
+
+    psa_key_policy_init( &policy );
+    psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_DERIVE, alg );
+    TEST_ASSERT( psa_set_key_policy( slot, &policy ) == PSA_SUCCESS );
+
+    TEST_ASSERT( psa_import_key( slot, PSA_KEY_TYPE_DERIVE,
+                                 key_data->x,
+                                 key_data->len ) == PSA_SUCCESS );
+
+    /* Extraction phase. */
+    TEST_ASSERT( psa_key_derivation( &generator, slot, alg,
+                                     salt->x, salt->len,
+                                     label->x, label->len,
+                                     requested_capacity ) == PSA_SUCCESS );
+    TEST_ASSERT( psa_get_generator_capacity( &generator,
+                                             &current_capacity ) ==
+                 PSA_SUCCESS );
+    TEST_ASSERT( current_capacity == expected_capacity );
+
+    /* Expansion phase. */
+    while( current_capacity > 0 )
+    {
+        size_t read_size = sizeof( output_buffer );
+        if( read_size > current_capacity )
+            read_size = current_capacity;
+        TEST_ASSERT( psa_generator_read( &generator,
+                                         output_buffer,
+                                         read_size ) == PSA_SUCCESS );
+        expected_capacity -= read_size;
+        TEST_ASSERT( psa_get_generator_capacity( &generator,
+                                                 &current_capacity ) ==
+                     PSA_SUCCESS );
+        TEST_ASSERT( current_capacity == expected_capacity );
+    }
+
+    /* Check that the generator refuses to go over capacity. */
+    TEST_ASSERT( psa_generator_read( &generator,
+                                     output_buffer,
+                                     1 ) == PSA_ERROR_INSUFFICIENT_CAPACITY );
+
+    TEST_ASSERT( psa_generator_abort( &generator ) == PSA_SUCCESS );
+
+exit:
+    psa_generator_abort( &generator );
+    psa_destroy_key( slot );
+    mbedtls_psa_crypto_free( );
+}
+/* END_CASE */
+
+/* BEGIN_CASE */
+void derive_key_exercise( int alg_arg,
+                          data_t *key_data,
+                          data_t *salt,
+                          data_t *label,
+                          int derived_type_arg,
+                          int derived_bits_arg,
+                          int derived_usage_arg,
+                          int derived_alg_arg )
+{
+    psa_key_slot_t base_key = 1;
+    psa_key_slot_t derived_key = 2;
+    psa_algorithm_t alg = alg_arg;
+    psa_key_type_t derived_type = derived_type_arg;
+    size_t derived_bits = derived_bits_arg;
+    psa_key_usage_t derived_usage = derived_usage_arg;
+    psa_algorithm_t derived_alg = derived_alg_arg;
+    size_t capacity = PSA_BITS_TO_BYTES( derived_bits );
+    psa_crypto_generator_t generator = PSA_CRYPTO_GENERATOR_INIT;
+    psa_key_policy_t policy;
+    psa_key_type_t got_type;
+    size_t got_bits;
+
+    TEST_ASSERT( psa_crypto_init( ) == PSA_SUCCESS );
+
+    psa_key_policy_init( &policy );
+    psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_DERIVE, alg );
+    TEST_ASSERT( psa_set_key_policy( base_key, &policy ) == PSA_SUCCESS );
+    TEST_ASSERT( psa_import_key( base_key, PSA_KEY_TYPE_DERIVE,
+                                 key_data->x,
+                                 key_data->len ) == PSA_SUCCESS );
+
+    /* Derive a key. */
+    TEST_ASSERT( psa_key_derivation( &generator, base_key, alg,
+                                     salt->x, salt->len,
+                                     label->x, label->len,
+                                     capacity ) == PSA_SUCCESS );
+    psa_key_policy_set_usage( &policy, derived_usage, derived_alg );
+    TEST_ASSERT( psa_set_key_policy( derived_key, &policy ) == PSA_SUCCESS );
+    TEST_ASSERT( psa_generator_import_key( derived_key,
+                                           derived_type,
+                                           derived_bits,
+                                           &generator ) == PSA_SUCCESS );
+
+    /* Test the key information */
+    TEST_ASSERT( psa_get_key_information( derived_key,
+                                          &got_type,
+                                          &got_bits ) == PSA_SUCCESS );
+    TEST_ASSERT( got_type == derived_type );
+    TEST_ASSERT( got_bits == derived_bits );
+
+    /* Exercise the derived key. */
+    if( ! exercise_key( derived_key, derived_usage, derived_alg ) )
+        goto exit;
+
+exit:
+    psa_generator_abort( &generator );
+    psa_destroy_key( base_key );
+    psa_destroy_key( derived_key );
+    mbedtls_psa_crypto_free( );
+}
+/* END_CASE */
+
+/* BEGIN_CASE */
+void derive_key_export( int alg_arg,
+                        data_t *key_data,
+                        data_t *salt,
+                        data_t *label,
+                        int bytes1_arg,
+                        int bytes2_arg )
+{
+    psa_key_slot_t base_key = 1;
+    psa_key_slot_t derived_key = 2;
+    psa_algorithm_t alg = alg_arg;
+    size_t bytes1 = bytes1_arg;
+    size_t bytes2 = bytes2_arg;
+    size_t capacity = bytes1 + bytes2;
+    psa_crypto_generator_t generator = PSA_CRYPTO_GENERATOR_INIT;
+    uint8_t *output_buffer = mbedtls_calloc( 1, capacity );
+    uint8_t *export_buffer = mbedtls_calloc( 1, capacity );
+    psa_key_policy_t policy;
+    size_t length;
+
+    TEST_ASSERT( output_buffer != NULL );
+    TEST_ASSERT( export_buffer != NULL );
+    TEST_ASSERT( psa_crypto_init( ) == PSA_SUCCESS );
+
+    psa_key_policy_init( &policy );
+    psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_DERIVE, alg );
+    TEST_ASSERT( psa_set_key_policy( base_key, &policy ) == PSA_SUCCESS );
+    TEST_ASSERT( psa_import_key( base_key, PSA_KEY_TYPE_DERIVE,
+                                 key_data->x,
+                                 key_data->len ) == PSA_SUCCESS );
+
+    /* Derive some material and output it. */
+    TEST_ASSERT( psa_key_derivation( &generator, base_key, alg,
+                                     salt->x, salt->len,
+                                     label->x, label->len,
+                                     capacity ) == PSA_SUCCESS );
+    TEST_ASSERT( psa_generator_read( &generator,
+                                     output_buffer,
+                                     capacity ) == PSA_SUCCESS );
+    TEST_ASSERT( psa_generator_abort( &generator ) == PSA_SUCCESS );
+
+    /* Derive the same output again, but this time store it in key objects. */
+    TEST_ASSERT( psa_key_derivation( &generator, base_key, alg,
+                                     salt->x, salt->len,
+                                     label->x, label->len,
+                                     capacity ) == PSA_SUCCESS );
+    psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_EXPORT, 0 );
+    TEST_ASSERT( psa_set_key_policy( derived_key, &policy ) == PSA_SUCCESS );
+    TEST_ASSERT( psa_generator_import_key( derived_key,
+                                           PSA_KEY_TYPE_RAW_DATA,
+                                           PSA_BYTES_TO_BITS( bytes1 ),
+                                           &generator ) == PSA_SUCCESS );
+    TEST_ASSERT( psa_export_key( derived_key,
+                                 export_buffer, bytes1,
+                                 &length ) == PSA_SUCCESS );
+    TEST_ASSERT( length == bytes1 );
+    TEST_ASSERT( psa_destroy_key( derived_key ) == PSA_SUCCESS );
+    TEST_ASSERT( psa_set_key_policy( derived_key, &policy ) == PSA_SUCCESS );
+    TEST_ASSERT( psa_generator_import_key( derived_key,
+                                           PSA_KEY_TYPE_RAW_DATA,
+                                           PSA_BYTES_TO_BITS( bytes2 ),
+                                           &generator ) == PSA_SUCCESS );
+    TEST_ASSERT( psa_export_key( derived_key,
+                                 export_buffer + bytes1, bytes2,
+                                 &length ) == PSA_SUCCESS );
+    TEST_ASSERT( length == bytes2 );
+
+    /* Compare the outputs from the two runs. */
+    TEST_ASSERT( memcmp( output_buffer, export_buffer, capacity ) == 0 );
+
+exit:
+    mbedtls_free( output_buffer );
+    mbedtls_free( export_buffer );
+    psa_generator_abort( &generator );
+    psa_destroy_key( base_key );
+    psa_destroy_key( derived_key );
+    mbedtls_psa_crypto_free( );
+}
+/* END_CASE */
+
+/* BEGIN_CASE */
 void generate_random( int bytes_arg )
 {
     size_t bytes = bytes_arg;