Implement psa_generate_key_ext, psa_key_derivation_output_key_ext

Implement and unit-test the new functions psa_generate_key_ext() and
psa_key_derivation_output_key_ext(), only for the default method.

Signed-off-by: Gilles Peskine <Gilles.Peskine@arm.com>
diff --git a/library/psa_crypto.c b/library/psa_crypto.c
index 4a0666b..6263be9 100644
--- a/library/psa_crypto.c
+++ b/library/psa_crypto.c
@@ -6023,9 +6023,27 @@
     return status;
 }
 
-psa_status_t psa_key_derivation_output_key(const psa_key_attributes_t *attributes,
-                                           psa_key_derivation_operation_t *operation,
-                                           mbedtls_svc_key_id_t *key)
+static const psa_key_generation_method_t default_method = PSA_KEY_GENERATION_METHOD_INIT;
+
+static int psa_key_generation_method_is_default(
+    const psa_key_generation_method_t *method,
+    size_t method_length)
+{
+    if (method_length != sizeof(*method)) {
+        return 0;
+    }
+    if (method->flags != 0) {
+        return 0;
+    }
+    return 1;
+}
+
+psa_status_t psa_key_derivation_output_key_ext(
+    const psa_key_attributes_t *attributes,
+    psa_key_derivation_operation_t *operation,
+    const psa_key_generation_method_t *method,
+    size_t method_length,
+    mbedtls_svc_key_id_t *key)
 {
     psa_status_t status;
     psa_key_slot_t *slot = NULL;
@@ -6039,6 +6057,13 @@
         return PSA_ERROR_INVALID_ARGUMENT;
     }
 
+    if (method_length < sizeof(*method)) {
+        return PSA_ERROR_INVALID_ARGUMENT;
+    }
+    if (!psa_key_generation_method_is_default(method, method_length)) {
+        return PSA_ERROR_INVALID_ARGUMENT;
+    }
+
     if (operation->alg == PSA_ALG_NONE) {
         return PSA_ERROR_BAD_STATE;
     }
@@ -6070,6 +6095,16 @@
     return status;
 }
 
+psa_status_t psa_key_derivation_output_key(
+    const psa_key_attributes_t *attributes,
+    psa_key_derivation_operation_t *operation,
+    mbedtls_svc_key_id_t *key)
+{
+    return psa_key_derivation_output_key_ext(
+        attributes, operation,
+        &default_method, sizeof(default_method),
+        key);
+}
 
 
 /****************************************************************/
@@ -7523,8 +7558,10 @@
     return PSA_SUCCESS;
 }
 
-psa_status_t psa_generate_key(const psa_key_attributes_t *attributes,
-                              mbedtls_svc_key_id_t *key)
+psa_status_t psa_generate_key_ext(const psa_key_attributes_t *attributes,
+                                  const psa_key_generation_method_t *method,
+                                  size_t method_length,
+                                  mbedtls_svc_key_id_t *key)
 {
     psa_status_t status;
     psa_key_slot_t *slot = NULL;
@@ -7544,6 +7581,13 @@
         return PSA_ERROR_INVALID_ARGUMENT;
     }
 
+    if (method_length < sizeof(*method)) {
+        return PSA_ERROR_INVALID_ARGUMENT;
+    }
+    if (!psa_key_generation_method_is_default(method, method_length)) {
+        return PSA_ERROR_INVALID_ARGUMENT;
+    }
+
     status = psa_start_key_creation(PSA_KEY_CREATION_GENERATE, attributes,
                                     &slot, &driver);
     if (status != PSA_SUCCESS) {
@@ -7598,6 +7642,14 @@
     return status;
 }
 
+psa_status_t psa_generate_key(const psa_key_attributes_t *attributes,
+                              mbedtls_svc_key_id_t *key)
+{
+    return psa_generate_key_ext(attributes,
+                                &default_method, sizeof(default_method),
+                                key);
+}
+
 /****************************************************************/
 /* Module setup */
 /****************************************************************/