Add framework for simple key derivation

New key type PSA_KEY_TYPE_DERIVE. New usage flag PSA_KEY_USAGE_DERIVE.
New function psa_key_derivation.

No key derivation algorithm is implemented yet. The code may not
compile with -Wunused.

Write some unit test code for psa_key_derivation. Most of it cannot be
used yet due to the lack of a key derivation algorithm.
diff --git a/tests/suites/test_suite_psa_crypto.function b/tests/suites/test_suite_psa_crypto.function
index 37d6aca..278554f 100644
--- a/tests/suites/test_suite_psa_crypto.function
+++ b/tests/suites/test_suite_psa_crypto.function
@@ -357,6 +357,36 @@
     return( 0 );
 }
 
+static int exercise_key_derivation_key( psa_key_slot_t key,
+                                        psa_key_usage_t usage,
+                                        psa_algorithm_t alg )
+{
+    psa_crypto_generator_t generator = PSA_CRYPTO_GENERATOR_INIT;
+    unsigned char label[16] = "This is a label.";
+    size_t label_length = sizeof( label );
+    unsigned char seed[16] = "abcdefghijklmnop";
+    size_t seed_length = sizeof( seed );
+    unsigned char output[1];
+
+    if( usage & PSA_KEY_USAGE_DERIVE )
+    {
+        TEST_ASSERT( psa_key_derivation( &generator,
+                                         key, alg,
+                                         label, label_length,
+                                         seed, seed_length,
+                                         sizeof( output ) ) == PSA_SUCCESS );
+        TEST_ASSERT( psa_generator_read( &generator,
+                                         output,
+                                         sizeof( output ) ) == PSA_SUCCESS );
+        TEST_ASSERT( psa_generator_abort( &generator ) == PSA_SUCCESS );
+    }
+
+    return( 1 );
+
+exit:
+    return( 0 );
+}
+
 static int exercise_key( psa_key_slot_t slot,
                          psa_key_usage_t usage,
                          psa_algorithm_t alg )
@@ -374,6 +404,8 @@
         ok = exercise_signature_key( slot, usage, alg );
     else if( PSA_ALG_IS_ASYMMETRIC_ENCRYPTION( alg ) )
         ok = exercise_asymmetric_encryption_key( slot, usage, alg );
+    else if( PSA_ALG_IS_KEY_DERIVATION( alg ) )
+        ok = exercise_key_derivation_key( slot, usage, alg );
     else
     {
         char message[40];
@@ -657,6 +689,7 @@
           ( PSA_KEY_TYPE_IS_PUBLIC_KEY( type ) ?
             PSA_KEY_USAGE_ENCRYPT :
             PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT ) :
+          PSA_ALG_IS_KEY_DERIVATION( alg ) ? PSA_KEY_USAGE_DERIVE :
           0 );
     psa_key_policy_t policy;
     psa_key_type_t got_type;
@@ -992,6 +1025,45 @@
 /* END_CASE */
 
 /* BEGIN_CASE */
+void derive_key_policy( int policy_usage,
+                        int policy_alg,
+                        int key_type,
+                        data_t *key_data,
+                        int exercise_alg )
+{
+    int key_slot = 1;
+    psa_key_policy_t policy;
+    psa_crypto_generator_t generator = PSA_CRYPTO_GENERATOR_INIT;
+    psa_status_t status;
+
+    TEST_ASSERT( psa_crypto_init( ) == PSA_SUCCESS );
+
+    psa_key_policy_init( &policy );
+    psa_key_policy_set_usage( &policy, policy_usage, policy_alg );
+    TEST_ASSERT( psa_set_key_policy( key_slot, &policy ) == PSA_SUCCESS );
+
+    TEST_ASSERT( psa_import_key( key_slot, key_type,
+                                 key_data->x, key_data->len ) == PSA_SUCCESS );
+
+    status = psa_key_derivation( &generator, key_slot,
+                                 exercise_alg,
+                                 NULL, 0,
+                                 NULL, 0,
+                                 1 );
+    if( policy_alg == exercise_alg &&
+        ( policy_usage & PSA_KEY_USAGE_DERIVE ) != 0 )
+        TEST_ASSERT( status == PSA_SUCCESS );
+    else
+        TEST_ASSERT( status == PSA_ERROR_NOT_PERMITTED );
+
+exit:
+    psa_generator_abort( &generator );
+    psa_destroy_key( key_slot );
+    mbedtls_psa_crypto_free( );
+}
+/* END_CASE */
+
+/* BEGIN_CASE */
 void key_lifetime( int lifetime_arg )
 {
     int key_slot = 1;
@@ -2373,6 +2445,45 @@
 /* END_CASE */
 
 /* BEGIN_CASE */
+void derive_setup( int key_type_arg,
+                   data_t *key_data,
+                   int alg_arg,
+                   data_t *salt,
+                   data_t *label,
+                   int requested_capacity_arg,
+                   int expected_status_arg )
+{
+    psa_key_slot_t slot = 1;
+    size_t key_type = key_type_arg;
+    psa_algorithm_t alg = alg_arg;
+    size_t requested_capacity = requested_capacity_arg;
+    psa_status_t expected_status = expected_status_arg;
+    psa_crypto_generator_t generator = PSA_CRYPTO_GENERATOR_INIT;
+    psa_key_policy_t policy;
+
+    TEST_ASSERT( psa_crypto_init( ) == PSA_SUCCESS );
+
+    psa_key_policy_init( &policy );
+    psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_DERIVE, alg );
+    TEST_ASSERT( psa_set_key_policy( slot, &policy ) == PSA_SUCCESS );
+
+    TEST_ASSERT( psa_import_key( slot, key_type,
+                                 key_data->x,
+                                 key_data->len ) == PSA_SUCCESS );
+
+    TEST_ASSERT( psa_key_derivation( &generator, slot, alg,
+                                     salt->x, salt->len,
+                                     label->x, label->len,
+                                     requested_capacity ) == expected_status );
+
+exit:
+    psa_generator_abort( &generator );
+    psa_destroy_key( slot );
+    mbedtls_psa_crypto_free( );
+}
+/* END_CASE */
+
+/* BEGIN_CASE */
 void generate_random( int bytes_arg )
 {
     size_t bytes = bytes_arg;