Merge pull request #4377 from mpg/psa-pbkdf2-api

PSA API for PBKDF2-HMAC
diff --git a/docs/proposed/psa-driver-interface.md b/docs/proposed/psa-driver-interface.md
index 23274c7..125a415 100644
--- a/docs/proposed/psa-driver-interface.md
+++ b/docs/proposed/psa-driver-interface.md
@@ -305,9 +305,12 @@
 * `"key_derivation_setup"`: called by `psa_key_derivation_setup()`.
 * `"key_derivation_set_capacity"`: called by `psa_key_derivation_set_capacity()`. The core will always enforce the capacity, therefore this function does not need to do anything for algorithms where the output stream only depends on the effective generated length and not on the capacity.
 * `"key_derivation_input_bytes"`: called by `psa_key_derivation_input_bytes()` and `psa_key_derivation_input_key()`. For transparent drivers, when processing a call to `psa_key_derivation_input_key()`, the core always calls the applicable driver's `"key_derivation_input_bytes"` entry point.
+* `"key_derivation_input_integer"`: called by `psa_key_derivation_input_integer()`.
 * `"key_derivation_input_key"` (opaque drivers only)
 * `"key_derivation_output_bytes"`: called by `psa_key_derivation_output_bytes()`; also by `psa_key_derivation_output_key()` for transparent drivers.
 * `"key_derivation_output_key"`: called by `psa_key_derivation_output_key()` for transparent drivers when deriving an asymmetric key pair, and also for opaque drivers.
+* `"key_derivation_verify_bytes"` (opaque drivers only).
+* `"key_derivation_verify_key"` (opaque drivers only).
 * `"key_derivation_abort"`: called by all key derivation functions of the PSA Cryptography API.
 
 TODO: key input and output for opaque drivers; deterministic key generation for transparent drivers
diff --git a/include/psa/crypto.h b/include/psa/crypto.h
index 94b8f99..b14f4c5 100644
--- a/include/psa/crypto.h
+++ b/include/psa/crypto.h
@@ -3337,6 +3337,50 @@
     const uint8_t *data,
     size_t data_length);
 
+/** Provide a numeric input for key derivation or key agreement.
+ *
+ * Which inputs are required and in what order depends on the algorithm.
+ * However, when an algorithm requires a particular order, numeric inputs
+ * usually come first as they tend to be configuration parameters.
+ * Refer to the documentation of each key derivation or key agreement
+ * algorithm for information.
+ *
+ * This function is used for inputs which are fixed-size non-negative
+ * integers.
+ *
+ * If this function returns an error status, the operation enters an error
+ * state and must be aborted by calling psa_key_derivation_abort().
+ *
+ * \param[in,out] operation       The key derivation operation object to use.
+ *                                It must have been set up with
+ *                                psa_key_derivation_setup() and must not
+ *                                have produced any output yet.
+ * \param step                    Which step the input data is for.
+ * \param[in] value               The value of the numeric input.
+ *
+ * \retval #PSA_SUCCESS
+ *         Success.
+ * \retval #PSA_ERROR_INVALID_ARGUMENT
+ *         \c step is not compatible with the operation's algorithm.
+ * \retval #PSA_ERROR_INVALID_ARGUMENT
+ *         \c step does not allow numeric inputs.
+ * \retval #PSA_ERROR_INSUFFICIENT_MEMORY
+ * \retval #PSA_ERROR_COMMUNICATION_FAILURE
+ * \retval #PSA_ERROR_HARDWARE_FAILURE
+ * \retval #PSA_ERROR_CORRUPTION_DETECTED
+ * \retval #PSA_ERROR_STORAGE_FAILURE
+ * \retval #PSA_ERROR_BAD_STATE
+ *         The operation state is not valid for this input \p step.
+ * \retval #PSA_ERROR_BAD_STATE
+ *         The library has not been previously initialized by psa_crypto_init().
+ *         It is implementation-dependent whether a failure to initialize
+ *         results in this error code.
+ */
+psa_status_t psa_key_derivation_input_integer(
+    psa_key_derivation_operation_t *operation,
+    psa_key_derivation_step_t step,
+    uint64_t value);
+
 /** Provide an input for key derivation in the form of a key.
  *
  * Which inputs are required and in what order depends on the algorithm.
@@ -3361,12 +3405,29 @@
  * \param step                    Which step the input data is for.
  * \param key                     Identifier of the key. It must have an
  *                                appropriate type for step and must allow the
- *                                usage #PSA_KEY_USAGE_DERIVE.
+ *                                usage #PSA_KEY_USAGE_DERIVE or
+ *                                #PSA_KEY_USAGE_VERIFY_DERIVATION (see note)
+ *                                and the algorithm used by the operation.
+ *
+ * \note Once all inputs steps are completed, the operations will allow:
+ * - psa_key_derivation_output_bytes() if each input was either a direct input
+ *   or  a key with #PSA_KEY_USAGE_DERIVE set;
+ * - psa_key_derivation_output_key() if the input for step
+ *   #PSA_KEY_DERIVATION_INPUT_SECRET or #PSA_KEY_DERIVATION_INPUT_PASSWORD
+ *   was from a key slot with #PSA_KEY_USAGE_DERIVE and each other input was
+ *   either a direct input or a key with #PSA_KEY_USAGE_DERIVE set;
+ * - psa_key_derivation_verify_bytes() if each input was either a direct input
+ *   or  a key with #PSA_KEY_USAGE_VERIFY_DERIVATION set;
+ * - psa_key_derivation_verify_key() under the same conditions as
+ *   psa_key_derivation_verify_bytes().
  *
  * \retval #PSA_SUCCESS
  *         Success.
  * \retval #PSA_ERROR_INVALID_HANDLE
  * \retval #PSA_ERROR_NOT_PERMITTED
+ *         The key allows neither #PSA_KEY_USAGE_DERIVE nor
+ *         #PSA_KEY_USAGE_VERIFY_DERIVATION, or it doesn't allow this
+ *         algorithm.
  * \retval #PSA_ERROR_INVALID_ARGUMENT
  *         \c step is not compatible with the operation's algorithm.
  * \retval #PSA_ERROR_INVALID_ARGUMENT
@@ -3479,6 +3540,9 @@
  * \param output_length     Number of bytes to output.
  *
  * \retval #PSA_SUCCESS
+ * \retval #PSA_ERROR_NOT_PERMITTED
+ *         One of the inputs was a key whose policy didn't allow
+ *         #PSA_KEY_USAGE_DERIVE.
  * \retval #PSA_ERROR_INSUFFICIENT_DATA
  *                          The operation's capacity was less than
  *                          \p output_length bytes. Note that in this case,
@@ -3539,7 +3603,8 @@
  *     - #PSA_KEY_TYPE_ARC4;
  *     - #PSA_KEY_TYPE_CAMELLIA;
  *     - #PSA_KEY_TYPE_DERIVE;
- *     - #PSA_KEY_TYPE_HMAC.
+ *     - #PSA_KEY_TYPE_HMAC;
+ *     - #PSA_KEY_TYPE_PASSWORD_HASH.
  *
  * - For ECC keys on a Montgomery elliptic curve
  *   (#PSA_KEY_TYPE_ECC_KEY_PAIR(\c curve) where \c curve designates a
@@ -3601,6 +3666,10 @@
  * on the derived key based on the attributes and strength of the secret key.
  *
  * \param[in] attributes    The attributes for the new key.
+ *                          If the key type to be created is
+ *                          #PSA_KEY_TYPE_PASSWORD_HASH then the algorithm in
+ *                          the policy must be the same as in the current
+ *                          operation.
  * \param[in,out] operation The key derivation operation object to read from.
  * \param[out] key          On success, an identifier for the newly created
  *                          key. For persistent keys, this is the key
@@ -3625,8 +3694,10 @@
  * \retval #PSA_ERROR_INVALID_ARGUMENT
  *         The provided key attributes are not valid for the operation.
  * \retval #PSA_ERROR_NOT_PERMITTED
- *         The #PSA_KEY_DERIVATION_INPUT_SECRET input was not provided through
- *         a key.
+ *         The #PSA_KEY_DERIVATION_INPUT_SECRET or
+ *         #PSA_KEY_DERIVATION_INPUT_PASSWORD input was not provided through a
+ *         key; or one of the inputs was a key whose policy didn't allow
+ *         #PSA_KEY_USAGE_DERIVE.
  * \retval #PSA_ERROR_BAD_STATE
  *         The operation state is not valid (it must be active and completed
  *         all required input steps).
@@ -3648,6 +3719,129 @@
     psa_key_derivation_operation_t *operation,
     mbedtls_svc_key_id_t *key);
 
+/** Compare output data from a key derivation operation to an expected value.
+ *
+ * This function calculates output bytes from a key derivation algorithm and
+ * compares those bytes to an expected value in constant time.
+ * If you view the key derivation's output as a stream of bytes, this
+ * function destructively reads the requested number of bytes from the
+ * stream before comparing them.
+ * The operation's capacity decreases by the number of bytes read.
+ *
+ * This is functionally equivalent to the following code:
+ * \code
+ * psa_key_derivation_output_bytes(operation, tmp, output_length);
+ * if (memcmp(output, tmp, output_length) != 0)
+ *     return PSA_ERROR_INVALID_SIGNATURE;
+ * \endcode
+ * except (1) it works even if the key's policy does not allow outputting the
+ * bytes, and (2) the comparison will be done in constant time.
+ *
+ * If this function returns an error status other than
+ * #PSA_ERROR_INSUFFICIENT_DATA or #PSA_ERROR_INVALID_SIGNATURE,
+ * the operation enters an error state and must be aborted by calling
+ * psa_key_derivation_abort().
+ *
+ * \param[in,out] operation The key derivation operation object to read from.
+ * \param[in] expected_output Buffer where the output will be written.
+ * \param output_length     Length ot the expected output; this is also the
+ *                          number of bytes that will be read.
+ *
+ * \retval #PSA_SUCCESS
+ * \retval #PSA_ERROR_INVALID_SIGNATURE
+ *         The output was read successfully, but if differs from the expected
+ *         output.
+ * \retval #PSA_ERROR_NOT_PERMITTED
+ *         One of the inputs was a key whose policy didn't allow
+ *         #PSA_KEY_USAGE_VERIFY_DERIVATION.
+ * \retval #PSA_ERROR_INSUFFICIENT_DATA
+ *                          The operation's capacity was less than
+ *                          \p output_length bytes. Note that in this case,
+ *                          the operation'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
+ *         The operation state is not valid (it must be active and completed
+ *         all required input steps).
+ * \retval #PSA_ERROR_INSUFFICIENT_MEMORY
+ * \retval #PSA_ERROR_COMMUNICATION_FAILURE
+ * \retval #PSA_ERROR_HARDWARE_FAILURE
+ * \retval #PSA_ERROR_CORRUPTION_DETECTED
+ * \retval #PSA_ERROR_STORAGE_FAILURE
+ * \retval #PSA_ERROR_BAD_STATE
+ *         The library has not been previously initialized by psa_crypto_init().
+ *         It is implementation-dependent whether a failure to initialize
+ *         results in this error code.
+ */
+psa_status_t psa_key_derivation_verify_bytes(
+    psa_key_derivation_operation_t *operation,
+    const uint8_t *expected_output,
+    size_t output_length);
+
+/** Compare output data from a key derivation operation to an expected value
+ * stored in a key object.
+ *
+ * This function calculates output bytes from a key derivation algorithm and
+ * compares those bytes to an expected value, provided as key of type
+ * #PSA_KEY_TYPE_PASSWORD_HASH.
+ * If you view the key derivation's output as a stream of bytes, this
+ * function destructively reads the number of bytes corresponding the the
+ * length of the expected value from the stream before comparing them.
+ * The operation's capacity decreases by the number of bytes read.
+ *
+ * This is functionally equivalent to exporting the key and calling
+ * psa_key_derivation_verify_bytes() on the result, except that it
+ * works even if the key cannot be exported.
+ *
+ * If this function returns an error status other than
+ * #PSA_ERROR_INSUFFICIENT_DATA or #PSA_ERROR_INVALID_SIGNATURE,
+ * the operation enters an error state and must be aborted by calling
+ * psa_key_derivation_abort().
+ *
+ * \param[in,out] operation The key derivation operation object to read from.
+ * \param[in] expected      A key of type #PSA_KEY_TYPE_PASSWORD_HASH
+ *                          containing the expected output. Its policy must
+ *                          include the #PSA_KEY_USAGE_VERIFY_DERIVATION flag
+ *                          and the permitted algorithm must match the
+ *                          operation. The value of this key was likely
+ *                          computed by a previous call to
+ *                          psa_key_derivation_output_key().
+ *
+ * \retval #PSA_SUCCESS
+ * \retval #PSA_ERROR_INVALID_SIGNATURE
+ *         The output was read successfully, but if differs from the expected
+ *         output.
+ * \retval #PSA_ERROR_INVALID_HANDLE
+ *         The key passed as the expected value does not exist.
+ * \retval #PSA_ERROR_INVALID_ARGUMENT
+ *         The key passed as the expected value has an invalid type.
+ * \retval #PSA_ERROR_NOT_PERMITTED
+ *         The key passed as the expected value does not allow this usage or
+ *         this algorithm; or one of the inputs was a key whose policy didn't
+ *         allow #PSA_KEY_USAGE_VERIFY_DERIVATION.
+ * \retval #PSA_ERROR_INSUFFICIENT_DATA
+ *                          The operation's capacity was less than
+ *                          the length of the expected value. In this case,
+ *                          the operation'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
+ *         The operation state is not valid (it must be active and completed
+ *         all required input steps).
+ * \retval #PSA_ERROR_INSUFFICIENT_MEMORY
+ * \retval #PSA_ERROR_COMMUNICATION_FAILURE
+ * \retval #PSA_ERROR_HARDWARE_FAILURE
+ * \retval #PSA_ERROR_CORRUPTION_DETECTED
+ * \retval #PSA_ERROR_STORAGE_FAILURE
+ * \retval #PSA_ERROR_BAD_STATE
+ *         The library has not been previously initialized by psa_crypto_init().
+ *         It is implementation-dependent whether a failure to initialize
+ *         results in this error code.
+ */
+psa_status_t psa_key_derivation_verify_key(
+    psa_key_derivation_operation_t *operation,
+    psa_key_id_t expected);
+
 /** Abort a key derivation operation.
  *
  * Aborting an operation frees all associated resources except for the \c
diff --git a/include/psa/crypto_config.h b/include/psa/crypto_config.h
index 246e894..eb16492 100644
--- a/include/psa/crypto_config.h
+++ b/include/psa/crypto_config.h
@@ -73,6 +73,9 @@
 #define PSA_WANT_ALG_MD4                        1
 #define PSA_WANT_ALG_MD5                        1
 #define PSA_WANT_ALG_OFB                        1
+/* PBKDF2-HMAC is not yet supported via the PSA API in Mbed TLS.
+ * Note: when adding support, also adjust include/mbedtls/config_psa.h */
+//#define PSA_WANT_ALG_PBKDF2_HMAC                1
 #define PSA_WANT_ALG_RIPEMD160                  1
 #define PSA_WANT_ALG_RSA_OAEP                   1
 #define PSA_WANT_ALG_RSA_PKCS1V15_CRYPT         1
diff --git a/include/psa/crypto_values.h b/include/psa/crypto_values.h
index 9bfd5ab..bfff968 100644
--- a/include/psa/crypto_values.h
+++ b/include/psa/crypto_values.h
@@ -409,11 +409,55 @@
 
 /** A secret for key derivation.
  *
+ * This key type is for high-entropy secrets only. For low-entropy secrets,
+ * #PSA_KEY_TYPE_PASSWORD should be used instead.
+ *
+ * These keys can be used as the #PSA_KEY_DERIVATION_INPUT_SECRET or
+ * #PSA_KEY_DERIVATION_INPUT_PASSWORD input of key derivation algorithms.
+ *
  * The key policy determines which key derivation algorithm the key
  * can be used for.
  */
 #define PSA_KEY_TYPE_DERIVE                         ((psa_key_type_t)0x1200)
 
+/** A low-entropy secret for password hashing or key derivation.
+ *
+ * This key type is suitable for passwords and passphrases which are typically
+ * intended to be memorizable by humans, and have a low entropy relative to
+ * their size. It can be used for randomly generated or derived keys with
+ * maximum or near-maximum entropy, but #PSA_KEY_TYPE_DERIVE is more suitable
+ * for such keys. It is not suitable for passwords with extremely low entropy,
+ * such as numerical PINs.
+ *
+ * These keys can be used as the #PSA_KEY_DERIVATION_INPUT_PASSWORD input of
+ * key derivation algorithms. Algorithms that accept such an input were
+ * designed to accept low-entropy secret and are known as password hashing or
+ * key stretching algorithms.
+ *
+ * These keys cannot be used as the #PSA_KEY_DERIVATION_INPUT_SECRET input of
+ * key derivation algorithms, as the algorithms that take such an input expect
+ * it to be high-entropy.
+ *
+ * The key policy determines which key derivation algorithm the key can be
+ * used for, among the permissible subset defined above.
+ */
+#define PSA_KEY_TYPE_PASSWORD                       ((psa_key_type_t)0x1203)
+
+/** A secret value that can be used to verify a password hash.
+ *
+ * The key policy determines which key derivation algorithm the key
+ * can be used for, among the same permissible subset as for
+ * #PSA_KEY_TYPE_PASSWORD.
+ */
+#define PSA_KEY_TYPE_PASSWORD_HASH                  ((psa_key_type_t)0x1205)
+
+/** A secret value that can be used in when computing a password hash.
+ *
+ * The key policy determines which key derivation algorithm the key
+ * can be used for, among the subset of algorithms that can use pepper.
+ */
+#define PSA_KEY_TYPE_PEPPER                         ((psa_key_type_t)0x1206)
+
 /** Key for a 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
@@ -786,6 +830,24 @@
 #define PSA_ALG_IS_KEY_DERIVATION(alg)                                  \
     (((alg) & PSA_ALG_CATEGORY_MASK) == PSA_ALG_CATEGORY_KEY_DERIVATION)
 
+/** Whether the specified algorithm is a key stretching / password hashing
+ * algorithm.
+ *
+ * A key stretching / password hashing algorithm is a key derivation algorithm
+ * that is suitable for use with a low-entropy secret such as a password.
+ * Equivalently, it's a key derivation algorithm that uses a
+ * #PSA_KEY_DERIVATION_INPUT_PASSWORD input step.
+ *
+ * \param alg An algorithm identifier (value of type #psa_algorithm_t).
+ *
+ * \return 1 if \p alg is a key stretching / passowrd hashing algorithm, 0
+ *         otherwise. This macro may return either 0 or 1 if \p alg is not a
+ *         supported algorithm identifier.
+ */
+#define PSA_ALG_IS_KEY_DERIVATION_STRETCHING(alg)                                  \
+    (PSA_ALG_IS_KEY_DERIVATION(alg) &&              \
+     (alg) & PSA_ALG_KEY_DERIVATION_STRETCHING_FLAG)
+
 #define PSA_ALG_HASH_MASK                       ((psa_algorithm_t)0x000000ff)
 /** MD2 */
 #define PSA_ALG_MD2                             ((psa_algorithm_t)0x02000001)
@@ -1667,6 +1729,67 @@
 #define PSA_ALG_TLS12_PSK_TO_MS_GET_HASH(hkdf_alg)                         \
     (PSA_ALG_CATEGORY_HASH | ((hkdf_alg) & PSA_ALG_HASH_MASK))
 
+/* This flag indicates whether the key derivation algorithm is suitable for
+ * use on low-entropy secrets such as password - these algorithms are also
+ * known as key stretching or password hashing schemes. These are also the
+ * algorithms that accepts inputs of type #PSA_KEY_DERIVATION_INPUT_PASSWORD.
+ *
+ * Those algorithms cannot be combined with a key agreement algorithm.
+ */
+#define PSA_ALG_KEY_DERIVATION_STRETCHING_FLAG  ((psa_algorithm_t)0x00800000)
+
+#define PSA_ALG_PBKDF2_HMAC_BASE                ((psa_algorithm_t)0x08800100)
+/** Macro to build a PBKDF2-HMAC password hashing / key stretching algorithm.
+ *
+ * PBKDF2 is defined by PKCS#5, republished as RFC 8018 (section 5.2).
+ * This macro specifies the PBKDF2 algorithm constructed using a PRF based on
+ * HMAC with the specified hash.
+ * For example, `PSA_ALG_PBKDF2_HMAC(PSA_ALG_SHA256)` specifies PBKDF2
+ * using the PRF HMAC-SHA-256.
+ *
+ * This key derivation algorithm uses the following inputs, which must be
+ * provided in the following order:
+ * - #PSA_KEY_DERIVATION_INPUT_COST is the iteration count.
+ *   This input step must be used exactly once.
+ * - #PSA_KEY_DERIVATION_INPUT_SALT is the salt.
+ *   This input step must be used one or more times; if used several times, the
+ *   inputs will be concatenated. This can be used to build the final salt
+ *   from multiple sources, both public and secret (also known as pepper).
+ * - #PSA_KEY_DERIVATION_INPUT_PASSWORD is the password to be hashed.
+ *   This input step must be used exactly once.
+ *
+ * \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 PBKDF2-HMAC-XXX algorithm.
+ * \return              Unspecified if \p hash_alg is not a supported
+ *                      hash algorithm.
+ */
+#define PSA_ALG_PBKDF2_HMAC(hash_alg)                                  \
+    (PSA_ALG_PBKDF2_HMAC_BASE | ((hash_alg) & PSA_ALG_HASH_MASK))
+
+/** Whether the specified algorithm is a PBKDF2-HMAC algorithm.
+ *
+ * \param alg An algorithm identifier (value of type #psa_algorithm_t).
+ *
+ * \return 1 if \c alg is a PBKDF2-HMAC 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_PBKDF2_HMAC(alg)                                    \
+    (((alg) & ~PSA_ALG_HASH_MASK) == PSA_ALG_PBKDF2_HMAC_BASE)
+
+/** The PBKDF2-AES-CMAC-PRF-128 password hashing / key stretching algorithm.
+ *
+ * PBKDF2 is defined by PKCS#5, republished as RFC 8018 (section 5.2).
+ * This macro specifies the PBKDF2 algorithm constructed using the
+ * AES-CMAC-PRF-128 PRF specified by RFC 4615.
+ *
+ * This key derivation algorithm uses the same inputs as
+ * #PSA_ALG_PBKDF2_HMAC() with the same constraints.
+ */
+#define PSA_ALG_PBKDF2_AES_CMAC_PRF_128         ((psa_algorithm_t)0x08800200)
+
 #define PSA_ALG_KEY_DERIVATION_MASK             ((psa_algorithm_t)0xfe00ffff)
 #define PSA_ALG_KEY_AGREEMENT_MASK              ((psa_algorithm_t)0xffff0000)
 
@@ -1804,6 +1927,18 @@
      (alg & PSA_ALG_AEAD_AT_LEAST_THIS_LENGTH_FLAG) != 0 :  \
      (alg) == PSA_ALG_ANY_HASH)
 
+/** Get the hash used by a composite algorithm.
+ *
+ * \param alg An algorithm identifier (value of type #psa_algorithm_t).
+ *
+ * \return The underlying hash algorithm if alg is a composite algorithm that
+ * uses a hash algorithm.
+ *
+ * \return \c 0 if alg is not a composite algorithm that uses a hash.
+ */
+#define PSA_ALG_GET_HASH(alg) \
+        (((alg) & 0x000000ff) == 0 ? ((psa_algorithm_t)0) : 0x02000000 | ((alg) & 0x000000ff))
+
 /**@}*/
 
 /** \defgroup key_lifetimes Key lifetimes
@@ -2083,10 +2218,34 @@
  */
 #define PSA_KEY_USAGE_VERIFY_HASH               ((psa_key_usage_t)0x00002000)
 
-/** Whether the key may be used to derive other keys.
+/** Whether the key may be used to derive other keys or produce a password
+ * hash.
+ *
+ * This flag allows the key to be used as the input of
+ * psa_key_derivation_input_key() at the step
+ * #PSA_KEY_DERIVATION_INPUT_SECRET of #PSA_KEY_DERIVATION_INPUT_PASSWORD
+ * depending on the algorithm, and allows the use of
+ * psa_key_derivation_output_bytes() or psa_key_derivation_output_key()
+ * at the end of the operation.
  */
 #define PSA_KEY_USAGE_DERIVE                    ((psa_key_usage_t)0x00004000)
 
+/** Whether the key may be used to verify the result of a key derivation,
+ * including password hashing.
+ *
+ * This flag allows the key to be used:
+ *
+ * - for a key of type #PSA_KEY_TYPE_PASSWORD_HASH, as the \c key argument of
+ *   psa_key_derivation_verify_key();
+ * - for a key of type #PSA_KEY_TYPE_PASSWORD (or #PSA_KEY_TYPE_DERIVE), as
+ *   the input to psa_key_derivation_input_key() at the step
+ *   #PSA_KEY_DERIVATION_INPUT_PASSWORD (or #PSA_KEY_DERIVATION_INPUT_SECRET);
+ *   then at the end of the operation use of psa_key_derivation_verify_bytes()
+ *   or psa_key_derivation_verify_key() will be permitted (but not
+ *   psa_key_derivation_output_xxx() unless #PSA_KEY_USAGE_DERIVE is set).
+ */
+#define PSA_KEY_USAGE_VERIFY_DERIVATION         ((psa_key_usage_t)0x00008000)
+
 /**@}*/
 
 /** \defgroup derivation Key derivation
@@ -2102,11 +2261,32 @@
  *
  * The secret can also be a direct input (passed to
  * key_derivation_input_bytes()). In this case, the derivation operation
- * may not be used to derive keys: the operation will only allow
- * psa_key_derivation_output_bytes(), not psa_key_derivation_output_key().
+ * may not be used to derive or verify keys: the operation will only allow
+ * psa_key_derivation_output_bytes() or
+ * psa_key_derivation_verify_bytes() but not
+ * psa_key_derivation_output_key() or
+ * psa_key_derivation_verify_key().
  */
 #define PSA_KEY_DERIVATION_INPUT_SECRET     ((psa_key_derivation_step_t)0x0101)
 
+/** A low-entropy secret input for password hashing / key stretching.
+ *
+ * This is usually a key of type #PSA_KEY_TYPE_PASSWORD (passed to
+ * psa_key_derivation_input_key()) or a direct input (passed to
+ * psa_key_derivation_input_bytes()) that is a password or passphrase. It can
+ * also be high-entropy secret such as a key of type #PSA_KEY_TYPE_DERIVE or
+ * the shared secret resulting from a key agreement.
+ *
+ * The secret can also be a direct input (passed to
+ * key_derivation_input_bytes()). In this case, the derivation operation
+ * may not be used to derive or verify keys: the operation will only allow
+ * psa_key_derivation_output_bytes() or
+ * psa_key_derivation_verify_bytes(), not
+ * psa_key_derivation_output_key() or
+ * psa_key_derivation_verify_key().
+ */
+#define PSA_KEY_DERIVATION_INPUT_PASSWORD   ((psa_key_derivation_step_t)0x0102)
+
 /** A label for key derivation.
  *
  * This should be a direct input.
@@ -2117,7 +2297,8 @@
 /** A salt for key derivation.
  *
  * This should be a direct input.
- * It can also be a key of type #PSA_KEY_TYPE_RAW_DATA.
+ * It can also be a key of type #PSA_KEY_TYPE_RAW_DATA or
+ * #PSA_KEY_TYPE_PEPPER.
  */
 #define PSA_KEY_DERIVATION_INPUT_SALT       ((psa_key_derivation_step_t)0x0202)
 
@@ -2135,6 +2316,12 @@
  */
 #define PSA_KEY_DERIVATION_INPUT_SEED       ((psa_key_derivation_step_t)0x0204)
 
+/** A cost parameter for password hashing / key stretching.
+ *
+ * This must be a direct input, passed to psa_key_derivation_input_integer().
+ */
+#define PSA_KEY_DERIVATION_INPUT_COST       ((psa_key_derivation_step_t)0x0205)
+
 /**@}*/
 
 /** \defgroup helper_macros Helper macros
diff --git a/library/psa_crypto.c b/library/psa_crypto.c
index 5f57c38..2583735 100644
--- a/library/psa_crypto.c
+++ b/library/psa_crypto.c
@@ -1494,6 +1494,7 @@
                              PSA_KEY_USAGE_DECRYPT |
                              PSA_KEY_USAGE_SIGN_HASH |
                              PSA_KEY_USAGE_VERIFY_HASH |
+                             PSA_KEY_USAGE_VERIFY_DERIVATION |
                              PSA_KEY_USAGE_DERIVE ) ) != 0 )
         return( PSA_ERROR_INVALID_ARGUMENT );
 
diff --git a/programs/psa/psa_constant_names.c b/programs/psa/psa_constant_names.c
index 14d4494..b5fea04 100644
--- a/programs/psa/psa_constant_names.c
+++ b/programs/psa/psa_constant_names.c
@@ -52,12 +52,6 @@
 }
 #endif
 
-/* 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)
diff --git a/programs/psa/psa_constant_names_generated.c b/programs/psa/psa_constant_names_generated.c
index dcbe87f..bcb95f8 100644
--- a/programs/psa/psa_constant_names_generated.c
+++ b/programs/psa/psa_constant_names_generated.c
@@ -113,6 +113,9 @@
     case PSA_KEY_TYPE_ECC_PUBLIC_KEY_BASE: append(&buffer, buffer_size, &required_size, "PSA_KEY_TYPE_ECC_PUBLIC_KEY_BASE", 32); break;
     case PSA_KEY_TYPE_HMAC: append(&buffer, buffer_size, &required_size, "PSA_KEY_TYPE_HMAC", 17); break;
     case PSA_KEY_TYPE_NONE: append(&buffer, buffer_size, &required_size, "PSA_KEY_TYPE_NONE", 17); break;
+    case PSA_KEY_TYPE_PASSWORD: append(&buffer, buffer_size, &required_size, "PSA_KEY_TYPE_PASSWORD", 21); break;
+    case PSA_KEY_TYPE_PASSWORD_HASH: append(&buffer, buffer_size, &required_size, "PSA_KEY_TYPE_PASSWORD_HASH", 26); break;
+    case PSA_KEY_TYPE_PEPPER: append(&buffer, buffer_size, &required_size, "PSA_KEY_TYPE_PEPPER", 19); break;
     case PSA_KEY_TYPE_RAW_DATA: append(&buffer, buffer_size, &required_size, "PSA_KEY_TYPE_RAW_DATA", 21); break;
     case PSA_KEY_TYPE_RSA_KEY_PAIR: append(&buffer, buffer_size, &required_size, "PSA_KEY_TYPE_RSA_KEY_PAIR", 25); break;
     case PSA_KEY_TYPE_RSA_PUBLIC_KEY: append(&buffer, buffer_size, &required_size, "PSA_KEY_TYPE_RSA_PUBLIC_KEY", 27); break;
@@ -221,6 +224,8 @@
     case PSA_ALG_MD4: append(&buffer, buffer_size, &required_size, "PSA_ALG_MD4", 11); break;
     case PSA_ALG_MD5: append(&buffer, buffer_size, &required_size, "PSA_ALG_MD5", 11); break;
     case PSA_ALG_OFB: append(&buffer, buffer_size, &required_size, "PSA_ALG_OFB", 11); break;
+    case PSA_ALG_PBKDF2_AES_CMAC_PRF_128: append(&buffer, buffer_size, &required_size, "PSA_ALG_PBKDF2_AES_CMAC_PRF_128", 31); break;
+    case PSA_ALG_PBKDF2_HMAC_BASE: append(&buffer, buffer_size, &required_size, "PSA_ALG_PBKDF2_HMAC_BASE", 24); break;
     case PSA_ALG_PURE_EDDSA: append(&buffer, buffer_size, &required_size, "PSA_ALG_PURE_EDDSA", 18); break;
     case PSA_ALG_RIPEMD160: append(&buffer, buffer_size, &required_size, "PSA_ALG_RIPEMD160", 17); break;
     case PSA_ALG_RSA_OAEP_BASE: append(&buffer, buffer_size, &required_size, "PSA_ALG_RSA_OAEP_BASE", 21); break;
@@ -286,6 +291,13 @@
                             psa_hash_algorithm_name,
                             PSA_ALG_GET_HASH(core_alg));
             append(&buffer, buffer_size, &required_size, ")", 1);
+        } else if (PSA_ALG_IS_PBKDF2_HMAC(core_alg)) {
+            append(&buffer, buffer_size, &required_size,
+                   "PSA_ALG_PBKDF2_HMAC(", 19 + 1);
+            append_with_alg(&buffer, buffer_size, &required_size,
+                            psa_hash_algorithm_name,
+                            PSA_ALG_GET_HASH(core_alg));
+            append(&buffer, buffer_size, &required_size, ")", 1);
         } else if (PSA_ALG_IS_RSA_OAEP(core_alg)) {
             append(&buffer, buffer_size, &required_size,
                    "PSA_ALG_RSA_OAEP(", 16 + 1);
@@ -394,6 +406,13 @@
         append(&buffer, buffer_size, &required_size, "PSA_KEY_USAGE_SIGN_HASH", 23);
         usage ^= PSA_KEY_USAGE_SIGN_HASH;
     }
+    if (usage & PSA_KEY_USAGE_VERIFY_DERIVATION) {
+        if (required_size != 0) {
+            append(&buffer, buffer_size, &required_size, " | ", 3);
+        }
+        append(&buffer, buffer_size, &required_size, "PSA_KEY_USAGE_VERIFY_DERIVATION", 31);
+        usage ^= PSA_KEY_USAGE_VERIFY_DERIVATION;
+    }
     if (usage & PSA_KEY_USAGE_VERIFY_HASH) {
         if (required_size != 0) {
             append(&buffer, buffer_size, &required_size, " | ", 3);
diff --git a/scripts/mbedtls_dev/crypto_knowledge.py b/scripts/mbedtls_dev/crypto_knowledge.py
index 500acea..aa52790 100644
--- a/scripts/mbedtls_dev/crypto_knowledge.py
+++ b/scripts/mbedtls_dev/crypto_knowledge.py
@@ -89,6 +89,9 @@
         'PSA_KEY_TYPE_DERIVE': (120, 128), # sample
         'PSA_KEY_TYPE_DES': (64, 128, 192), # exhaustive
         'PSA_KEY_TYPE_HMAC': (128, 160, 224, 256, 384, 512), # standard size for each supported hash
+        'PSA_KEY_TYPE_PASSWORD': (48, 168, 336), # sample
+        'PSA_KEY_TYPE_PASSWORD_HASH': (128, 256), # sample
+        'PSA_KEY_TYPE_PEPPER': (128, 256), # sample
         'PSA_KEY_TYPE_RAW_DATA': (8, 40, 128), # sample
         'PSA_KEY_TYPE_RSA_KEY_PAIR': (1024, 1536), # small sample
     }
diff --git a/tests/suites/test_suite_psa_crypto_not_supported.generated.data b/tests/suites/test_suite_psa_crypto_not_supported.generated.data
index e39c8ed..23ce19f 100644
--- a/tests/suites/test_suite_psa_crypto_not_supported.generated.data
+++ b/tests/suites/test_suite_psa_crypto_not_supported.generated.data
@@ -152,6 +152,62 @@
 depends_on:!PSA_WANT_KEY_TYPE_HMAC
 generate_not_supported:PSA_KEY_TYPE_HMAC:512
 
+PSA import PASSWORD 48-bit not supported
+depends_on:!PSA_WANT_KEY_TYPE_PASSWORD:DEPENDENCY_NOT_IMPLEMENTED_YET
+import_not_supported:PSA_KEY_TYPE_PASSWORD:"486572650069"
+
+PSA generate PASSWORD 48-bit not supported
+depends_on:!PSA_WANT_KEY_TYPE_PASSWORD:DEPENDENCY_NOT_IMPLEMENTED_YET
+generate_not_supported:PSA_KEY_TYPE_PASSWORD:48
+
+PSA import PASSWORD 168-bit not supported
+depends_on:!PSA_WANT_KEY_TYPE_PASSWORD:DEPENDENCY_NOT_IMPLEMENTED_YET
+import_not_supported:PSA_KEY_TYPE_PASSWORD:"48657265006973206b6579a0646174614865726500"
+
+PSA generate PASSWORD 168-bit not supported
+depends_on:!PSA_WANT_KEY_TYPE_PASSWORD:DEPENDENCY_NOT_IMPLEMENTED_YET
+generate_not_supported:PSA_KEY_TYPE_PASSWORD:168
+
+PSA import PASSWORD 336-bit not supported
+depends_on:!PSA_WANT_KEY_TYPE_PASSWORD:DEPENDENCY_NOT_IMPLEMENTED_YET
+import_not_supported:PSA_KEY_TYPE_PASSWORD:"48657265006973206b6579a06461746148657265006973206b6579a06461746148657265006973206b65"
+
+PSA generate PASSWORD 336-bit not supported
+depends_on:!PSA_WANT_KEY_TYPE_PASSWORD:DEPENDENCY_NOT_IMPLEMENTED_YET
+generate_not_supported:PSA_KEY_TYPE_PASSWORD:336
+
+PSA import PASSWORD_HASH 128-bit not supported
+depends_on:!PSA_WANT_KEY_TYPE_PASSWORD_HASH:DEPENDENCY_NOT_IMPLEMENTED_YET
+import_not_supported:PSA_KEY_TYPE_PASSWORD_HASH:"48657265006973206b6579a064617461"
+
+PSA generate PASSWORD_HASH 128-bit not supported
+depends_on:!PSA_WANT_KEY_TYPE_PASSWORD_HASH:DEPENDENCY_NOT_IMPLEMENTED_YET
+generate_not_supported:PSA_KEY_TYPE_PASSWORD_HASH:128
+
+PSA import PASSWORD_HASH 256-bit not supported
+depends_on:!PSA_WANT_KEY_TYPE_PASSWORD_HASH:DEPENDENCY_NOT_IMPLEMENTED_YET
+import_not_supported:PSA_KEY_TYPE_PASSWORD_HASH:"48657265006973206b6579a06461746148657265006973206b6579a064617461"
+
+PSA generate PASSWORD_HASH 256-bit not supported
+depends_on:!PSA_WANT_KEY_TYPE_PASSWORD_HASH:DEPENDENCY_NOT_IMPLEMENTED_YET
+generate_not_supported:PSA_KEY_TYPE_PASSWORD_HASH:256
+
+PSA import PEPPER 128-bit not supported
+depends_on:!PSA_WANT_KEY_TYPE_PEPPER:DEPENDENCY_NOT_IMPLEMENTED_YET
+import_not_supported:PSA_KEY_TYPE_PEPPER:"48657265006973206b6579a064617461"
+
+PSA generate PEPPER 128-bit not supported
+depends_on:!PSA_WANT_KEY_TYPE_PEPPER:DEPENDENCY_NOT_IMPLEMENTED_YET
+generate_not_supported:PSA_KEY_TYPE_PEPPER:128
+
+PSA import PEPPER 256-bit not supported
+depends_on:!PSA_WANT_KEY_TYPE_PEPPER:DEPENDENCY_NOT_IMPLEMENTED_YET
+import_not_supported:PSA_KEY_TYPE_PEPPER:"48657265006973206b6579a06461746148657265006973206b6579a064617461"
+
+PSA generate PEPPER 256-bit not supported
+depends_on:!PSA_WANT_KEY_TYPE_PEPPER:DEPENDENCY_NOT_IMPLEMENTED_YET
+generate_not_supported:PSA_KEY_TYPE_PEPPER:256
+
 PSA import RSA_KEY_PAIR 1024-bit not supported
 depends_on:!PSA_WANT_KEY_TYPE_RSA_KEY_PAIR
 import_not_supported:PSA_KEY_TYPE_RSA_KEY_PAIR:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24"
diff --git a/tests/suites/test_suite_psa_crypto_storage_format.current.data b/tests/suites/test_suite_psa_crypto_storage_format.current.data
index f74d0e2..732b80b 100644
--- a/tests/suites/test_suite_psa_crypto_storage_format.current.data
+++ b/tests/suites/test_suite_psa_crypto_storage_format.current.data
@@ -28,6 +28,10 @@
 depends_on:PSA_WANT_KEY_TYPE_RAW_DATA
 key_storage_save:0x0001:PSA_KEY_TYPE_RAW_DATA:8:PSA_KEY_USAGE_SIGN_HASH:0x0000:0x0000:"4b":"505341004b455900000000000100000001100800001000000000000000000000010000004b"
 
+PSA storage save: usage: VERIFY_DERIVATION
+depends_on:PSA_WANT_KEY_TYPE_RAW_DATA
+key_storage_save:0x0001:PSA_KEY_TYPE_RAW_DATA:8:PSA_KEY_USAGE_VERIFY_DERIVATION:0x0000:0x0000:"4b":"505341004b455900000000000100000001100800008000000000000000000000010000004b"
+
 PSA storage save: usage: VERIFY_HASH
 depends_on:PSA_WANT_KEY_TYPE_RAW_DATA
 key_storage_save:0x0001:PSA_KEY_TYPE_RAW_DATA:8:PSA_KEY_USAGE_VERIFY_HASH:0x0000:0x0000:"4b":"505341004b455900000000000100000001100800002000000000000000000000010000004b"
@@ -52,9 +56,13 @@
 depends_on:PSA_WANT_KEY_TYPE_RAW_DATA
 key_storage_save:0x0001:PSA_KEY_TYPE_RAW_DATA:8:PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_SIGN_HASH:0x0000:0x0000:"4b":"505341004b455900000000000100000001100800011000000000000000000000010000004b"
 
-PSA storage save: usage: SIGN_HASH | VERIFY_HASH
+PSA storage save: usage: SIGN_HASH | VERIFY_DERIVATION
 depends_on:PSA_WANT_KEY_TYPE_RAW_DATA
-key_storage_save:0x0001:PSA_KEY_TYPE_RAW_DATA:8:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH:0x0000:0x0000:"4b":"505341004b455900000000000100000001100800003000000000000000000000010000004b"
+key_storage_save:0x0001:PSA_KEY_TYPE_RAW_DATA:8:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_DERIVATION:0x0000:0x0000:"4b":"505341004b455900000000000100000001100800009000000000000000000000010000004b"
+
+PSA storage save: usage: VERIFY_DERIVATION | VERIFY_HASH
+depends_on:PSA_WANT_KEY_TYPE_RAW_DATA
+key_storage_save:0x0001:PSA_KEY_TYPE_RAW_DATA:8:PSA_KEY_USAGE_VERIFY_DERIVATION | PSA_KEY_USAGE_VERIFY_HASH:0x0000:0x0000:"4b":"505341004b45590000000000010000000110080000a000000000000000000000010000004b"
 
 PSA storage save: usage: VERIFY_HASH | COPY
 depends_on:PSA_WANT_KEY_TYPE_RAW_DATA
@@ -62,7 +70,7 @@
 
 PSA storage save: usage: all known
 depends_on:PSA_WANT_KEY_TYPE_RAW_DATA
-key_storage_save:0x0001:PSA_KEY_TYPE_RAW_DATA:8:PSA_KEY_USAGE_COPY | PSA_KEY_USAGE_DECRYPT | PSA_KEY_USAGE_DERIVE | PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH:0x0000:0x0000:"4b":"505341004b455900000000000100000001100800037300000000000000000000010000004b"
+key_storage_save:0x0001:PSA_KEY_TYPE_RAW_DATA:8:PSA_KEY_USAGE_COPY | PSA_KEY_USAGE_DECRYPT | PSA_KEY_USAGE_DERIVE | PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_DERIVATION | PSA_KEY_USAGE_VERIFY_HASH:0x0000:0x0000:"4b":"505341004b45590000000000010000000110080003f300000000000000000000010000004b"
 
 PSA storage save: type: AES 128-bit
 depends_on:PSA_WANT_KEY_TYPE_AES
@@ -148,6 +156,34 @@
 depends_on:PSA_WANT_KEY_TYPE_HMAC
 key_storage_save:0x0001:PSA_KEY_TYPE_HMAC:512:PSA_KEY_USAGE_EXPORT:0x0000:0x0000:"48657265006973206b6579a06461746148657265006973206b6579a06461746148657265006973206b6579a06461746148657265006973206b6579a064617461":"505341004b4559000000000001000000001100020100000000000000000000004000000048657265006973206b6579a06461746148657265006973206b6579a06461746148657265006973206b6579a06461746148657265006973206b6579a064617461"
 
+PSA storage save: type: PASSWORD 48-bit
+depends_on:PSA_WANT_KEY_TYPE_PASSWORD
+key_storage_save:0x0001:PSA_KEY_TYPE_PASSWORD:48:PSA_KEY_USAGE_EXPORT:0x0000:0x0000:"486572650069":"505341004b45590000000000010000000312300001000000000000000000000006000000486572650069"
+
+PSA storage save: type: PASSWORD 168-bit
+depends_on:PSA_WANT_KEY_TYPE_PASSWORD
+key_storage_save:0x0001:PSA_KEY_TYPE_PASSWORD:168:PSA_KEY_USAGE_EXPORT:0x0000:0x0000:"48657265006973206b6579a0646174614865726500":"505341004b45590000000000010000000312a8000100000000000000000000001500000048657265006973206b6579a0646174614865726500"
+
+PSA storage save: type: PASSWORD 336-bit
+depends_on:PSA_WANT_KEY_TYPE_PASSWORD
+key_storage_save:0x0001:PSA_KEY_TYPE_PASSWORD:336:PSA_KEY_USAGE_EXPORT:0x0000:0x0000:"48657265006973206b6579a06461746148657265006973206b6579a06461746148657265006973206b65":"505341004b4559000000000001000000031250010100000000000000000000002a00000048657265006973206b6579a06461746148657265006973206b6579a06461746148657265006973206b65"
+
+PSA storage save: type: PASSWORD_HASH 128-bit
+depends_on:PSA_WANT_KEY_TYPE_PASSWORD_HASH
+key_storage_save:0x0001:PSA_KEY_TYPE_PASSWORD_HASH:128:PSA_KEY_USAGE_EXPORT:0x0000:0x0000:"48657265006973206b6579a064617461":"505341004b4559000000000001000000051280000100000000000000000000001000000048657265006973206b6579a064617461"
+
+PSA storage save: type: PASSWORD_HASH 256-bit
+depends_on:PSA_WANT_KEY_TYPE_PASSWORD_HASH
+key_storage_save:0x0001:PSA_KEY_TYPE_PASSWORD_HASH:256:PSA_KEY_USAGE_EXPORT:0x0000:0x0000:"48657265006973206b6579a06461746148657265006973206b6579a064617461":"505341004b4559000000000001000000051200010100000000000000000000002000000048657265006973206b6579a06461746148657265006973206b6579a064617461"
+
+PSA storage save: type: PEPPER 128-bit
+depends_on:PSA_WANT_KEY_TYPE_PEPPER
+key_storage_save:0x0001:PSA_KEY_TYPE_PEPPER:128:PSA_KEY_USAGE_EXPORT:0x0000:0x0000:"48657265006973206b6579a064617461":"505341004b4559000000000001000000061280000100000000000000000000001000000048657265006973206b6579a064617461"
+
+PSA storage save: type: PEPPER 256-bit
+depends_on:PSA_WANT_KEY_TYPE_PEPPER
+key_storage_save:0x0001:PSA_KEY_TYPE_PEPPER:256:PSA_KEY_USAGE_EXPORT:0x0000:0x0000:"48657265006973206b6579a06461746148657265006973206b6579a064617461":"505341004b4559000000000001000000061200010100000000000000000000002000000048657265006973206b6579a06461746148657265006973206b6579a064617461"
+
 PSA storage save: type: RAW_DATA 8-bit
 depends_on:PSA_WANT_KEY_TYPE_RAW_DATA
 key_storage_save:0x0001:PSA_KEY_TYPE_RAW_DATA:8:PSA_KEY_USAGE_EXPORT:0x0000:0x0000:"48":"505341004b4559000000000001000000011008000100000000000000000000000100000048"
@@ -584,6 +620,14 @@
 depends_on:PSA_WANT_ALG_OFB:PSA_WANT_KEY_TYPE_RAW_DATA
 key_storage_save:0x0001:PSA_KEY_TYPE_RAW_DATA:8:PSA_KEY_USAGE_EXPORT:0x0000:PSA_ALG_OFB:"4c":"505341004b45590000000000010000000110080001000000000000000012c004010000004c"
 
+PSA storage save: alg: PSA_ALG_PBKDF2_AES_CMAC_PRF_128
+depends_on:PSA_WANT_ALG_PBKDF2_AES_CMAC_PRF_128:PSA_WANT_KEY_TYPE_RAW_DATA
+key_storage_save:0x0001:PSA_KEY_TYPE_RAW_DATA:8:PSA_KEY_USAGE_EXPORT:PSA_ALG_PBKDF2_AES_CMAC_PRF_128:0x0000:"4b":"505341004b455900000000000100000001100800010000000002800800000000010000004b"
+
+PSA storage save: alg2: PSA_ALG_PBKDF2_AES_CMAC_PRF_128
+depends_on:PSA_WANT_ALG_PBKDF2_AES_CMAC_PRF_128:PSA_WANT_KEY_TYPE_RAW_DATA
+key_storage_save:0x0001:PSA_KEY_TYPE_RAW_DATA:8:PSA_KEY_USAGE_EXPORT:0x0000:PSA_ALG_PBKDF2_AES_CMAC_PRF_128:"4c":"505341004b455900000000000100000001100800010000000000000000028008010000004c"
+
 PSA storage save: alg: PSA_ALG_PURE_EDDSA
 depends_on:PSA_WANT_ALG_PURE_EDDSA:PSA_WANT_KEY_TYPE_RAW_DATA
 key_storage_save:0x0001:PSA_KEY_TYPE_RAW_DATA:8:PSA_KEY_USAGE_EXPORT:PSA_ALG_PURE_EDDSA:0x0000:"4b":"505341004b455900000000000100000001100800010000000008000600000000010000004b"
diff --git a/tests/suites/test_suite_psa_crypto_storage_format.v0.data b/tests/suites/test_suite_psa_crypto_storage_format.v0.data
index 2b2f1b7..82f55dd 100644
--- a/tests/suites/test_suite_psa_crypto_storage_format.v0.data
+++ b/tests/suites/test_suite_psa_crypto_storage_format.v0.data
@@ -28,6 +28,10 @@
 depends_on:PSA_WANT_KEY_TYPE_RAW_DATA
 key_storage_read:0x0001:PSA_KEY_TYPE_RAW_DATA:8:PSA_KEY_USAGE_SIGN_HASH:0x0000:0x0000:"4b":"505341004b455900000000000100000001100800001000000000000000000000010000004b":0
 
+PSA storage read: usage: VERIFY_DERIVATION
+depends_on:PSA_WANT_KEY_TYPE_RAW_DATA
+key_storage_read:0x0001:PSA_KEY_TYPE_RAW_DATA:8:PSA_KEY_USAGE_VERIFY_DERIVATION:0x0000:0x0000:"4b":"505341004b455900000000000100000001100800008000000000000000000000010000004b":0
+
 PSA storage read: usage: VERIFY_HASH
 depends_on:PSA_WANT_KEY_TYPE_RAW_DATA
 key_storage_read:0x0001:PSA_KEY_TYPE_RAW_DATA:8:PSA_KEY_USAGE_VERIFY_HASH:0x0000:0x0000:"4b":"505341004b455900000000000100000001100800002000000000000000000000010000004b":0
@@ -52,9 +56,13 @@
 depends_on:PSA_WANT_KEY_TYPE_RAW_DATA
 key_storage_read:0x0001:PSA_KEY_TYPE_RAW_DATA:8:PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_SIGN_HASH:0x0000:0x0000:"4b":"505341004b455900000000000100000001100800011000000000000000000000010000004b":0
 
-PSA storage read: usage: SIGN_HASH | VERIFY_HASH
+PSA storage read: usage: SIGN_HASH | VERIFY_DERIVATION
 depends_on:PSA_WANT_KEY_TYPE_RAW_DATA
-key_storage_read:0x0001:PSA_KEY_TYPE_RAW_DATA:8:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH:0x0000:0x0000:"4b":"505341004b455900000000000100000001100800003000000000000000000000010000004b":0
+key_storage_read:0x0001:PSA_KEY_TYPE_RAW_DATA:8:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_DERIVATION:0x0000:0x0000:"4b":"505341004b455900000000000100000001100800009000000000000000000000010000004b":0
+
+PSA storage read: usage: VERIFY_DERIVATION | VERIFY_HASH
+depends_on:PSA_WANT_KEY_TYPE_RAW_DATA
+key_storage_read:0x0001:PSA_KEY_TYPE_RAW_DATA:8:PSA_KEY_USAGE_VERIFY_DERIVATION | PSA_KEY_USAGE_VERIFY_HASH:0x0000:0x0000:"4b":"505341004b45590000000000010000000110080000a000000000000000000000010000004b":0
 
 PSA storage read: usage: VERIFY_HASH | COPY
 depends_on:PSA_WANT_KEY_TYPE_RAW_DATA
@@ -62,7 +70,7 @@
 
 PSA storage read: usage: all known
 depends_on:PSA_WANT_KEY_TYPE_RAW_DATA
-key_storage_read:0x0001:PSA_KEY_TYPE_RAW_DATA:8:PSA_KEY_USAGE_COPY | PSA_KEY_USAGE_DECRYPT | PSA_KEY_USAGE_DERIVE | PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH:0x0000:0x0000:"4b":"505341004b455900000000000100000001100800037300000000000000000000010000004b":0
+key_storage_read:0x0001:PSA_KEY_TYPE_RAW_DATA:8:PSA_KEY_USAGE_COPY | PSA_KEY_USAGE_DECRYPT | PSA_KEY_USAGE_DERIVE | PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_DERIVATION | PSA_KEY_USAGE_VERIFY_HASH:0x0000:0x0000:"4b":"505341004b45590000000000010000000110080003f300000000000000000000010000004b":0
 
 PSA storage read: type: AES 128-bit
 depends_on:PSA_WANT_KEY_TYPE_AES
@@ -148,6 +156,34 @@
 depends_on:PSA_WANT_KEY_TYPE_HMAC
 key_storage_read:0x0001:PSA_KEY_TYPE_HMAC:512:PSA_KEY_USAGE_EXPORT:0x0000:0x0000:"48657265006973206b6579a06461746148657265006973206b6579a06461746148657265006973206b6579a06461746148657265006973206b6579a064617461":"505341004b4559000000000001000000001100020100000000000000000000004000000048657265006973206b6579a06461746148657265006973206b6579a06461746148657265006973206b6579a06461746148657265006973206b6579a064617461":1
 
+PSA storage read: type: PASSWORD 48-bit
+depends_on:PSA_WANT_KEY_TYPE_PASSWORD
+key_storage_read:0x0001:PSA_KEY_TYPE_PASSWORD:48:PSA_KEY_USAGE_EXPORT:0x0000:0x0000:"486572650069":"505341004b45590000000000010000000312300001000000000000000000000006000000486572650069":1
+
+PSA storage read: type: PASSWORD 168-bit
+depends_on:PSA_WANT_KEY_TYPE_PASSWORD
+key_storage_read:0x0001:PSA_KEY_TYPE_PASSWORD:168:PSA_KEY_USAGE_EXPORT:0x0000:0x0000:"48657265006973206b6579a0646174614865726500":"505341004b45590000000000010000000312a8000100000000000000000000001500000048657265006973206b6579a0646174614865726500":1
+
+PSA storage read: type: PASSWORD 336-bit
+depends_on:PSA_WANT_KEY_TYPE_PASSWORD
+key_storage_read:0x0001:PSA_KEY_TYPE_PASSWORD:336:PSA_KEY_USAGE_EXPORT:0x0000:0x0000:"48657265006973206b6579a06461746148657265006973206b6579a06461746148657265006973206b65":"505341004b4559000000000001000000031250010100000000000000000000002a00000048657265006973206b6579a06461746148657265006973206b6579a06461746148657265006973206b65":1
+
+PSA storage read: type: PASSWORD_HASH 128-bit
+depends_on:PSA_WANT_KEY_TYPE_PASSWORD_HASH
+key_storage_read:0x0001:PSA_KEY_TYPE_PASSWORD_HASH:128:PSA_KEY_USAGE_EXPORT:0x0000:0x0000:"48657265006973206b6579a064617461":"505341004b4559000000000001000000051280000100000000000000000000001000000048657265006973206b6579a064617461":1
+
+PSA storage read: type: PASSWORD_HASH 256-bit
+depends_on:PSA_WANT_KEY_TYPE_PASSWORD_HASH
+key_storage_read:0x0001:PSA_KEY_TYPE_PASSWORD_HASH:256:PSA_KEY_USAGE_EXPORT:0x0000:0x0000:"48657265006973206b6579a06461746148657265006973206b6579a064617461":"505341004b4559000000000001000000051200010100000000000000000000002000000048657265006973206b6579a06461746148657265006973206b6579a064617461":1
+
+PSA storage read: type: PEPPER 128-bit
+depends_on:PSA_WANT_KEY_TYPE_PEPPER
+key_storage_read:0x0001:PSA_KEY_TYPE_PEPPER:128:PSA_KEY_USAGE_EXPORT:0x0000:0x0000:"48657265006973206b6579a064617461":"505341004b4559000000000001000000061280000100000000000000000000001000000048657265006973206b6579a064617461":1
+
+PSA storage read: type: PEPPER 256-bit
+depends_on:PSA_WANT_KEY_TYPE_PEPPER
+key_storage_read:0x0001:PSA_KEY_TYPE_PEPPER:256:PSA_KEY_USAGE_EXPORT:0x0000:0x0000:"48657265006973206b6579a06461746148657265006973206b6579a064617461":"505341004b4559000000000001000000061200010100000000000000000000002000000048657265006973206b6579a06461746148657265006973206b6579a064617461":1
+
 PSA storage read: type: RAW_DATA 8-bit
 depends_on:PSA_WANT_KEY_TYPE_RAW_DATA
 key_storage_read:0x0001:PSA_KEY_TYPE_RAW_DATA:8:PSA_KEY_USAGE_EXPORT:0x0000:0x0000:"48":"505341004b4559000000000001000000011008000100000000000000000000000100000048":0
@@ -584,6 +620,14 @@
 depends_on:PSA_WANT_ALG_OFB:PSA_WANT_KEY_TYPE_RAW_DATA
 key_storage_read:0x0001:PSA_KEY_TYPE_RAW_DATA:8:PSA_KEY_USAGE_EXPORT:0x0000:PSA_ALG_OFB:"4c":"505341004b45590000000000010000000110080001000000000000000012c004010000004c":0
 
+PSA storage read: alg: PSA_ALG_PBKDF2_AES_CMAC_PRF_128
+depends_on:PSA_WANT_ALG_PBKDF2_AES_CMAC_PRF_128:PSA_WANT_KEY_TYPE_RAW_DATA
+key_storage_read:0x0001:PSA_KEY_TYPE_RAW_DATA:8:PSA_KEY_USAGE_EXPORT:PSA_ALG_PBKDF2_AES_CMAC_PRF_128:0x0000:"4b":"505341004b455900000000000100000001100800010000000002800800000000010000004b":0
+
+PSA storage read: alg2: PSA_ALG_PBKDF2_AES_CMAC_PRF_128
+depends_on:PSA_WANT_ALG_PBKDF2_AES_CMAC_PRF_128:PSA_WANT_KEY_TYPE_RAW_DATA
+key_storage_read:0x0001:PSA_KEY_TYPE_RAW_DATA:8:PSA_KEY_USAGE_EXPORT:0x0000:PSA_ALG_PBKDF2_AES_CMAC_PRF_128:"4c":"505341004b455900000000000100000001100800010000000000000000028008010000004c":0
+
 PSA storage read: alg: PSA_ALG_PURE_EDDSA
 depends_on:PSA_WANT_ALG_PURE_EDDSA:PSA_WANT_KEY_TYPE_RAW_DATA
 key_storage_read:0x0001:PSA_KEY_TYPE_RAW_DATA:8:PSA_KEY_USAGE_EXPORT:PSA_ALG_PURE_EDDSA:0x0000:"4b":"505341004b455900000000000100000001100800010000000008000600000000010000004b":0