Merge pull request #154 from yanesca/iotcrypt-789-update-tls-prf-to-multipart

Update TLS 1.2 PRF to multipart API
diff --git a/include/psa/crypto_extra.h b/include/psa/crypto_extra.h
index b08f46d..0ab5892 100644
--- a/include/psa/crypto_extra.h
+++ b/include/psa/crypto_extra.h
@@ -224,6 +224,7 @@
 psa_status_t mbedtls_psa_inject_entropy(const unsigned char *seed,
                                         size_t seed_size);
 
+#if defined(PSA_PRE_1_0_KEY_DERIVATION)
 /** Set up a key derivation operation.
  *
  * FIMXE This function is no longer part of the official API. Its prototype
@@ -280,9 +281,7 @@
                                 const uint8_t *label,
                                 size_t label_length,
                                 size_t capacity);
-
-/* FIXME Deprecated. Remove this as soon as all the tests are updated. */
-#define PSA_ALG_SELECT_RAW                      ((psa_algorithm_t)0x31000001)
+#endif /* PSA_PRE_1_0_KEY_DERIVATION */
 
 /** \addtogroup crypto_types
  * @{
diff --git a/include/psa/crypto_struct.h b/include/psa/crypto_struct.h
index 977b021..fdf78a8 100644
--- a/include/psa/crypto_struct.h
+++ b/include/psa/crypto_struct.h
@@ -191,7 +191,19 @@
 } psa_hkdf_key_derivation_t;
 #endif /* MBEDTLS_MD_C */
 
+/*
+ * If this option is not turned on, then the function `psa_key_derivation()`
+ * is removed. And the new psa_tls12_prf_key_derivation_t context is used along
+ * with the corresponding new API.
+ *
+ * The sole purpose of this option is to make the transition to the new API
+ * smoother. Once the transition is complete it can and should be removed
+ * along with the old API and its implementation.
+ */
+#define PSA_PRE_1_0_KEY_DERIVATION
+
 #if defined(MBEDTLS_MD_C)
+#if defined(PSA_PRE_1_0_KEY_DERIVATION)
 typedef struct psa_tls12_prf_key_derivation_s
 {
     /* The TLS 1.2 PRF uses the key for each HMAC iteration,
@@ -220,6 +232,43 @@
     uint8_t block_number;
 
 } psa_tls12_prf_key_derivation_t;
+#else
+
+typedef enum
+{
+    TLS12_PRF_STATE_INIT,       /* no input provided */
+    TLS12_PRF_STATE_SEED_SET,   /* seed has been set */
+    TLS12_PRF_STATE_KEY_SET,    /* key has been set */
+    TLS12_PRF_STATE_LABEL_SET,  /* label has been set */
+    TLS12_PRF_STATE_OUTPUT      /* output has been started */
+} psa_tls12_prf_key_derivation_state_t;
+
+typedef struct psa_tls12_prf_key_derivation_s
+{
+#if PSA_HASH_MAX_SIZE > 0xff
+#error "PSA_HASH_MAX_SIZE does not fit in uint8_t"
+#endif
+
+    /* Indicates how many bytes in the current HMAC block have
+     * not yet been read by the user. */
+    uint8_t left_in_block;
+
+    /* The 1-based number of the block. */
+    uint8_t block_number;
+
+    psa_tls12_prf_key_derivation_state_t state;
+
+    uint8_t *seed;
+    size_t seed_length;
+    uint8_t *label;
+    size_t label_length;
+    psa_hmac_internal_data hmac;
+    uint8_t Ai[PSA_HASH_MAX_SIZE];
+
+    /* `HMAC_hash( prk, A(i) + seed )` in the notation of RFC 5246, Sect. 5. */
+    uint8_t output_block[PSA_HASH_MAX_SIZE];
+} psa_tls12_prf_key_derivation_t;
+#endif /* PSA_PRE_1_0_KEY_DERIVATION */
 #endif /* MBEDTLS_MD_C */
 
 struct psa_key_derivation_s
@@ -228,11 +277,8 @@
     size_t capacity;
     union
     {
-        struct
-        {
-            uint8_t *data;
-            size_t size;
-        } buffer;
+        /* Make the union non-empty even with no supported algorithms. */
+        uint8_t dummy;
 #if defined(MBEDTLS_MD_C)
         psa_hkdf_key_derivation_t hkdf;
         psa_tls12_prf_key_derivation_t tls12_prf;
@@ -240,7 +286,8 @@
     } ctx;
 };
 
-#define PSA_KEY_DERIVATION_OPERATION_INIT {0, 0, {{0, 0}}}
+/* This only zeroes out the first byte in the union, the rest is unspecified. */
+#define PSA_KEY_DERIVATION_OPERATION_INIT {0, 0, {0}}
 static inline struct psa_key_derivation_s psa_key_derivation_operation_init( void )
 {
     const struct psa_key_derivation_s v = PSA_KEY_DERIVATION_OPERATION_INIT;
diff --git a/include/psa/crypto_values.h b/include/psa/crypto_values.h
index e9fb9ad..19dc28b 100644
--- a/include/psa/crypto_values.h
+++ b/include/psa/crypto_values.h
@@ -1244,10 +1244,11 @@
  * specified in Section 5 of RFC 5246. It is based on HMAC and can be
  * used with either SHA-256 or SHA-384.
  *
- * This key derivation algorithm uses the following inputs:
+ * This key derivation algorithm uses the following inputs, which must be
+ * passed in the order given here:
+ * - #PSA_KEY_DERIVATION_INPUT_SEED is the seed.
  * - #PSA_KEY_DERIVATION_INPUT_SECRET is the secret key.
  * - #PSA_KEY_DERIVATION_INPUT_LABEL is the label.
- * - #PSA_KEY_DERIVATION_INPUT_SEED is the seed.
  *
  * For the application to TLS-1.2 key expansion, the seed is the
  * concatenation of ServerHello.Random + ClientHello.Random,
@@ -1288,10 +1289,11 @@
  * The latter is based on HMAC and can be used with either SHA-256
  * or SHA-384.
  *
- * This key derivation algorithm uses the following inputs:
+ * This key derivation algorithm uses the following inputs, which must be
+ * passed in the order given here:
+ * - #PSA_KEY_DERIVATION_INPUT_SEED is the seed.
  * - #PSA_KEY_DERIVATION_INPUT_SECRET is the secret key.
  * - #PSA_KEY_DERIVATION_INPUT_LABEL is the label.
- * - #PSA_KEY_DERIVATION_INPUT_SEED is the seed.
  *
  * For the application to TLS-1.2, the seed (which is
  * forwarded to the TLS-1.2 PRF) is the concatenation of the
diff --git a/library/psa_crypto.c b/library/psa_crypto.c
index 8789084..2285694 100644
--- a/library/psa_crypto.c
+++ b/library/psa_crypto.c
@@ -2125,11 +2125,13 @@
     return( psa_hash_abort( &hmac->hash_ctx ) );
 }
 
+#if defined(PSA_PRE_1_0_KEY_DERIVATION)
 static void psa_hmac_init_internal( psa_hmac_internal_data *hmac )
 {
     /* Instances of psa_hash_operation_s can be initialized by zeroization. */
     memset( hmac, 0, sizeof( *hmac ) );
 }
+#endif /* PSA_PRE_1_0_KEY_DERIVATION */
 #endif /* MBEDTLS_MD_C */
 
 psa_status_t psa_mac_abort( psa_mac_operation_t *operation )
@@ -3866,16 +3868,6 @@
          * nothing to do. */
     }
     else
-    if( kdf_alg == PSA_ALG_SELECT_RAW )
-    {
-        if( operation->ctx.buffer.data != NULL )
-        {
-            mbedtls_platform_zeroize( operation->ctx.buffer.data,
-                             operation->ctx.buffer.size );
-            mbedtls_free( operation->ctx.buffer.data );
-        }
-    }
-    else
 #if defined(MBEDTLS_MD_C)
     if( PSA_ALG_IS_HKDF( kdf_alg ) )
     {
@@ -3886,6 +3878,7 @@
              /* TLS-1.2 PSK-to-MS KDF uses the same core as TLS-1.2 PRF */
              PSA_ALG_IS_TLS12_PSK_TO_MS( kdf_alg ) )
     {
+#if defined(PSA_PRE_1_0_KEY_DERIVATION)
         if( operation->ctx.tls12_prf.key != NULL )
         {
             mbedtls_platform_zeroize( operation->ctx.tls12_prf.key,
@@ -3899,13 +3892,33 @@
                              operation->ctx.tls12_prf.Ai_with_seed_len );
             mbedtls_free( operation->ctx.tls12_prf.Ai_with_seed );
         }
+#else
+        if( operation->ctx.tls12_prf.seed != NULL )
+        {
+            mbedtls_platform_zeroize( operation->ctx.tls12_prf.seed,
+                                      operation->ctx.tls12_prf.seed_length );
+            mbedtls_free( operation->ctx.tls12_prf.seed );
+        }
+
+        if( operation->ctx.tls12_prf.label != NULL )
+        {
+            mbedtls_platform_zeroize( operation->ctx.tls12_prf.label,
+                                      operation->ctx.tls12_prf.label_length );
+            mbedtls_free( operation->ctx.tls12_prf.label );
+        }
+
+        status = psa_hmac_abort_internal( &operation->ctx.tls12_prf.hmac );
+
+        /* We leave the fields Ai and output_block to be erased safely by the
+         * mbedtls_platform_zeroize() in the end of this function. */
+#endif /* PSA_PRE_1_0_KEY_DERIVATION */
     }
     else
 #endif /* MBEDTLS_MD_C */
     {
         status = PSA_ERROR_BAD_STATE;
     }
-    memset( operation, 0, sizeof( *operation ) );
+    mbedtls_platform_zeroize( operation, sizeof( *operation ) );
     return( status );
 }
 
@@ -4003,6 +4016,7 @@
     return( PSA_SUCCESS );
 }
 
+#if defined(PSA_PRE_1_0_KEY_DERIVATION)
 static psa_status_t psa_key_derivation_tls12_prf_generate_next_block(
     psa_tls12_prf_key_derivation_t *tls12_prf,
     psa_algorithm_t alg )
@@ -4114,14 +4128,124 @@
 
     return( status );
 }
+#else
+static psa_status_t psa_key_derivation_tls12_prf_generate_next_block(
+    psa_tls12_prf_key_derivation_t *tls12_prf,
+    psa_algorithm_t alg )
+{
+    psa_algorithm_t hash_alg = PSA_ALG_HKDF_GET_HASH( alg );
+    uint8_t hash_length = PSA_HASH_SIZE( hash_alg );
+    psa_hash_operation_t backup = PSA_HASH_OPERATION_INIT;
+    psa_status_t status, cleanup_status;
 
+    /* We can't be wanting more output after block 0xff, otherwise
+     * the capacity check in psa_key_derivation_output_bytes() would have
+     * prevented this call. It could happen only if the operation
+     * object was corrupted or if this function is called directly
+     * inside the library. */
+    if( tls12_prf->block_number == 0xff )
+        return( PSA_ERROR_CORRUPTION_DETECTED );
+
+    /* We need a new block */
+    ++tls12_prf->block_number;
+    tls12_prf->left_in_block = hash_length;
+
+    /* Recall the definition of the TLS-1.2-PRF from RFC 5246:
+     *
+     * PRF(secret, label, seed) = P_<hash>(secret, label + seed)
+     *
+     * P_hash(secret, seed) = HMAC_hash(secret, A(1) + seed) +
+     *                        HMAC_hash(secret, A(2) + seed) +
+     *                        HMAC_hash(secret, A(3) + seed) + ...
+     *
+     * A(0) = seed
+     * A(i) = HMAC_hash(secret, A(i-1))
+     *
+     * The `psa_tls12_prf_key_derivation` structure saves the block
+     * `HMAC_hash(secret, A(i) + seed)` from which the output
+     * is currently extracted as `output_block` and where i is
+     * `block_number`.
+     */
+
+    /* Save the hash context before using it, to preserve the hash state with
+     * only the inner padding in it. We need this, because inner padding depends
+     * on the key (secret in the RFC's terminology). */
+    status = psa_hash_clone( &tls12_prf->hmac.hash_ctx, &backup );
+    if( status != PSA_SUCCESS )
+        goto cleanup;
+
+    /* Calculate A(i) where i = tls12_prf->block_number. */
+    if( tls12_prf->block_number == 1 )
+    {
+        /* A(1) = HMAC_hash(secret, A(0)), where A(0) = seed. (The RFC overloads
+         * the variable seed and in this instance means it in the context of the
+         * P_hash function, where seed = label + seed.) */
+        status = psa_hash_update( &tls12_prf->hmac.hash_ctx,
+                                  tls12_prf->label, tls12_prf->label_length );
+        if( status != PSA_SUCCESS )
+            goto cleanup;
+        status = psa_hash_update( &tls12_prf->hmac.hash_ctx,
+                                  tls12_prf->seed, tls12_prf->seed_length );
+        if( status != PSA_SUCCESS )
+            goto cleanup;
+    }
+    else
+    {
+        /* A(i) = HMAC_hash(secret, A(i-1)) */
+        status = psa_hash_update( &tls12_prf->hmac.hash_ctx,
+                                  tls12_prf->Ai, hash_length );
+        if( status != PSA_SUCCESS )
+            goto cleanup;
+    }
+
+    status = psa_hmac_finish_internal( &tls12_prf->hmac,
+                                       tls12_prf->Ai, hash_length );
+    if( status != PSA_SUCCESS )
+        goto cleanup;
+    status = psa_hash_clone( &backup, &tls12_prf->hmac.hash_ctx );
+    if( status != PSA_SUCCESS )
+        goto cleanup;
+
+    /* Calculate HMAC_hash(secret, A(i) + label + seed). */
+    status = psa_hash_update( &tls12_prf->hmac.hash_ctx,
+                              tls12_prf->Ai, hash_length );
+    if( status != PSA_SUCCESS )
+        goto cleanup;
+    status = psa_hash_update( &tls12_prf->hmac.hash_ctx,
+                              tls12_prf->label, tls12_prf->label_length );
+    if( status != PSA_SUCCESS )
+        goto cleanup;
+    status = psa_hash_update( &tls12_prf->hmac.hash_ctx,
+                              tls12_prf->seed, tls12_prf->seed_length );
+    if( status != PSA_SUCCESS )
+        goto cleanup;
+    status = psa_hmac_finish_internal( &tls12_prf->hmac,
+                                       tls12_prf->output_block, hash_length );
+    if( status != PSA_SUCCESS )
+        goto cleanup;
+    status = psa_hash_clone( &backup, &tls12_prf->hmac.hash_ctx );
+    if( status != PSA_SUCCESS )
+        goto cleanup;
+
+
+cleanup:
+
+    cleanup_status = psa_hash_abort( &backup );
+    if( status == PSA_SUCCESS && cleanup_status != PSA_SUCCESS )
+        status = cleanup_status;
+
+    return( status );
+}
+#endif /* PSA_PRE_1_0_KEY_DERIVATION */
+
+#if defined(PSA_PRE_1_0_KEY_DERIVATION)
 /* Read some bytes from an TLS-1.2-PRF-based operation.
  * See Section 5 of RFC 5246. */
 static psa_status_t psa_key_derivation_tls12_prf_read(
-                                        psa_tls12_prf_key_derivation_t *tls12_prf,
-                                        psa_algorithm_t alg,
-                                        uint8_t *output,
-                                        size_t output_length )
+    psa_tls12_prf_key_derivation_t *tls12_prf,
+    psa_algorithm_t alg,
+    uint8_t *output,
+    size_t output_length )
 {
     psa_algorithm_t hash_alg = PSA_ALG_TLS12_PRF_GET_HASH( alg );
     uint8_t hash_length = PSA_HASH_SIZE( hash_alg );
@@ -4136,7 +4260,7 @@
         if( n == 0 )
         {
             status = psa_key_derivation_tls12_prf_generate_next_block( tls12_prf,
-                                                                  alg );
+                                                                       alg );
             if( status != PSA_SUCCESS )
                 return( status );
 
@@ -4154,11 +4278,52 @@
 
     return( PSA_SUCCESS );
 }
+#else
+static psa_status_t psa_key_derivation_tls12_prf_read(
+    psa_tls12_prf_key_derivation_t *tls12_prf,
+    psa_algorithm_t alg,
+    uint8_t *output,
+    size_t output_length )
+{
+    psa_algorithm_t hash_alg = PSA_ALG_TLS12_PRF_GET_HASH( alg );
+    uint8_t hash_length = PSA_HASH_SIZE( hash_alg );
+    psa_status_t status;
+    uint8_t offset, length;
+
+    while( output_length != 0 )
+    {
+        /* Check if we have fully processed the current block. */
+        if( tls12_prf->left_in_block == 0 )
+        {
+            status = psa_key_derivation_tls12_prf_generate_next_block( tls12_prf,
+                                                                       alg );
+            if( status != PSA_SUCCESS )
+                return( status );
+
+            continue;
+        }
+
+        if( tls12_prf->left_in_block > output_length )
+            length = (uint8_t) output_length;
+        else
+            length = tls12_prf->left_in_block;
+
+        offset = hash_length - tls12_prf->left_in_block;
+        memcpy( output, tls12_prf->output_block + offset, length );
+        output += length;
+        output_length -= length;
+        tls12_prf->left_in_block -= length;
+    }
+
+    return( PSA_SUCCESS );
+}
+#endif /* PSA_PRE_1_0_KEY_DERIVATION */
 #endif /* MBEDTLS_MD_C */
 
-psa_status_t psa_key_derivation_output_bytes( psa_key_derivation_operation_t *operation,
-                                 uint8_t *output,
-                                 size_t output_length )
+psa_status_t psa_key_derivation_output_bytes(
+    psa_key_derivation_operation_t *operation,
+    uint8_t *output,
+    size_t output_length )
 {
     psa_status_t status;
     psa_algorithm_t kdf_alg = psa_key_derivation_get_kdf_alg( operation );
@@ -4189,23 +4354,6 @@
     }
     operation->capacity -= output_length;
 
-    if( kdf_alg == PSA_ALG_SELECT_RAW )
-    {
-        /* Initially, the capacity of a selection operation is always
-         * the size of the buffer, i.e. `operation->ctx.buffer.size`,
-         * abbreviated in this comment as `size`. When the remaining
-         * capacity is `c`, the next bytes to serve start `c` bytes
-         * from the end of the buffer, i.e. `size - c` from the
-         * beginning of the buffer. Since `operation->capacity` was just
-         * decremented above, we need to serve the bytes from
-         * `size - operation->capacity - output_length` to
-         * `size - operation->capacity`. */
-        size_t offset =
-            operation->ctx.buffer.size - operation->capacity - output_length;
-        memcpy( output, operation->ctx.buffer.data + offset, output_length );
-        status = PSA_SUCCESS;
-    }
-    else
 #if defined(MBEDTLS_MD_C)
     if( PSA_ALG_IS_HKDF( kdf_alg ) )
     {
@@ -4213,7 +4361,8 @@
         status = psa_key_derivation_hkdf_read( &operation->ctx.hkdf, hash_alg,
                                           output, output_length );
     }
-    else if( PSA_ALG_IS_TLS12_PRF( kdf_alg ) ||
+    else
+    if( PSA_ALG_IS_TLS12_PRF( kdf_alg ) ||
              PSA_ALG_IS_TLS12_PSK_TO_MS( kdf_alg ) )
     {
         status = psa_key_derivation_tls12_prf_read( &operation->ctx.tls12_prf,
@@ -4314,6 +4463,7 @@
 /****************************************************************/
 
 #if defined(MBEDTLS_MD_C)
+#if defined(PSA_PRE_1_0_KEY_DERIVATION)
 /* Set up an HKDF-based operation. This is exactly the extract phase
  * of the HKDF algorithm.
  *
@@ -4357,9 +4507,11 @@
     hkdf->info_set = 1;
     return( PSA_SUCCESS );
 }
+#endif /* PSA_PRE_1_0_KEY_DERIVATION */
 #endif /* MBEDTLS_MD_C */
 
 #if defined(MBEDTLS_MD_C)
+#if defined(PSA_PRE_1_0_KEY_DERIVATION)
 /* Set up a TLS-1.2-prf-based operation (see RFC 5246, Section 5).
  *
  * Note that if this function fails, you must call psa_key_derivation_abort()
@@ -4416,7 +4568,9 @@
 
     return( PSA_SUCCESS );
 }
+#endif /* PSA_PRE_1_0_KEY_DERIVATION */
 
+#if defined(PSA_PRE_1_0_KEY_DERIVATION)
 /* Set up a TLS-1.2-PSK-to-MS-based operation. */
 static psa_status_t psa_key_derivation_tls12_psk_to_ms_setup(
     psa_tls12_prf_key_derivation_t *tls12_prf,
@@ -4457,8 +4611,10 @@
     mbedtls_platform_zeroize( pms, sizeof( pms ) );
     return( status );
 }
+#endif /* PSA_PRE_1_0_KEY_DERIVATION */
 #endif /* MBEDTLS_MD_C */
 
+#if defined(PSA_PRE_1_0_KEY_DERIVATION)
 /* Note that if this function fails, you must call psa_key_derivation_abort()
  * to potentially free embedded data structures and wipe confidential data.
  */
@@ -4476,23 +4632,6 @@
     /* Set operation->alg even on failure so that abort knows what to do. */
     operation->alg = alg;
 
-    if( alg == PSA_ALG_SELECT_RAW )
-    {
-        (void) salt;
-        if( salt_length != 0 )
-            return( PSA_ERROR_INVALID_ARGUMENT );
-        (void) label;
-        if( label_length != 0 )
-            return( PSA_ERROR_INVALID_ARGUMENT );
-        operation->ctx.buffer.data = mbedtls_calloc( 1, secret_length );
-        if( operation->ctx.buffer.data == NULL )
-            return( PSA_ERROR_INSUFFICIENT_MEMORY );
-        memcpy( operation->ctx.buffer.data, secret, secret_length );
-        operation->ctx.buffer.size = secret_length;
-        max_capacity = secret_length;
-        status = PSA_SUCCESS;
-    }
-    else
 #if defined(MBEDTLS_MD_C)
     if( PSA_ALG_IS_HKDF( alg ) )
     {
@@ -4557,7 +4696,9 @@
 
     return( PSA_SUCCESS );
 }
+#endif /* PSA_PRE_1_0_KEY_DERIVATION */
 
+#if defined(PSA_PRE_1_0_KEY_DERIVATION)
 psa_status_t psa_key_derivation( psa_key_derivation_operation_t *operation,
                                  psa_key_handle_t handle,
                                  psa_algorithm_t alg,
@@ -4597,11 +4738,16 @@
         psa_key_derivation_abort( operation );
     return( status );
 }
+#endif /* PSA_PRE_1_0_KEY_DERIVATION */
 
 static psa_status_t psa_key_derivation_setup_kdf(
     psa_key_derivation_operation_t *operation,
     psa_algorithm_t kdf_alg )
 {
+    /* Make sure that operation->ctx is properly zero-initialised. (Macro
+     * initialisers for this union leave some bytes unspecified.) */
+    memset( &operation->ctx, 0, sizeof( operation->ctx ) );
+
     /* Make sure that kdf_alg is a supported key derivation algorithm. */
 #if defined(MBEDTLS_MD_C)
     if( PSA_ALG_IS_HKDF( kdf_alg ) ||
@@ -4718,9 +4864,174 @@
             return( PSA_ERROR_INVALID_ARGUMENT );
     }
 }
+
+#if defined(PSA_PRE_1_0_KEY_DERIVATION)
+static psa_status_t psa_tls12_prf_input( psa_tls12_prf_key_derivation_t *prf,
+                                         psa_algorithm_t hash_alg,
+                                         psa_key_derivation_step_t step,
+                                         const uint8_t *data,
+                                         size_t data_length )
+{
+    (void) prf;
+    (void) hash_alg;
+    (void) step;
+    (void) data;
+    (void) data_length;
+
+    return( PSA_ERROR_INVALID_ARGUMENT );
+}
+
+static psa_status_t psa_tls12_prf_psk_to_ms_input(
+    psa_tls12_prf_key_derivation_t *prf,
+    psa_algorithm_t hash_alg,
+    psa_key_derivation_step_t step,
+    const uint8_t *data,
+    size_t data_length )
+{
+    (void) prf;
+    (void) hash_alg;
+    (void) step;
+    (void) data;
+    (void) data_length;
+
+    return( PSA_ERROR_INVALID_ARGUMENT );
+}
+#else
+static psa_status_t psa_tls12_prf_set_seed( psa_tls12_prf_key_derivation_t *prf,
+                                            const uint8_t *data,
+                                            size_t data_length )
+{
+    if( prf->state != TLS12_PRF_STATE_INIT )
+        return( PSA_ERROR_BAD_STATE );
+
+    if( data_length != 0 )
+    {
+        prf->seed = mbedtls_calloc( 1, data_length );
+        if( prf->seed == NULL )
+            return( PSA_ERROR_INSUFFICIENT_MEMORY );
+
+        memcpy( prf->seed, data, data_length );
+        prf->seed_length = data_length;
+    }
+
+    prf->state = TLS12_PRF_STATE_SEED_SET;
+
+    return( PSA_SUCCESS );
+}
+
+static psa_status_t psa_tls12_prf_set_key( psa_tls12_prf_key_derivation_t *prf,
+                                           psa_algorithm_t hash_alg,
+                                           const uint8_t *data,
+                                           size_t data_length )
+{
+    psa_status_t status;
+    if( prf->state != TLS12_PRF_STATE_SEED_SET )
+        return( PSA_ERROR_BAD_STATE );
+
+    status = psa_hmac_setup_internal( &prf->hmac, data, data_length, hash_alg );
+    if( status != PSA_SUCCESS )
+        return( status );
+
+    prf->state = TLS12_PRF_STATE_KEY_SET;
+
+    return( PSA_SUCCESS );
+}
+
+static psa_status_t psa_tls12_prf_psk_to_ms_set_key(
+    psa_tls12_prf_key_derivation_t *prf,
+    psa_algorithm_t hash_alg,
+    const uint8_t *data,
+    size_t data_length )
+{
+    psa_status_t status;
+    unsigned char pms[ 4 + 2 * PSA_ALG_TLS12_PSK_TO_MS_MAX_PSK_LEN ];
+    unsigned char* cur = pms;
+
+    if( data_length > PSA_ALG_TLS12_PSK_TO_MS_MAX_PSK_LEN )
+        return( PSA_ERROR_INVALID_ARGUMENT );
+
+    /* Quoting RFC 4279, Section 2:
+     *
+     * The premaster secret is formed as follows: if the PSK is N octets
+     * long, concatenate a uint16 with the value N, N zero octets, a second
+     * uint16 with the value N, and the PSK itself.
+     */
+
+    *cur++ = ( data_length >> 8 ) & 0xff;
+    *cur++ = ( data_length >> 0 ) & 0xff;
+    memset( cur, 0, data_length );
+    cur += data_length;
+    *cur++ = pms[0];
+    *cur++ = pms[1];
+    memcpy( cur, data, data_length );
+    cur += data_length;
+
+    status = psa_tls12_prf_set_key( prf, hash_alg, pms, cur - pms );
+
+    mbedtls_platform_zeroize( pms, sizeof( pms ) );
+    return( status );
+}
+
+static psa_status_t psa_tls12_prf_set_label( psa_tls12_prf_key_derivation_t *prf,
+                                             const uint8_t *data,
+                                             size_t data_length )
+{
+    if( prf->state != TLS12_PRF_STATE_KEY_SET )
+        return( PSA_ERROR_BAD_STATE );
+
+    if( data_length != 0 )
+    {
+        prf->label = mbedtls_calloc( 1, data_length );
+        if( prf->label == NULL )
+            return( PSA_ERROR_INSUFFICIENT_MEMORY );
+
+        memcpy( prf->label, data, data_length );
+        prf->label_length = data_length;
+    }
+
+    prf->state = TLS12_PRF_STATE_LABEL_SET;
+
+    return( PSA_SUCCESS );
+}
+
+static psa_status_t psa_tls12_prf_input( psa_tls12_prf_key_derivation_t *prf,
+                                         psa_algorithm_t hash_alg,
+                                         psa_key_derivation_step_t step,
+                                         const uint8_t *data,
+                                         size_t data_length )
+{
+    switch( step )
+    {
+        case PSA_KEY_DERIVATION_INPUT_SEED:
+            return( psa_tls12_prf_set_seed( prf, data, data_length ) );
+        case PSA_KEY_DERIVATION_INPUT_SECRET:
+            return( psa_tls12_prf_set_key( prf, hash_alg, data, data_length ) );
+        case PSA_KEY_DERIVATION_INPUT_LABEL:
+            return( psa_tls12_prf_set_label( prf, data, data_length ) );
+        default:
+            return( PSA_ERROR_INVALID_ARGUMENT );
+    }
+}
+
+static psa_status_t psa_tls12_prf_psk_to_ms_input(
+    psa_tls12_prf_key_derivation_t *prf,
+    psa_algorithm_t hash_alg,
+    psa_key_derivation_step_t step,
+    const uint8_t *data,
+    size_t data_length )
+{
+    if( step == PSA_KEY_DERIVATION_INPUT_SECRET )
+    {
+        return( psa_tls12_prf_psk_to_ms_set_key( prf, hash_alg,
+                                                 data, data_length ) );
+    }
+
+    return( psa_tls12_prf_input( prf, hash_alg, step, data, data_length ) );
+}
+#endif /* PSA_PRE_1_0_KEY_DERIVATION */
 #endif /* MBEDTLS_MD_C */
 
-static psa_status_t psa_key_derivation_input_raw(
+static psa_status_t psa_key_derivation_input_internal(
     psa_key_derivation_operation_t *operation,
     psa_key_derivation_step_t step,
     const uint8_t *data,
@@ -4729,19 +5040,6 @@
     psa_status_t status;
     psa_algorithm_t kdf_alg = psa_key_derivation_get_kdf_alg( operation );
 
-    if( kdf_alg == PSA_ALG_SELECT_RAW )
-    {
-        if( operation->capacity != 0 )
-            return( PSA_ERROR_INVALID_ARGUMENT );
-        operation->ctx.buffer.data = mbedtls_calloc( 1, data_length );
-        if( operation->ctx.buffer.data == NULL )
-            return( PSA_ERROR_INSUFFICIENT_MEMORY );
-        memcpy( operation->ctx.buffer.data, data, data_length );
-        operation->ctx.buffer.size = data_length;
-        operation->capacity = data_length;
-        status = PSA_SUCCESS;
-    }
-    else
 #if defined(MBEDTLS_MD_C)
     if( PSA_ALG_IS_HKDF( kdf_alg ) )
     {
@@ -4752,12 +5050,17 @@
     else
 #endif /* MBEDTLS_MD_C */
 #if defined(MBEDTLS_MD_C)
-        /* TLS-1.2 PRF and TLS-1.2 PSK-to-MS are very similar, so share code. */
-    if( PSA_ALG_IS_TLS12_PRF( kdf_alg ) ||
-        PSA_ALG_IS_TLS12_PSK_TO_MS( kdf_alg ) )
+    if( PSA_ALG_IS_TLS12_PRF( kdf_alg ) )
     {
-        // To do: implement this
-        status = PSA_ERROR_NOT_SUPPORTED;
+        status = psa_tls12_prf_input( &operation->ctx.tls12_prf,
+                                      PSA_ALG_HKDF_GET_HASH( kdf_alg ),
+                                      step, data, data_length );
+    }
+    else if( PSA_ALG_IS_TLS12_PSK_TO_MS( kdf_alg ) )
+    {
+        status = psa_tls12_prf_psk_to_ms_input( &operation->ctx.tls12_prf,
+                                                PSA_ALG_HKDF_GET_HASH( kdf_alg ),
+                                                step, data, data_length );
     }
     else
 #endif /* MBEDTLS_MD_C */
@@ -4771,26 +5074,23 @@
     return( status );
 }
 
-psa_status_t psa_key_derivation_input_bytes( psa_key_derivation_operation_t *operation,
-                                             psa_key_derivation_step_t step,
-                                             const uint8_t *data,
-                                             size_t data_length )
+psa_status_t psa_key_derivation_input_bytes(
+    psa_key_derivation_operation_t *operation,
+    psa_key_derivation_step_t step,
+    const uint8_t *data,
+    size_t data_length )
 {
-    switch( step )
-    {
-        case PSA_KEY_DERIVATION_INPUT_LABEL:
-        case PSA_KEY_DERIVATION_INPUT_SALT:
-        case PSA_KEY_DERIVATION_INPUT_INFO:
-            return( psa_key_derivation_input_raw( operation, step,
-                                                  data, data_length ) );
-        default:
-            return( PSA_ERROR_INVALID_ARGUMENT );
-    }
+    if( step == PSA_KEY_DERIVATION_INPUT_SECRET )
+        return( PSA_ERROR_INVALID_ARGUMENT );
+
+    return( psa_key_derivation_input_internal( operation, step,
+                                               data, data_length ) );
 }
 
-psa_status_t psa_key_derivation_input_key( psa_key_derivation_operation_t *operation,
-                                           psa_key_derivation_step_t step,
-                                           psa_key_handle_t handle )
+psa_status_t psa_key_derivation_input_key(
+    psa_key_derivation_operation_t *operation,
+    psa_key_derivation_step_t step,
+    psa_key_handle_t handle )
 {
     psa_key_slot_t *slot;
     psa_status_t status;
@@ -4809,10 +5109,10 @@
      * and leak values derived from the key. So be conservative. */
     if( step != PSA_KEY_DERIVATION_INPUT_SECRET )
         return( PSA_ERROR_INVALID_ARGUMENT );
-    return( psa_key_derivation_input_raw( operation,
-                                          step,
-                                          slot->data.raw.data,
-                                          slot->data.raw.bytes ) );
+    return( psa_key_derivation_input_internal( operation,
+                                               step,
+                                               slot->data.raw.data,
+                                               slot->data.raw.bytes ) );
 }
 
 
@@ -4924,8 +5224,9 @@
 
     /* Step 2: set up the key derivation to generate key material from
      * the shared secret. */
-    status = psa_key_derivation_input_raw( operation, step,
-                                           shared_secret, shared_secret_length );
+    status = psa_key_derivation_input_internal( operation, step,
+                                                shared_secret,
+                                                shared_secret_length );
 
 exit:
     mbedtls_platform_zeroize( shared_secret, shared_secret_length );
diff --git a/programs/psa/key_ladder_demo.c b/programs/psa/key_ladder_demo.c
index af7be1e..426e41f 100644
--- a/programs/psa/key_ladder_demo.c
+++ b/programs/psa/key_ladder_demo.c
@@ -66,12 +66,14 @@
 /* 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)
+    !defined(MBEDTLS_PSA_CRYPTO_C) || !defined(MBEDTLS_FS_IO) ||\
+    !defined(PSA_PRE_1_0_KEY_DERIVATION)
 int main( void )
 {
     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");
+           "MBEDTLS_PSA_CRYPTO_C and/or MBEDTLS_FS_IO and/or "
+           "PSA_PRE_1_0_KEY_DERIVATION not defined.\n");
     return( 0 );
 }
 #else
diff --git a/tests/suites/test_suite_psa_crypto.data b/tests/suites/test_suite_psa_crypto.data
index b3d27a8..f618e13 100644
--- a/tests/suites/test_suite_psa_crypto.data
+++ b/tests/suites/test_suite_psa_crypto.data
@@ -461,7 +461,7 @@
 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 via TLS 1.2 PRF, permitted
-depends_on:MBEDTLS_MD_C:MBEDTLS_SHA256_C
+depends_on:MBEDTLS_MD_C:MBEDTLS_SHA256_C:!PSA_PRE_1_0_KEY_DERIVATION
 derive_key_policy:PSA_KEY_USAGE_DERIVE:PSA_ALG_TLS12_PRF(PSA_ALG_SHA_256):PSA_KEY_TYPE_DERIVE:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":PSA_ALG_TLS12_PRF(PSA_ALG_SHA_256)
 
 PSA key policy: derive via HKDF, not permitted
@@ -469,7 +469,7 @@
 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 via TLS 1.2 PRF, not permitted
-depends_on:MBEDTLS_MD_C:MBEDTLS_SHA256_C
+depends_on:MBEDTLS_MD_C:MBEDTLS_SHA256_C:!PSA_PRE_1_0_KEY_DERIVATION
 derive_key_policy:0:PSA_ALG_TLS12_PRF(PSA_ALG_SHA_256):PSA_KEY_TYPE_DERIVE:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":PSA_ALG_TLS12_PRF(PSA_ALG_SHA_256)
 
 PSA key policy: derive via HKDF, wrong algorithm
@@ -477,7 +477,7 @@
 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 policy: derive via TLS 1.2 PRF, wrong algorithm
-depends_on:MBEDTLS_MD_C:MBEDTLS_SHA256_C
+depends_on:MBEDTLS_MD_C:MBEDTLS_SHA256_C:!PSA_PRE_1_0_KEY_DERIVATION
 derive_key_policy:PSA_KEY_USAGE_DERIVE:PSA_ALG_TLS12_PRF(PSA_ALG_SHA_256):PSA_KEY_TYPE_DERIVE:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":PSA_ALG_HKDF(PSA_ALG_SHA_224)
 
 PSA key policy: agreement + KDF, permitted
@@ -1757,39 +1757,67 @@
 
 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
+derive_setup:PSA_ALG_HKDF(PSA_ALG_SHA_256):PSA_SUCCESS
 
 PSA key derivation: HKDF-SHA-512, good case
 depends_on:MBEDTLS_MD_C:MBEDTLS_SHA512_C
-derive_setup:PSA_KEY_TYPE_DERIVE:"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":PSA_ALG_HKDF(PSA_ALG_SHA_512):"":"":42:PSA_SUCCESS
-
-PSA key derivation: HKDF-SHA-256, 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
+derive_setup:PSA_ALG_HKDF(PSA_ALG_SHA_512):PSA_SUCCESS
 
 PSA key derivation: TLS 1.2 PRF SHA-256, good case
 depends_on:MBEDTLS_MD_C:MBEDTLS_SHA256_C
-derive_setup:PSA_KEY_TYPE_DERIVE:"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":PSA_ALG_TLS12_PRF(PSA_ALG_SHA_256):"":"":42:PSA_SUCCESS
-
-PSA key derivation: TLS 1.2 PRF SHA-256, bad key type
-depends_on:MBEDTLS_MD_C:MBEDTLS_SHA256_C
-derive_setup:PSA_KEY_TYPE_RAW_DATA:"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":PSA_ALG_TLS12_PRF(PSA_ALG_SHA_256):"":"":42:PSA_ERROR_INVALID_ARGUMENT
-
-PSA key derivation: not a key derivation algorithm (selection)
-depends_on:MBEDTLS_MD_C:MBEDTLS_SHA256_C
-derive_setup:PSA_KEY_TYPE_DERIVE:"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":PSA_ALG_SELECT_RAW:"":"":42:PSA_ERROR_INVALID_ARGUMENT
+derive_setup:PSA_ALG_TLS12_PRF(PSA_ALG_SHA_256):PSA_SUCCESS
 
 PSA key derivation: not a key derivation algorithm (HMAC)
 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
+derive_setup:PSA_ALG_HMAC(PSA_ALG_SHA_256):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
+derive_setup::PSA_ALG_HKDF(PSA_ALG_CATEGORY_HASH):PSA_ERROR_NOT_SUPPORTED
 
 PSA key derivation: unsupported key derivation algorithm
 depends_on:MBEDTLS_MD_C:MBEDTLS_SHA256_C
-derive_setup:PSA_KEY_TYPE_DERIVE:"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":PSA_ALG_CATEGORY_KEY_DERIVATION:"":"":42:PSA_ERROR_NOT_SUPPORTED
+derive_setup:PSA_ALG_CATEGORY_KEY_DERIVATION:PSA_ERROR_NOT_SUPPORTED
+
+PSA key derivation: HKDF-SHA-256, good case
+depends_on:MBEDTLS_MD_C:MBEDTLS_SHA256_C
+derive_input:PSA_ALG_HKDF(PSA_ALG_SHA_256):PSA_KEY_TYPE_DERIVE:PSA_KEY_DERIVATION_INPUT_SALT:"":PSA_KEY_DERIVATION_INPUT_SECRET:"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":PSA_KEY_DERIVATION_INPUT_INFO:"":PSA_SUCCESS:PSA_SUCCESS:PSA_SUCCESS
+
+PSA key derivation: HKDF-SHA-512, good case
+depends_on:MBEDTLS_MD_C:MBEDTLS_SHA512_C
+derive_input:PSA_ALG_HKDF(PSA_ALG_SHA_512):PSA_KEY_TYPE_DERIVE:PSA_KEY_DERIVATION_INPUT_SALT:"":PSA_KEY_DERIVATION_INPUT_SECRET:"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":PSA_KEY_DERIVATION_INPUT_INFO:"":PSA_SUCCESS:PSA_SUCCESS:PSA_SUCCESS
+
+PSA key derivation: HKDF-SHA-256, bad key type
+depends_on:MBEDTLS_MD_C:MBEDTLS_SHA256_C
+derive_input:PSA_ALG_HKDF(PSA_ALG_SHA_256):PSA_KEY_TYPE_RAW_DATA:PSA_KEY_DERIVATION_INPUT_SALT:"":PSA_KEY_DERIVATION_INPUT_SECRET:"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":PSA_KEY_DERIVATION_INPUT_INFO:"":PSA_SUCCESS:PSA_ERROR_INVALID_ARGUMENT:PSA_SUCCESS
+
+PSA key derivation: TLS 1.2 PRF SHA-256, good case
+depends_on:MBEDTLS_MD_C:MBEDTLS_SHA256_C:!PSA_PRE_1_0_KEY_DERIVATION
+derive_input:PSA_ALG_TLS12_PRF(PSA_ALG_SHA_256):PSA_KEY_TYPE_DERIVE:PSA_KEY_DERIVATION_INPUT_SEED:"":PSA_KEY_DERIVATION_INPUT_SECRET:"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":PSA_KEY_DERIVATION_INPUT_LABEL:"":PSA_SUCCESS:PSA_SUCCESS:PSA_SUCCESS
+
+PSA key derivation: TLS 1.2 PRF SHA-256, key first
+depends_on:MBEDTLS_MD_C:MBEDTLS_SHA256_C:!PSA_PRE_1_0_KEY_DERIVATION
+derive_input:PSA_ALG_TLS12_PRF(PSA_ALG_SHA_256):PSA_KEY_TYPE_DERIVE:PSA_KEY_DERIVATION_INPUT_SECRET:"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":PSA_KEY_DERIVATION_INPUT_SEED:"":PSA_KEY_DERIVATION_INPUT_LABEL:"":PSA_ERROR_BAD_STATE:PSA_ERROR_BAD_STATE:PSA_ERROR_BAD_STATE
+
+PSA key derivation: TLS 1.2 PRF SHA-256, label first
+depends_on:MBEDTLS_MD_C:MBEDTLS_SHA256_C:!PSA_PRE_1_0_KEY_DERIVATION
+derive_input:PSA_ALG_TLS12_PRF(PSA_ALG_SHA_256):PSA_KEY_TYPE_DERIVE:PSA_KEY_DERIVATION_INPUT_LABEL:"":PSA_KEY_DERIVATION_INPUT_SECRET:"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":PSA_KEY_DERIVATION_INPUT_SEED:"":PSA_ERROR_BAD_STATE:PSA_ERROR_BAD_STATE:PSA_ERROR_BAD_STATE
+
+PSA key derivation: TLS 1.2 PRF SHA-256, early label
+depends_on:MBEDTLS_MD_C:MBEDTLS_SHA256_C:!PSA_PRE_1_0_KEY_DERIVATION
+derive_input:PSA_ALG_TLS12_PRF(PSA_ALG_SHA_256):PSA_KEY_TYPE_DERIVE:PSA_KEY_DERIVATION_INPUT_SEED:"":PSA_KEY_DERIVATION_INPUT_LABEL:"":PSA_KEY_DERIVATION_INPUT_SECRET:"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":PSA_SUCCESS:PSA_ERROR_BAD_STATE:PSA_ERROR_BAD_STATE
+
+PSA key derivation: TLS 1.2 PRF SHA-256, double seed
+depends_on:MBEDTLS_MD_C:MBEDTLS_SHA256_C:!PSA_PRE_1_0_KEY_DERIVATION
+derive_input:PSA_ALG_TLS12_PRF(PSA_ALG_SHA_256):PSA_KEY_TYPE_DERIVE:PSA_KEY_DERIVATION_INPUT_SEED:"":PSA_KEY_DERIVATION_INPUT_SEED:"":PSA_KEY_DERIVATION_INPUT_SECRET:"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":PSA_SUCCESS:PSA_ERROR_BAD_STATE:PSA_ERROR_BAD_STATE
+
+PSA key derivation: TLS 1.2 PRF SHA-256, double key
+depends_on:MBEDTLS_MD_C:MBEDTLS_SHA256_C:!PSA_PRE_1_0_KEY_DERIVATION
+derive_input:PSA_ALG_TLS12_PRF(PSA_ALG_SHA_256):PSA_KEY_TYPE_DERIVE:PSA_KEY_DERIVATION_INPUT_SEED:"":PSA_KEY_DERIVATION_INPUT_SECRET:"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":PSA_KEY_DERIVATION_INPUT_SECRET:"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":PSA_SUCCESS:PSA_SUCCESS:PSA_ERROR_BAD_STATE
+
+PSA key derivation: TLS 1.2 PRF SHA-256, bad key type
+depends_on:MBEDTLS_MD_C:MBEDTLS_SHA256_C:!PSA_PRE_1_0_KEY_DERIVATION
+derive_input:PSA_ALG_TLS12_PRF(PSA_ALG_SHA_256):PSA_KEY_TYPE_RAW_DATA:PSA_KEY_DERIVATION_INPUT_SEED:"":PSA_KEY_DERIVATION_INPUT_SECRET:"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":PSA_KEY_DERIVATION_INPUT_LABEL:"":PSA_SUCCESS:PSA_ERROR_INVALID_ARGUMENT:PSA_ERROR_BAD_STATE
 
 PSA key derivation: invalid state (double generate + read past capacity)
 depends_on:MBEDTLS_MD_C:MBEDTLS_SHA256_C
@@ -1801,155 +1829,155 @@
 
 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":""
+derive_output:PSA_ALG_HKDF(PSA_ALG_SHA_256):PSA_KEY_DERIVATION_INPUT_SALT:"000102030405060708090a0b0c":PSA_KEY_DERIVATION_INPUT_SECRET:"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":PSA_KEY_DERIVATION_INPUT_INFO:"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"
+derive_output:PSA_ALG_HKDF(PSA_ALG_SHA_256):PSA_KEY_DERIVATION_INPUT_SALT:"000102030405060708090a0b0c":PSA_KEY_DERIVATION_INPUT_SECRET:"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":PSA_KEY_DERIVATION_INPUT_INFO:"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"
+derive_output:PSA_ALG_HKDF(PSA_ALG_SHA_256):PSA_KEY_DERIVATION_INPUT_SALT:"000102030405060708090a0b0c":PSA_KEY_DERIVATION_INPUT_SECRET:"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":PSA_KEY_DERIVATION_INPUT_INFO:"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"
+derive_output:PSA_ALG_HKDF(PSA_ALG_SHA_256):PSA_KEY_DERIVATION_INPUT_SALT:"000102030405060708090a0b0c":PSA_KEY_DERIVATION_INPUT_SECRET:"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":PSA_KEY_DERIVATION_INPUT_INFO:"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":""
+derive_output:PSA_ALG_HKDF(PSA_ALG_SHA_256):PSA_KEY_DERIVATION_INPUT_SALT:"000102030405060708090a0b0c":PSA_KEY_DERIVATION_INPUT_SECRET:"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":PSA_KEY_DERIVATION_INPUT_INFO:"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"
+derive_output:PSA_ALG_HKDF(PSA_ALG_SHA_256):PSA_KEY_DERIVATION_INPUT_SALT:"000102030405060708090a0b0c":PSA_KEY_DERIVATION_INPUT_SECRET:"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":PSA_KEY_DERIVATION_INPUT_INFO:"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":""
+derive_output:PSA_ALG_HKDF(PSA_ALG_SHA_256):PSA_KEY_DERIVATION_INPUT_SALT:"606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeaf":PSA_KEY_DERIVATION_INPUT_SECRET:"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f":PSA_KEY_DERIVATION_INPUT_INFO:"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":""
+derive_output:PSA_ALG_HKDF(PSA_ALG_SHA_256):PSA_KEY_DERIVATION_INPUT_SALT:"":PSA_KEY_DERIVATION_INPUT_SECRET:"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":PSA_KEY_DERIVATION_INPUT_INFO:"":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":""
+derive_output:PSA_ALG_HKDF(PSA_ALG_SHA_1):PSA_KEY_DERIVATION_INPUT_SALT:"000102030405060708090a0b0c":PSA_KEY_DERIVATION_INPUT_SECRET:"0b0b0b0b0b0b0b0b0b0b0b":PSA_KEY_DERIVATION_INPUT_INFO:"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":""
+derive_output:PSA_ALG_HKDF(PSA_ALG_SHA_1):PSA_KEY_DERIVATION_INPUT_SALT:"606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeaf":PSA_KEY_DERIVATION_INPUT_SECRET:"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f":PSA_KEY_DERIVATION_INPUT_INFO:"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":""
+derive_output:PSA_ALG_HKDF(PSA_ALG_SHA_1):PSA_KEY_DERIVATION_INPUT_SALT:"":PSA_KEY_DERIVATION_INPUT_SECRET:"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":PSA_KEY_DERIVATION_INPUT_INFO:"":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":""
+derive_output:PSA_ALG_HKDF(PSA_ALG_SHA_1):PSA_KEY_DERIVATION_INPUT_SALT:"":PSA_KEY_DERIVATION_INPUT_SECRET:"0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c":PSA_KEY_DERIVATION_INPUT_INFO:"":42:"2c91117204d745f3500d636a62f64f0ab3bae548aa53d423b0d1f27ebba6f5e5673a081d70cce7acfc48":""
 
 # Test vectors taken from https://www.ietf.org/mail-archive/web/tls/current/msg03416.html
 PSA key derivation: TLS 1.2 PRF SHA-256, output 100+0
-depends_on:MBEDTLS_MD_C:MBEDTLS_SHA256_C
-derive_output:PSA_ALG_TLS12_PRF(PSA_ALG_SHA_256):"9bbe436ba940f017b17652849a71db35":"a0ba9f936cda311827a6f796ffd5198c":"74657374206c6162656c":100:"e3f229ba727be17b8d122620557cd453c2aab21d07c3d495329b52d4e61edb5a6b301791e90d35c9c9a46b4e14baf9af0fa022f7077def17abfd3797c0564bab4fbc91666e9def9b97fce34f796789baa48082d122ee42c5a72e5a5110fff70187347b66":""
+depends_on:MBEDTLS_MD_C:MBEDTLS_SHA256_C:!PSA_PRE_1_0_KEY_DERIVATION
+derive_output:PSA_ALG_TLS12_PRF(PSA_ALG_SHA_256):PSA_KEY_DERIVATION_INPUT_SEED:"a0ba9f936cda311827a6f796ffd5198c":PSA_KEY_DERIVATION_INPUT_SECRET:"9bbe436ba940f017b17652849a71db35":PSA_KEY_DERIVATION_INPUT_LABEL:"74657374206c6162656c":100:"e3f229ba727be17b8d122620557cd453c2aab21d07c3d495329b52d4e61edb5a6b301791e90d35c9c9a46b4e14baf9af0fa022f7077def17abfd3797c0564bab4fbc91666e9def9b97fce34f796789baa48082d122ee42c5a72e5a5110fff70187347b66":""
 
 PSA key derivation: TLS 1.2 PRF SHA-256, output 99+1
-depends_on:MBEDTLS_MD_C:MBEDTLS_SHA256_C
-derive_output:PSA_ALG_TLS12_PRF(PSA_ALG_SHA_256):"9bbe436ba940f017b17652849a71db35":"a0ba9f936cda311827a6f796ffd5198c":"74657374206c6162656c":100:"e3f229ba727be17b8d122620557cd453c2aab21d07c3d495329b52d4e61edb5a6b301791e90d35c9c9a46b4e14baf9af0fa022f7077def17abfd3797c0564bab4fbc91666e9def9b97fce34f796789baa48082d122ee42c5a72e5a5110fff70187347b":"66"
+depends_on:MBEDTLS_MD_C:MBEDTLS_SHA256_C:!PSA_PRE_1_0_KEY_DERIVATION
+derive_output:PSA_ALG_TLS12_PRF(PSA_ALG_SHA_256):PSA_KEY_DERIVATION_INPUT_SEED:"a0ba9f936cda311827a6f796ffd5198c":PSA_KEY_DERIVATION_INPUT_SECRET:"9bbe436ba940f017b17652849a71db35":PSA_KEY_DERIVATION_INPUT_LABEL:"74657374206c6162656c":100:"e3f229ba727be17b8d122620557cd453c2aab21d07c3d495329b52d4e61edb5a6b301791e90d35c9c9a46b4e14baf9af0fa022f7077def17abfd3797c0564bab4fbc91666e9def9b97fce34f796789baa48082d122ee42c5a72e5a5110fff70187347b":"66"
 
 PSA key derivation: TLS 1.2 PRF SHA-256, output 1+99
-depends_on:MBEDTLS_MD_C:MBEDTLS_SHA256_C
-derive_output:PSA_ALG_TLS12_PRF(PSA_ALG_SHA_256):"9bbe436ba940f017b17652849a71db35":"a0ba9f936cda311827a6f796ffd5198c":"74657374206c6162656c":100:"e3":"f229ba727be17b8d122620557cd453c2aab21d07c3d495329b52d4e61edb5a6b301791e90d35c9c9a46b4e14baf9af0fa022f7077def17abfd3797c0564bab4fbc91666e9def9b97fce34f796789baa48082d122ee42c5a72e5a5110fff70187347b66"
+depends_on:MBEDTLS_MD_C:MBEDTLS_SHA256_C:!PSA_PRE_1_0_KEY_DERIVATION
+derive_output:PSA_ALG_TLS12_PRF(PSA_ALG_SHA_256):PSA_KEY_DERIVATION_INPUT_SEED:"a0ba9f936cda311827a6f796ffd5198c":PSA_KEY_DERIVATION_INPUT_SECRET:"9bbe436ba940f017b17652849a71db35":PSA_KEY_DERIVATION_INPUT_LABEL:"74657374206c6162656c":100:"e3":"f229ba727be17b8d122620557cd453c2aab21d07c3d495329b52d4e61edb5a6b301791e90d35c9c9a46b4e14baf9af0fa022f7077def17abfd3797c0564bab4fbc91666e9def9b97fce34f796789baa48082d122ee42c5a72e5a5110fff70187347b66"
 
 PSA key derivation: TLS 1.2 PRF SHA-256, output 50+50
-depends_on:MBEDTLS_MD_C:MBEDTLS_SHA256_C
-derive_output:PSA_ALG_TLS12_PRF(PSA_ALG_SHA_256):"9bbe436ba940f017b17652849a71db35":"a0ba9f936cda311827a6f796ffd5198c":"74657374206c6162656c":100:"e3f229ba727be17b8d122620557cd453c2aab21d07c3d495329b52d4e61edb5a6b301791e90d35c9c9a46b4e14baf9af0fa0":"22f7077def17abfd3797c0564bab4fbc91666e9def9b97fce34f796789baa48082d122ee42c5a72e5a5110fff70187347b66"
+depends_on:MBEDTLS_MD_C:MBEDTLS_SHA256_C:!PSA_PRE_1_0_KEY_DERIVATION
+derive_output:PSA_ALG_TLS12_PRF(PSA_ALG_SHA_256):PSA_KEY_DERIVATION_INPUT_SEED:"a0ba9f936cda311827a6f796ffd5198c":PSA_KEY_DERIVATION_INPUT_SECRET:"9bbe436ba940f017b17652849a71db35":PSA_KEY_DERIVATION_INPUT_LABEL:"74657374206c6162656c":100:"e3f229ba727be17b8d122620557cd453c2aab21d07c3d495329b52d4e61edb5a6b301791e90d35c9c9a46b4e14baf9af0fa0":"22f7077def17abfd3797c0564bab4fbc91666e9def9b97fce34f796789baa48082d122ee42c5a72e5a5110fff70187347b66"
 
 PSA key derivation: TLS 1.2 PRF SHA-256, output 50+49
-depends_on:MBEDTLS_MD_C:MBEDTLS_SHA256_C
-derive_output:PSA_ALG_TLS12_PRF(PSA_ALG_SHA_256):"9bbe436ba940f017b17652849a71db35":"a0ba9f936cda311827a6f796ffd5198c":"74657374206c6162656c":100:"e3f229ba727be17b8d122620557cd453c2aab21d07c3d495329b52d4e61edb5a6b301791e90d35c9c9a46b4e14baf9af0fa0":"22f7077def17abfd3797c0564bab4fbc91666e9def9b97fce34f796789baa48082d122ee42c5a72e5a5110fff70187347b"
+depends_on:MBEDTLS_MD_C:MBEDTLS_SHA256_C:!PSA_PRE_1_0_KEY_DERIVATION
+derive_output:PSA_ALG_TLS12_PRF(PSA_ALG_SHA_256):PSA_KEY_DERIVATION_INPUT_SEED:"a0ba9f936cda311827a6f796ffd5198c":PSA_KEY_DERIVATION_INPUT_SECRET:"9bbe436ba940f017b17652849a71db35":PSA_KEY_DERIVATION_INPUT_LABEL:"74657374206c6162656c":100:"e3f229ba727be17b8d122620557cd453c2aab21d07c3d495329b52d4e61edb5a6b301791e90d35c9c9a46b4e14baf9af0fa0":"22f7077def17abfd3797c0564bab4fbc91666e9def9b97fce34f796789baa48082d122ee42c5a72e5a5110fff70187347b"
 
 PSA key derivation: TLS 1.2 PRF SHA-384, output 148+0
-depends_on:MBEDTLS_MD_C:MBEDTLS_SHA512_C
-derive_output:PSA_ALG_TLS12_PRF(PSA_ALG_SHA_384):"b80b733d6ceefcdc71566ea48e5567df":"cd665cf6a8447dd6ff8b27555edb7465":"74657374206c6162656c":148:"7b0c18e9ced410ed1804f2cfa34a336a1c14dffb4900bb5fd7942107e81c83cde9ca0faa60be9fe34f82b1233c9146a0e534cb400fed2700884f9dc236f80edd8bfa961144c9e8d792eca722a7b32fc3d416d473ebc2c5fd4abfdad05d9184259b5bf8cd4d90fa0d31e2dec479e4f1a26066f2eea9a69236a3e52655c9e9aee691c8f3a26854308d5eaa3be85e0990703d73e56f":""
+depends_on:MBEDTLS_MD_C:MBEDTLS_SHA512_C:!PSA_PRE_1_0_KEY_DERIVATION
+derive_output:PSA_ALG_TLS12_PRF(PSA_ALG_SHA_384):PSA_KEY_DERIVATION_INPUT_SEED:"cd665cf6a8447dd6ff8b27555edb7465":PSA_KEY_DERIVATION_INPUT_SECRET:"b80b733d6ceefcdc71566ea48e5567df":PSA_KEY_DERIVATION_INPUT_LABEL:"74657374206c6162656c":148:"7b0c18e9ced410ed1804f2cfa34a336a1c14dffb4900bb5fd7942107e81c83cde9ca0faa60be9fe34f82b1233c9146a0e534cb400fed2700884f9dc236f80edd8bfa961144c9e8d792eca722a7b32fc3d416d473ebc2c5fd4abfdad05d9184259b5bf8cd4d90fa0d31e2dec479e4f1a26066f2eea9a69236a3e52655c9e9aee691c8f3a26854308d5eaa3be85e0990703d73e56f":""
 
 PSA key derivation: TLS 1.2 PRF SHA-384, output 147+1
-depends_on:MBEDTLS_MD_C:MBEDTLS_SHA512_C
-derive_output:PSA_ALG_TLS12_PRF(PSA_ALG_SHA_384):"b80b733d6ceefcdc71566ea48e5567df":"cd665cf6a8447dd6ff8b27555edb7465":"74657374206c6162656c":148:"7b0c18e9ced410ed1804f2cfa34a336a1c14dffb4900bb5fd7942107e81c83cde9ca0faa60be9fe34f82b1233c9146a0e534cb400fed2700884f9dc236f80edd8bfa961144c9e8d792eca722a7b32fc3d416d473ebc2c5fd4abfdad05d9184259b5bf8cd4d90fa0d31e2dec479e4f1a26066f2eea9a69236a3e52655c9e9aee691c8f3a26854308d5eaa3be85e0990703d73e5":"6f"
+depends_on:MBEDTLS_MD_C:MBEDTLS_SHA512_C:!PSA_PRE_1_0_KEY_DERIVATION
+derive_output:PSA_ALG_TLS12_PRF(PSA_ALG_SHA_384):PSA_KEY_DERIVATION_INPUT_SEED:"cd665cf6a8447dd6ff8b27555edb7465":PSA_KEY_DERIVATION_INPUT_SECRET:"b80b733d6ceefcdc71566ea48e5567df":PSA_KEY_DERIVATION_INPUT_LABEL:"74657374206c6162656c":148:"7b0c18e9ced410ed1804f2cfa34a336a1c14dffb4900bb5fd7942107e81c83cde9ca0faa60be9fe34f82b1233c9146a0e534cb400fed2700884f9dc236f80edd8bfa961144c9e8d792eca722a7b32fc3d416d473ebc2c5fd4abfdad05d9184259b5bf8cd4d90fa0d31e2dec479e4f1a26066f2eea9a69236a3e52655c9e9aee691c8f3a26854308d5eaa3be85e0990703d73e5":"6f"
 
 PSA key derivation: TLS 1.2 PRF SHA-384, output 1+147
-depends_on:MBEDTLS_MD_C:MBEDTLS_SHA512_C
-derive_output:PSA_ALG_TLS12_PRF(PSA_ALG_SHA_384):"b80b733d6ceefcdc71566ea48e5567df":"cd665cf6a8447dd6ff8b27555edb7465":"74657374206c6162656c":148:"7b":"0c18e9ced410ed1804f2cfa34a336a1c14dffb4900bb5fd7942107e81c83cde9ca0faa60be9fe34f82b1233c9146a0e534cb400fed2700884f9dc236f80edd8bfa961144c9e8d792eca722a7b32fc3d416d473ebc2c5fd4abfdad05d9184259b5bf8cd4d90fa0d31e2dec479e4f1a26066f2eea9a69236a3e52655c9e9aee691c8f3a26854308d5eaa3be85e0990703d73e56f"
+depends_on:MBEDTLS_MD_C:MBEDTLS_SHA512_C:!PSA_PRE_1_0_KEY_DERIVATION
+derive_output:PSA_ALG_TLS12_PRF(PSA_ALG_SHA_384):PSA_KEY_DERIVATION_INPUT_SEED:"cd665cf6a8447dd6ff8b27555edb7465":PSA_KEY_DERIVATION_INPUT_SECRET:"b80b733d6ceefcdc71566ea48e5567df":PSA_KEY_DERIVATION_INPUT_LABEL:"74657374206c6162656c":148:"7b":"0c18e9ced410ed1804f2cfa34a336a1c14dffb4900bb5fd7942107e81c83cde9ca0faa60be9fe34f82b1233c9146a0e534cb400fed2700884f9dc236f80edd8bfa961144c9e8d792eca722a7b32fc3d416d473ebc2c5fd4abfdad05d9184259b5bf8cd4d90fa0d31e2dec479e4f1a26066f2eea9a69236a3e52655c9e9aee691c8f3a26854308d5eaa3be85e0990703d73e56f"
 
 PSA key derivation: TLS 1.2 PRF SHA-384, output 74+74
-depends_on:MBEDTLS_MD_C:MBEDTLS_SHA512_C
-derive_output:PSA_ALG_TLS12_PRF(PSA_ALG_SHA_384):"b80b733d6ceefcdc71566ea48e5567df":"cd665cf6a8447dd6ff8b27555edb7465":"74657374206c6162656c":148:"7b0c18e9ced410ed1804f2cfa34a336a1c14dffb4900bb5fd7942107e81c83cde9ca0faa60be9fe34f82b1233c9146a0e534cb400fed2700884f9dc236f80edd8bfa961144c9e8d792ec":"a722a7b32fc3d416d473ebc2c5fd4abfdad05d9184259b5bf8cd4d90fa0d31e2dec479e4f1a26066f2eea9a69236a3e52655c9e9aee691c8f3a26854308d5eaa3be85e0990703d73e56f"
+depends_on:MBEDTLS_MD_C:MBEDTLS_SHA512_C:!PSA_PRE_1_0_KEY_DERIVATION
+derive_output:PSA_ALG_TLS12_PRF(PSA_ALG_SHA_384):PSA_KEY_DERIVATION_INPUT_SEED:"cd665cf6a8447dd6ff8b27555edb7465":PSA_KEY_DERIVATION_INPUT_SECRET:"b80b733d6ceefcdc71566ea48e5567df":PSA_KEY_DERIVATION_INPUT_LABEL:"74657374206c6162656c":148:"7b0c18e9ced410ed1804f2cfa34a336a1c14dffb4900bb5fd7942107e81c83cde9ca0faa60be9fe34f82b1233c9146a0e534cb400fed2700884f9dc236f80edd8bfa961144c9e8d792ec":"a722a7b32fc3d416d473ebc2c5fd4abfdad05d9184259b5bf8cd4d90fa0d31e2dec479e4f1a26066f2eea9a69236a3e52655c9e9aee691c8f3a26854308d5eaa3be85e0990703d73e56f"
 
 PSA key derivation: TLS 1.2 PRF SHA-384, output 74+73
-depends_on:MBEDTLS_MD_C:MBEDTLS_SHA512_C
-derive_output:PSA_ALG_TLS12_PRF(PSA_ALG_SHA_384):"b80b733d6ceefcdc71566ea48e5567df":"cd665cf6a8447dd6ff8b27555edb7465":"74657374206c6162656c":148:"7b0c18e9ced410ed1804f2cfa34a336a1c14dffb4900bb5fd7942107e81c83cde9ca0faa60be9fe34f82b1233c9146a0e534cb400fed2700884f9dc236f80edd8bfa961144c9e8d792ec":"a722a7b32fc3d416d473ebc2c5fd4abfdad05d9184259b5bf8cd4d90fa0d31e2dec479e4f1a26066f2eea9a69236a3e52655c9e9aee691c8f3a26854308d5eaa3be85e0990703d73e5"
+depends_on:MBEDTLS_MD_C:MBEDTLS_SHA512_C:!PSA_PRE_1_0_KEY_DERIVATION
+derive_output:PSA_ALG_TLS12_PRF(PSA_ALG_SHA_384):PSA_KEY_DERIVATION_INPUT_SEED:"cd665cf6a8447dd6ff8b27555edb7465":PSA_KEY_DERIVATION_INPUT_SECRET:"b80b733d6ceefcdc71566ea48e5567df":PSA_KEY_DERIVATION_INPUT_LABEL:"74657374206c6162656c":148:"7b0c18e9ced410ed1804f2cfa34a336a1c14dffb4900bb5fd7942107e81c83cde9ca0faa60be9fe34f82b1233c9146a0e534cb400fed2700884f9dc236f80edd8bfa961144c9e8d792ec":"a722a7b32fc3d416d473ebc2c5fd4abfdad05d9184259b5bf8cd4d90fa0d31e2dec479e4f1a26066f2eea9a69236a3e52655c9e9aee691c8f3a26854308d5eaa3be85e0990703d73e5"
 
 # Test case manually extracted from debug output of TLS-PSK run
 # Label: "master secret"
 # Salt: Concatenation of ClientHello.Random and ServerHello.Random
 PSA key derivation: TLS 1.2 PSK-to-MS, SHA-256, 48+0
-depends_on:MBEDTLS_MD_C:MBEDTLS_SHA256_C
-derive_output:PSA_ALG_TLS12_PSK_TO_MS(PSA_ALG_SHA_256):"01020304":"5bc0b19b4a8b24b07afe7ec65c471e94a7d518fcef06c3574315255c52afe21b5bc0b19b872b9b26508458f03603744d575f463a11ae7f1b090c012606fd3e9f":"6d617374657220736563726574":48:"5a9dd5ffa78b4d1f28f40d91b4e6e6ed37849042d61ba32ca43d866e744cee7cd1baaa497e1ecd5c2e60f9f13030a710":""
+depends_on:MBEDTLS_MD_C:MBEDTLS_SHA256_C:!PSA_PRE_1_0_KEY_DERIVATION
+derive_output:PSA_ALG_TLS12_PSK_TO_MS(PSA_ALG_SHA_256):PSA_KEY_DERIVATION_INPUT_SEED:"5bc0b19b4a8b24b07afe7ec65c471e94a7d518fcef06c3574315255c52afe21b5bc0b19b872b9b26508458f03603744d575f463a11ae7f1b090c012606fd3e9f":PSA_KEY_DERIVATION_INPUT_SECRET:"01020304":PSA_KEY_DERIVATION_INPUT_LABEL:"6d617374657220736563726574":48:"5a9dd5ffa78b4d1f28f40d91b4e6e6ed37849042d61ba32ca43d866e744cee7cd1baaa497e1ecd5c2e60f9f13030a710":""
 
 PSA key derivation: TLS 1.2 PSK-to-MS, SHA-256, 24+24
-depends_on:MBEDTLS_MD_C:MBEDTLS_SHA256_C
-derive_output:PSA_ALG_TLS12_PSK_TO_MS(PSA_ALG_SHA_256):"01020304":"5bc0b19b4a8b24b07afe7ec65c471e94a7d518fcef06c3574315255c52afe21b5bc0b19b872b9b26508458f03603744d575f463a11ae7f1b090c012606fd3e9f":"6d617374657220736563726574":48:"5a9dd5ffa78b4d1f28f40d91b4e6e6ed37849042d61ba32c":"a43d866e744cee7cd1baaa497e1ecd5c2e60f9f13030a710"
+depends_on:MBEDTLS_MD_C:MBEDTLS_SHA256_C:!PSA_PRE_1_0_KEY_DERIVATION
+derive_output:PSA_ALG_TLS12_PSK_TO_MS(PSA_ALG_SHA_256):PSA_KEY_DERIVATION_INPUT_SEED:"5bc0b19b4a8b24b07afe7ec65c471e94a7d518fcef06c3574315255c52afe21b5bc0b19b872b9b26508458f03603744d575f463a11ae7f1b090c012606fd3e9f":PSA_KEY_DERIVATION_INPUT_SECRET:"01020304":PSA_KEY_DERIVATION_INPUT_LABEL:"6d617374657220736563726574":48:"5a9dd5ffa78b4d1f28f40d91b4e6e6ed37849042d61ba32c":"a43d866e744cee7cd1baaa497e1ecd5c2e60f9f13030a710"
 
 PSA key derivation: TLS 1.2 PSK-to-MS, SHA-256, 0+48
-depends_on:MBEDTLS_MD_C:MBEDTLS_SHA256_C
-derive_output:PSA_ALG_TLS12_PSK_TO_MS(PSA_ALG_SHA_256):"01020304":"5bc0b19b4a8b24b07afe7ec65c471e94a7d518fcef06c3574315255c52afe21b5bc0b19b872b9b26508458f03603744d575f463a11ae7f1b090c012606fd3e9f":"6d617374657220736563726574":48:"":"5a9dd5ffa78b4d1f28f40d91b4e6e6ed37849042d61ba32ca43d866e744cee7cd1baaa497e1ecd5c2e60f9f13030a710"
+depends_on:MBEDTLS_MD_C:MBEDTLS_SHA256_C:!PSA_PRE_1_0_KEY_DERIVATION
+derive_output:PSA_ALG_TLS12_PSK_TO_MS(PSA_ALG_SHA_256):PSA_KEY_DERIVATION_INPUT_SEED:"5bc0b19b4a8b24b07afe7ec65c471e94a7d518fcef06c3574315255c52afe21b5bc0b19b872b9b26508458f03603744d575f463a11ae7f1b090c012606fd3e9f":PSA_KEY_DERIVATION_INPUT_SECRET:"01020304":PSA_KEY_DERIVATION_INPUT_LABEL:"6d617374657220736563726574":48:"":"5a9dd5ffa78b4d1f28f40d91b4e6e6ed37849042d61ba32ca43d866e744cee7cd1baaa497e1ecd5c2e60f9f13030a710"
 
 PSA key derivation: TLS 1.2 PSK-to-MS, SHA-384, 48+0
-depends_on:MBEDTLS_MD_C:MBEDTLS_SHA512_C
-derive_output:PSA_ALG_TLS12_PSK_TO_MS(PSA_ALG_SHA_384):"01020304":"5bed47716a11a49a6268a8350b085929116ad9ccc8181f09a05b07a7741576d65bed47718dfd82f2d3f57544afe52decae6819b970dc716ada72ae0dd3072e9a":"6d617374657220736563726574":48:"f5a61fbdd2ec415762abb8042a6c16645a53d2edb6dec8c85ca71689301f9f4d875128c87608b75250b20a9550e4fe18":""
+depends_on:MBEDTLS_MD_C:MBEDTLS_SHA512_C:!PSA_PRE_1_0_KEY_DERIVATION
+derive_output:PSA_ALG_TLS12_PSK_TO_MS(PSA_ALG_SHA_384):PSA_KEY_DERIVATION_INPUT_SEED:"5bed47716a11a49a6268a8350b085929116ad9ccc8181f09a05b07a7741576d65bed47718dfd82f2d3f57544afe52decae6819b970dc716ada72ae0dd3072e9a":PSA_KEY_DERIVATION_INPUT_SECRET:"01020304":PSA_KEY_DERIVATION_INPUT_LABEL:"6d617374657220736563726574":48:"f5a61fbdd2ec415762abb8042a6c16645a53d2edb6dec8c85ca71689301f9f4d875128c87608b75250b20a9550e4fe18":""
 
 PSA key derivation: TLS 1.2 PSK-to-MS, SHA-384, 24+24
-depends_on:MBEDTLS_MD_C:MBEDTLS_SHA512_C
-derive_output:PSA_ALG_TLS12_PSK_TO_MS(PSA_ALG_SHA_384):"01020304":"5bed47716a11a49a6268a8350b085929116ad9ccc8181f09a05b07a7741576d65bed47718dfd82f2d3f57544afe52decae6819b970dc716ada72ae0dd3072e9a":"6d617374657220736563726574":48:"":"f5a61fbdd2ec415762abb8042a6c16645a53d2edb6dec8c85ca71689301f9f4d875128c87608b75250b20a9550e4fe18"
+depends_on:MBEDTLS_MD_C:MBEDTLS_SHA512_C:!PSA_PRE_1_0_KEY_DERIVATION
+derive_output:PSA_ALG_TLS12_PSK_TO_MS(PSA_ALG_SHA_384):PSA_KEY_DERIVATION_INPUT_SEED:"5bed47716a11a49a6268a8350b085929116ad9ccc8181f09a05b07a7741576d65bed47718dfd82f2d3f57544afe52decae6819b970dc716ada72ae0dd3072e9a":PSA_KEY_DERIVATION_INPUT_SECRET:"01020304":PSA_KEY_DERIVATION_INPUT_LABEL:"6d617374657220736563726574":48:"":"f5a61fbdd2ec415762abb8042a6c16645a53d2edb6dec8c85ca71689301f9f4d875128c87608b75250b20a9550e4fe18"
 
 PSA key derivation: TLS 1.2 PSK-to-MS, SHA-384, 0+48
-depends_on:MBEDTLS_MD_C:MBEDTLS_SHA512_C
-derive_output:PSA_ALG_TLS12_PSK_TO_MS(PSA_ALG_SHA_384):"01020304":"5bed47716a11a49a6268a8350b085929116ad9ccc8181f09a05b07a7741576d65bed47718dfd82f2d3f57544afe52decae6819b970dc716ada72ae0dd3072e9a":"6d617374657220736563726574":48:"f5a61fbdd2ec415762abb8042a6c16645a53d2edb6dec8c8":"5ca71689301f9f4d875128c87608b75250b20a9550e4fe18"
+depends_on:MBEDTLS_MD_C:MBEDTLS_SHA512_C:!PSA_PRE_1_0_KEY_DERIVATION
+derive_output:PSA_ALG_TLS12_PSK_TO_MS(PSA_ALG_SHA_384):PSA_KEY_DERIVATION_INPUT_SEED:"5bed47716a11a49a6268a8350b085929116ad9ccc8181f09a05b07a7741576d65bed47718dfd82f2d3f57544afe52decae6819b970dc716ada72ae0dd3072e9a":PSA_KEY_DERIVATION_INPUT_SECRET:"01020304":PSA_KEY_DERIVATION_INPUT_LABEL:"6d617374657220736563726574":48:"f5a61fbdd2ec415762abb8042a6c16645a53d2edb6dec8c8":"5ca71689301f9f4d875128c87608b75250b20a9550e4fe18"
 
 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":""
+derive_output:PSA_ALG_HKDF(PSA_ALG_SHA_256):PSA_KEY_DERIVATION_INPUT_SALT:"000102030405060708090a0b0c":PSA_KEY_DERIVATION_INPUT_SECRET:"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":PSA_KEY_DERIVATION_INPUT_INFO:"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":""
+derive_output:PSA_ALG_HKDF(PSA_ALG_SHA_1):PSA_KEY_DERIVATION_INPUT_SALT:"":PSA_KEY_DERIVATION_INPUT_SECRET:"0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c":PSA_KEY_DERIVATION_INPUT_INFO:"":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
+derive_set_capacity:PSA_ALG_HKDF(PSA_ALG_SHA_256):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
+derive_set_capacity:PSA_ALG_HKDF(PSA_ALG_SHA_1):255 * 20 + 1:PSA_ERROR_INVALID_ARGUMENT
 
 PSA key derivation: TLS 1.2 PSK-to-MS, SHA-256, PSK too long (160 Bytes)
-depends_on:MBEDTLS_MD_C:MBEDTLS_SHA256_C
-derive_setup:PSA_KEY_TYPE_DERIVE:"01020304050607080102030405060708010203040506070801020304050607080102030405060708010203040506070801020304050607080102030405060708010203040506070801020304050607080102030405060708010203040506070801020304050607080102030405060708010203040506070801020304050607080102030405060708010203040506070801020304050607080102030405060708":PSA_ALG_TLS12_PSK_TO_MS(PSA_ALG_SHA_256):"":"":100:PSA_ERROR_INVALID_ARGUMENT
+depends_on:MBEDTLS_MD_C:MBEDTLS_SHA256_C:!PSA_PRE_1_0_KEY_DERIVATION
+derive_input:PSA_ALG_TLS12_PSK_TO_MS(PSA_ALG_SHA_256):PSA_KEY_TYPE_DERIVE:PSA_KEY_DERIVATION_INPUT_SEED:"":PSA_KEY_DERIVATION_INPUT_SECRET:"01020304050607080102030405060708010203040506070801020304050607080102030405060708010203040506070801020304050607080102030405060708010203040506070801020304050607080102030405060708010203040506070801020304050607080102030405060708010203040506070801020304050607080102030405060708010203040506070801020304050607080102030405060708":PSA_KEY_DERIVATION_INPUT_LABEL:"":PSA_SUCCESS:PSA_ERROR_INVALID_ARGUMENT:PSA_ERROR_BAD_STATE
 
 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"
+derive_output:PSA_ALG_HKDF(PSA_ALG_SHA_256):PSA_KEY_DERIVATION_INPUT_SALT:"000102030405060708090a0b0c":PSA_KEY_DERIVATION_INPUT_SECRET:"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":PSA_KEY_DERIVATION_INPUT_INFO:"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"
+derive_output:PSA_ALG_HKDF(PSA_ALG_SHA_256):PSA_KEY_DERIVATION_INPUT_SALT:"000102030405060708090a0b0c":PSA_KEY_DERIVATION_INPUT_SECRET:"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":PSA_KEY_DERIVATION_INPUT_INFO:"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":""
+derive_output:PSA_ALG_HKDF(PSA_ALG_SHA_256):PSA_KEY_DERIVATION_INPUT_SALT:"000102030405060708090a0b0c":PSA_KEY_DERIVATION_INPUT_SECRET:"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":PSA_KEY_DERIVATION_INPUT_INFO:"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"
+derive_output:PSA_ALG_HKDF(PSA_ALG_SHA_256):PSA_KEY_DERIVATION_INPUT_SALT:"000102030405060708090a0b0c":PSA_KEY_DERIVATION_INPUT_SECRET:"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":PSA_KEY_DERIVATION_INPUT_INFO:"f0f1f2f3f4f5f6f7f8f9":42:"3cb25f25faacd57a90434f64d0362f2a2d2d0a90cf1a5a4c5db02d56ecc4c5bf34007208d5b887185865ff":"ff"
 
 PSA key derivation: HKDF SHA-256, read maximum capacity minus 1
 depends_on:MBEDTLS_MD_C:MBEDTLS_SHA256_C
diff --git a/tests/suites/test_suite_psa_crypto.function b/tests/suites/test_suite_psa_crypto.function
index 4441e9b..48f5337 100644
--- a/tests/suites/test_suite_psa_crypto.function
+++ b/tests/suites/test_suite_psa_crypto.function
@@ -545,6 +545,7 @@
                                                         seed,
                                                         seed_length ) );
         }
+#if defined(PSA_PRE_1_0_KEY_DERIVATION)
         else
         {
             // legacy
@@ -554,6 +555,7 @@
                                             seed, seed_length,
                                             sizeof( output ) ) );
         }
+#endif
         PSA_ASSERT( psa_key_derivation_output_bytes( &operation,
                                                      output,
                                                      sizeof( output ) ) );
@@ -1797,11 +1799,21 @@
     PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
                                 &handle ) );
 
-    status = psa_key_derivation( &operation, handle,
-                                 exercise_alg,
-                                 NULL, 0,
-                                 NULL, 0,
-                                 1 );
+    PSA_ASSERT( psa_key_derivation_setup( &operation, exercise_alg ) );
+
+    if( PSA_ALG_IS_TLS12_PRF( exercise_alg ) ||
+            PSA_ALG_IS_TLS12_PSK_TO_MS( exercise_alg ) )
+    {
+        PSA_ASSERT( psa_key_derivation_input_bytes(
+                                            &operation,
+                                            PSA_KEY_DERIVATION_INPUT_SEED,
+                                            (const uint8_t*) "", 0) );
+    }
+
+    status = psa_key_derivation_input_key( &operation,
+                                           PSA_KEY_DERIVATION_INPUT_SECRET,
+                                           handle );
+
     if( policy_alg == exercise_alg &&
         ( policy_usage & PSA_KEY_USAGE_DERIVE ) != 0 )
         PSA_ASSERT( status );
@@ -4025,21 +4037,66 @@
 /* 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 )
+void derive_setup( int alg_arg, int expected_status_arg )
 {
-    psa_key_handle_t handle = 0;
-    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_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
+
+    PSA_ASSERT( psa_crypto_init( ) );
+
+    TEST_EQUAL( psa_key_derivation_setup( &operation, alg ),
+                expected_status );
+
+exit:
+    psa_key_derivation_abort( &operation );
+    PSA_DONE( );
+}
+/* END_CASE */
+
+/* BEGIN_CASE */
+void derive_set_capacity( int alg_arg, int capacity_arg,
+                          int expected_status_arg )
+{
+    psa_algorithm_t alg = alg_arg;
+    size_t capacity = capacity_arg;
+    psa_status_t expected_status = expected_status_arg;
+    psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
+
+    PSA_ASSERT( psa_crypto_init( ) );
+
+    PSA_ASSERT( psa_key_derivation_setup( &operation, alg ) );
+
+    TEST_EQUAL( psa_key_derivation_set_capacity( &operation, capacity ),
+                expected_status );
+
+exit:
+    psa_key_derivation_abort( &operation );
+    PSA_DONE( );
+}
+/* END_CASE */
+
+/* BEGIN_CASE */
+void derive_input( int alg_arg,
+                   int key_type_arg,
+                   int step1_arg, data_t *input1,
+                   int step2_arg, data_t *input2,
+                   int step3_arg, data_t *input3,
+                   int expected_status_arg1,
+                   int expected_status_arg2,
+                   int expected_status_arg3 )
+{
+    psa_algorithm_t alg = alg_arg;
+    size_t key_type = key_type_arg;
+    psa_key_derivation_step_t steps[] = {step1_arg, step2_arg, step3_arg};
+    psa_status_t expected_statuses[] = {expected_status_arg1,
+                                        expected_status_arg2,
+                                        expected_status_arg3};
+    data_t *inputs[] = {input1, input2, input3};
+    psa_key_handle_t handles[] = {0, 0, 0};
+    psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
     psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
+    size_t i;
 
     PSA_ASSERT( psa_crypto_init( ) );
 
@@ -4047,23 +4104,38 @@
     psa_set_key_algorithm( &attributes, alg );
     psa_set_key_type( &attributes, key_type );
 
-    PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
-                                &handle ) );
+    PSA_ASSERT( psa_key_derivation_setup( &operation, alg ) );
 
-    TEST_EQUAL( psa_key_derivation( &operation, handle, alg,
-                                    salt->x, salt->len,
-                                    label->x, label->len,
-                                    requested_capacity ),
-                expected_status );
+    for( i = 0; i < ARRAY_LENGTH( steps ); i++ )
+    {
+        switch( steps[i] )
+        {
+            case PSA_KEY_DERIVATION_INPUT_SECRET:
+                PSA_ASSERT( psa_import_key( &attributes,
+                                            inputs[i]->x, inputs[i]->len,
+                                            &handles[i] ) );
+                TEST_EQUAL( psa_key_derivation_input_key( &operation, steps[i],
+                                                          handles[i] ),
+                            expected_statuses[i] );
+                break;
+            default:
+                TEST_EQUAL( psa_key_derivation_input_bytes(
+                                    &operation, steps[i],
+                                    inputs[i]->x, inputs[i]->len ),
+                            expected_statuses[i] );
+                break;
+        }
+    }
 
 exit:
     psa_key_derivation_abort( &operation );
-    psa_destroy_key( handle );
+    for( i = 0; i < ARRAY_LENGTH( handles ); i++ )
+        psa_destroy_key( handles[i] );
     PSA_DONE( );
 }
 /* END_CASE */
 
-/* BEGIN_CASE */
+/* BEGIN_CASE depends_on:PSA_PRE_1_0_KEY_DERIVATION */
 void test_derive_invalid_key_derivation_state( )
 {
     psa_key_handle_t handle = 0;
@@ -4143,15 +4215,17 @@
 
 /* BEGIN_CASE */
 void derive_output( int alg_arg,
-                    data_t *key_data,
-                    data_t *salt,
-                    data_t *label,
+                    int step1_arg, data_t *input1,
+                    int step2_arg, data_t *input2,
+                    int step3_arg, data_t *input3,
                     int requested_capacity_arg,
                     data_t *expected_output1,
                     data_t *expected_output2 )
 {
-    psa_key_handle_t handle = 0;
     psa_algorithm_t alg = alg_arg;
+    psa_key_derivation_step_t steps[] = {step1_arg, step2_arg, step3_arg};
+    data_t *inputs[] = {input1, input2, input3};
+    psa_key_handle_t handles[] = {0, 0, 0};
     size_t requested_capacity = requested_capacity_arg;
     psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
     uint8_t *expected_outputs[2] =
@@ -4164,7 +4238,7 @@
     size_t current_capacity;
     psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
     psa_status_t status;
-    unsigned i;
+    size_t i;
 
     for( i = 0; i < ARRAY_LENGTH( expected_outputs ); i++ )
     {
@@ -4180,33 +4254,32 @@
     psa_set_key_algorithm( &attributes, alg );
     psa_set_key_type( &attributes, PSA_KEY_TYPE_DERIVE );
 
-    PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
-                                &handle ) );
-
     /* Extraction phase. */
-    if( PSA_ALG_IS_HKDF( alg ) )
+    PSA_ASSERT( psa_key_derivation_setup( &operation, alg ) );
+    PSA_ASSERT( psa_key_derivation_set_capacity( &operation,
+                                                 requested_capacity ) );
+    for( i = 0; i < ARRAY_LENGTH( steps ); i++ )
     {
-        PSA_ASSERT( psa_key_derivation_setup( &operation, alg ) );
-        PSA_ASSERT( psa_key_derivation_set_capacity( &operation,
-                                                     requested_capacity ) );
-        PSA_ASSERT( psa_key_derivation_input_bytes( &operation,
-                                                    PSA_KEY_DERIVATION_INPUT_SALT,
-                                                    salt->x, salt->len ) );
-        PSA_ASSERT( psa_key_derivation_input_key( &operation,
-                                                  PSA_KEY_DERIVATION_INPUT_SECRET,
-                                                  handle ) );
-        PSA_ASSERT( psa_key_derivation_input_bytes( &operation,
-                                                    PSA_KEY_DERIVATION_INPUT_INFO,
-                                                    label->x, label->len ) );
+        switch( steps[i] )
+        {
+            case 0:
+                break;
+            case PSA_KEY_DERIVATION_INPUT_SECRET:
+                PSA_ASSERT( psa_import_key( &attributes,
+                                            inputs[i]->x, inputs[i]->len,
+                                            &handles[i] ) );
+                PSA_ASSERT( psa_key_derivation_input_key(
+                                &operation, steps[i],
+                                handles[i] ) );
+                break;
+            default:
+                PSA_ASSERT( psa_key_derivation_input_bytes(
+                                &operation, steps[i],
+                                inputs[i]->x, inputs[i]->len ) );
+                break;
+        }
     }
-    else
-    {
-        // legacy
-        PSA_ASSERT( psa_key_derivation( &operation, handle, alg,
-                                        salt->x, salt->len,
-                                        label->x, label->len,
-                                        requested_capacity ) );
-    }
+
     PSA_ASSERT( psa_key_derivation_get_capacity( &operation,
                                                  &current_capacity ) );
     TEST_EQUAL( current_capacity, requested_capacity );
@@ -4249,7 +4322,8 @@
 exit:
     mbedtls_free( output_buffer );
     psa_key_derivation_abort( &operation );
-    psa_destroy_key( handle );
+    for( i = 0; i < ARRAY_LENGTH( handles ); i++ )
+        psa_destroy_key( handles[i] );
     PSA_DONE( );
 }
 /* END_CASE */
@@ -4295,6 +4369,8 @@
                                                     PSA_KEY_DERIVATION_INPUT_INFO,
                                                     label->x, label->len ) );
     }
+
+#if defined(PSA_PRE_1_0_KEY_DERIVATION)
     else
     {
         // legacy
@@ -4303,6 +4379,7 @@
                                         label->x, label->len,
                                         requested_capacity ) );
     }
+#endif
     PSA_ASSERT( psa_key_derivation_get_capacity( &operation,
                                                  &current_capacity ) );
     TEST_EQUAL( current_capacity, expected_capacity );
@@ -4335,7 +4412,7 @@
 }
 /* END_CASE */
 
-/* BEGIN_CASE */
+/* BEGIN_CASE depends_on:PSA_PRE_1_0_KEY_DERIVATION */
 void derive_key_exercise( int alg_arg,
                           data_t *key_data,
                           data_t *salt,
@@ -4395,7 +4472,7 @@
 }
 /* END_CASE */
 
-/* BEGIN_CASE */
+/* BEGIN_CASE depends_on:PSA_PRE_1_0_KEY_DERIVATION */
 void derive_key_export( int alg_arg,
                         data_t *key_data,
                         data_t *salt,