Crypto: Align to Mbed Crypto 3.0.1

This patch upgrades the Crypto service to be able
to use Mbed Crypto 3.0.1:

- Updates the PSA crypto headers to latest available in mbed-crypto
- Updates the service implementation
- Updates the test suites where needed
- Updates the SST and Attestation interfaces
  towards cryptographic functionalities
- Updates documentation to reflect updated
  requirements, and changes in the integration guide

This patch migrates the use of psa_asymmetric_sign() and
psa_asymmetric_verify() to the non-deprecated versions of
the API psa_sign_hash() and psa_verify_hash().

Signed-off-by: Antonio de Angelis <antonio.deangelis@arm.com>
Change-Id: I7d8275def2336c1b5cfb8847b2842c305cfab116
diff --git a/secure_fw/services/crypto/crypto_key.c b/secure_fw/services/crypto/crypto_key.c
index 00cf946..f3fd277 100644
--- a/secure_fw/services/crypto/crypto_key.c
+++ b/secure_fw/services/crypto/crypto_key.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018-2019, Arm Limited. All rights reserved.
+ * Copyright (c) 2018-2020, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  *
@@ -33,73 +33,6 @@
                                  handle_owner[TFM_CRYPTO_MAX_KEY_HANDLES] = {0};
 #endif
 
-/**
- * \brief Open a handle to the hardware unique key (HUK).
- *
- * \note As persistent keys are not yet supported by TF-M Crypto, this function
- *       allocates an empty volatile key to get a valid key handle.
- *
- * \param[in]  lifetime  The lifetime of the key
- * \param[out] handle    On success, a handle to the HUK
- *
- * \return Return values as described in \ref psa_status_t
- */
-#ifndef TFM_CRYPTO_KEY_MODULE_DISABLED
-static psa_status_t tfm_crypto_open_huk(psa_key_lifetime_t lifetime,
-                                        psa_key_handle_t *key_handle)
-{
-    psa_status_t status;
-    int32_t partition_id;
-    uint32_t i;
-    psa_key_policy_t huk_policy = PSA_KEY_POLICY_INIT;
-
-    /* The HUK has a persistent lifetime */
-    if (lifetime != PSA_KEY_LIFETIME_PERSISTENT) {
-        return PSA_ERROR_INVALID_ARGUMENT;
-    }
-
-    for (i = 0; i < TFM_CRYPTO_MAX_KEY_HANDLES; i++) {
-        if (handle_owner[i].in_use == TFM_CRYPTO_NOT_IN_USE) {
-            break;
-        }
-    }
-
-    if (i == TFM_CRYPTO_MAX_KEY_HANDLES) {
-        return PSA_ERROR_INSUFFICIENT_MEMORY;
-    }
-
-    status = tfm_crypto_get_caller_id(&partition_id);
-    if (status != PSA_SUCCESS) {
-        return status;
-    }
-
-    /* Allocate a transient key to get a valid key handle */
-    status = psa_allocate_key(key_handle);
-    if (status != PSA_SUCCESS) {
-        return status;
-    }
-
-    /* The HUK can only be used to derive other keys */
-    huk_policy.usage = PSA_KEY_USAGE_DERIVE;
-    huk_policy.alg = TFM_CRYPTO_ALG_HUK_DERIVATION;
-    status = psa_set_key_policy(*key_handle, &huk_policy);
-    if (status != PSA_SUCCESS) {
-        return status;
-    }
-
-    /* Import zero data to the HUK handle to prevent further modification */
-    status = psa_import_key(*key_handle, PSA_KEY_TYPE_RAW_DATA, NULL, 0);
-
-    if (status == PSA_SUCCESS) {
-        handle_owner[i].owner = partition_id;
-        handle_owner[i].handle = *key_handle;
-        handle_owner[i].in_use = TFM_CRYPTO_IN_USE;
-    }
-
-    return status;
-}
-#endif /* TFM_CRYPTO_KEY_MODULE_DISABLED */
-
 /*!
  * \defgroup public Public functions
  *
@@ -138,28 +71,58 @@
 #endif /* TFM_CRYPTO_KEY_MODULE_DISABLED */
 }
 
-psa_status_t tfm_crypto_allocate_key(psa_invec in_vec[],
-                                     size_t in_len,
-                                     psa_outvec out_vec[],
-                                     size_t out_len)
+psa_status_t tfm_crypto_set_key_domain_parameters(psa_invec in_vec[],
+                                   size_t in_len,
+                                   psa_outvec out_vec[],
+                                   size_t out_len)
 {
 #ifdef TFM_CRYPTO_KEY_MODULE_DISABLED
     return PSA_ERROR_NOT_SUPPORTED;
 #else
-    if ((in_len != 1) || (out_len != 1)) {
+    /* FixMe: To be implemented */
+    return PSA_ERROR_NOT_SUPPORTED;
+#endif /* TFM_CRYPTO_KEY_MODULE_DISABLED */
+}
+
+psa_status_t tfm_crypto_get_key_domain_parameters(psa_invec in_vec[],
+                                   size_t in_len,
+                                   psa_outvec out_vec[],
+                                   size_t out_len)
+{
+#ifdef TFM_CRYPTO_KEY_MODULE_DISABLED
+    return PSA_ERROR_NOT_SUPPORTED;
+#else
+    /* FixMe: To be implemented */
+    return PSA_ERROR_NOT_SUPPORTED;
+#endif /* TFM_CRYPTO_KEY_MODULE_DISABLED */
+}
+
+psa_status_t tfm_crypto_import_key(psa_invec in_vec[],
+                                   size_t in_len,
+                                   psa_outvec out_vec[],
+                                   size_t out_len)
+{
+#ifdef TFM_CRYPTO_KEY_MODULE_DISABLED
+    return PSA_ERROR_NOT_SUPPORTED;
+#else
+
+    if ((in_len != 3) || (out_len != 1)) {
         return PSA_ERROR_CONNECTION_REFUSED;
     }
 
     if ((in_vec[0].len != sizeof(struct tfm_crypto_pack_iovec)) ||
+        (in_vec[1].len != sizeof(psa_key_attributes_t)) ||
         (out_vec[0].len != sizeof(psa_key_handle_t))) {
         return PSA_ERROR_CONNECTION_REFUSED;
     }
-
+    const psa_key_attributes_t *key_attributes = in_vec[1].base;
+    const uint8_t *data = in_vec[2].base;
+    size_t data_length = in_vec[2].len;
     psa_key_handle_t *key_handle = out_vec[0].base;
+    psa_status_t status;
     uint32_t i = 0;
     int32_t partition_id = 0;
     bool empty_found = false;
-    psa_status_t status;
 
     for (i = 0; i < TFM_CRYPTO_MAX_KEY_HANDLES; i++) {
         if (handle_owner[i].in_use == TFM_CRYPTO_NOT_IN_USE) {
@@ -177,7 +140,7 @@
         return status;
     }
 
-    status = psa_allocate_key(key_handle);
+    status =  psa_import_key(key_attributes, data, data_length, key_handle);
 
     if (status == PSA_SUCCESS) {
         handle_owner[i].owner = partition_id;
@@ -207,19 +170,7 @@
         return PSA_ERROR_CONNECTION_REFUSED;
     }
 
-    const struct tfm_crypto_pack_iovec *iov = in_vec[0].base;
-    psa_key_lifetime_t lifetime = iov->lifetime;
-    psa_key_id_t id = *((psa_key_id_t *)in_vec[1].base);
-    psa_key_handle_t *key_handle = out_vec[0].base;
-
-    /* FIXME: Persistent key APIs are not supported in general, so use a
-     * specific implementation to open a handle to the HUK.
-     */
-    if (id == TFM_CRYPTO_KEY_ID_HUK) {
-        return tfm_crypto_open_huk(lifetime, key_handle);
-    } else {
-        return PSA_ERROR_NOT_SUPPORTED;
-    }
+    return PSA_ERROR_NOT_SUPPORTED;
 #endif /* TFM_CRYPTO_KEY_MODULE_DISABLED */
 }
 
@@ -262,39 +213,6 @@
 #endif /* TFM_CRYPTO_KEY_MODULE_DISABLED */
 }
 
-psa_status_t tfm_crypto_import_key(psa_invec in_vec[],
-                                   size_t in_len,
-                                   psa_outvec out_vec[],
-                                   size_t out_len)
-{
-#ifdef TFM_CRYPTO_KEY_MODULE_DISABLED
-    return PSA_ERROR_NOT_SUPPORTED;
-#else
-    (void)out_vec;
-
-    if ((in_len != 2) || (out_len != 0)) {
-        return PSA_ERROR_CONNECTION_REFUSED;
-    }
-
-    if (in_vec[0].len != sizeof(struct tfm_crypto_pack_iovec)) {
-        return PSA_ERROR_CONNECTION_REFUSED;
-    }
-    const struct tfm_crypto_pack_iovec *iov = in_vec[0].base;
-
-    psa_key_handle_t key = iov->key_handle;
-    psa_key_type_t type = iov->type;
-    const uint8_t *data = in_vec[1].base;
-    size_t data_length = in_vec[1].len;
-    psa_status_t status = tfm_crypto_check_handle_owner(key, NULL);
-
-    if (status != PSA_SUCCESS) {
-        return status;
-    }
-
-    return psa_import_key(key, type, data, data_length);
-#endif /* TFM_CRYPTO_KEY_MODULE_DISABLED */
-}
-
 psa_status_t tfm_crypto_destroy_key(psa_invec in_vec[],
                                     size_t in_len,
                                     psa_outvec out_vec[],
@@ -334,30 +252,54 @@
 #endif /* TFM_CRYPTO_KEY_MODULE_DISABLED */
 }
 
-psa_status_t tfm_crypto_get_key_information(psa_invec in_vec[],
-                                            size_t in_len,
-                                            psa_outvec out_vec[],
-                                            size_t out_len)
+psa_status_t tfm_crypto_get_key_attributes(psa_invec in_vec[],
+                                           size_t in_len,
+                                           psa_outvec out_vec[],
+                                           size_t out_len)
 {
 #ifdef TFM_CRYPTO_KEY_MODULE_DISABLED
     return PSA_ERROR_NOT_SUPPORTED;
 #else
-    if ((in_len != 1) || (out_len != 2)) {
+    if ((in_len != 1) || (out_len != 1)) {
         return PSA_ERROR_CONNECTION_REFUSED;
     }
 
     if ((in_vec[0].len != sizeof(struct tfm_crypto_pack_iovec)) ||
-        (out_vec[0].len != sizeof(psa_key_type_t)) ||
-        (out_vec[1].len != sizeof(size_t))) {
+        (out_vec[0].len != sizeof(psa_key_attributes_t))) {
         return PSA_ERROR_CONNECTION_REFUSED;
     }
     const struct tfm_crypto_pack_iovec *iov = in_vec[0].base;
 
     psa_key_handle_t key = iov->key_handle;
-    psa_key_type_t *type = out_vec[0].base;
-    size_t *bits = out_vec[1].base;
+    psa_key_attributes_t *key_attributes = out_vec[0].base;
 
-    return psa_get_key_information(key, type, bits);
+    return psa_get_key_attributes(key, key_attributes);
+#endif /* TFM_CRYPTO_KEY_MODULE_DISABLED */
+}
+
+psa_status_t tfm_crypto_reset_key_attributes(psa_invec in_vec[],
+                                             size_t in_len,
+                                             psa_outvec out_vec[],
+                                             size_t out_len)
+{
+#if (TFM_CRYPTO_KEY_MODULE_DISABLED != 0)
+    return PSA_ERROR_NOT_SUPPORTED;
+#else
+    if ((in_len != 1) || (out_len != 1)) {
+        return PSA_ERROR_CONNECTION_REFUSED;
+    }
+
+    if ((in_vec[0].len != sizeof(struct tfm_crypto_pack_iovec)) ||
+        (out_vec[0].len != sizeof(psa_key_attributes_t))) {
+        return PSA_ERROR_CONNECTION_REFUSED;
+    }
+
+    psa_key_attributes_t *key_attributes = out_vec[0].base;
+
+    psa_reset_key_attributes(key_attributes);
+
+    /* psa_reset_key_attributes() doesn't report any error */
+    return PSA_SUCCESS;
 #endif /* TFM_CRYPTO_KEY_MODULE_DISABLED */
 }
 
@@ -419,106 +361,104 @@
 #ifdef TFM_CRYPTO_KEY_MODULE_DISABLED
     return PSA_ERROR_NOT_SUPPORTED;
 #else
-    (void)out_vec;
 
-    if ((in_len != 3) || (out_len != 0)) {
+    if ((in_len != 2) || (out_len != 1)) {
         return PSA_ERROR_CONNECTION_REFUSED;
     }
 
     if ((in_vec[0].len != sizeof(struct tfm_crypto_pack_iovec)) ||
-        (in_vec[1].len != sizeof(psa_key_handle_t)) ||
-        (in_vec[2].len != sizeof(psa_key_policy_t))) {
+        (out_vec[0].len != sizeof(psa_key_handle_t)) ||
+        (in_vec[1].len != sizeof(psa_key_attributes_t))) {
         return PSA_ERROR_CONNECTION_REFUSED;
     }
     const struct tfm_crypto_pack_iovec *iov = in_vec[0].base;
 
     psa_key_handle_t source_handle = iov->key_handle;
-    psa_key_handle_t target_handle = *((psa_key_handle_t *)in_vec[1].base);
-    const psa_key_policy_t *policy = in_vec[2].base;
+    psa_key_handle_t *target_handle = out_vec[0].base;
+    const psa_key_attributes_t *key_attributes = in_vec[1].base;
+    psa_status_t status;
+    uint32_t i = 0;
+    int32_t partition_id = 0;
+    bool empty_found = false;
 
-    return psa_copy_key(source_handle, target_handle, policy);
-#endif /* TFM_CRYPTO_KEY_MODULE_DISABLED */
-}
-
-psa_status_t tfm_crypto_set_key_policy(psa_invec in_vec[],
-                                       size_t in_len,
-                                       psa_outvec out_vec[],
-                                       size_t out_len)
-{
-#ifdef TFM_CRYPTO_KEY_MODULE_DISABLED
-    return PSA_ERROR_NOT_SUPPORTED;
-#else
-    (void)out_vec;
-
-    if ((in_len != 2) || (out_len != 0)) {
-        return PSA_ERROR_CONNECTION_REFUSED;
+    for (i = 0; i < TFM_CRYPTO_MAX_KEY_HANDLES; i++) {
+        if (handle_owner[i].in_use == TFM_CRYPTO_NOT_IN_USE) {
+            empty_found = true;
+            break;
+        }
     }
 
-    if ((in_vec[0].len != sizeof(struct tfm_crypto_pack_iovec)) ||
-        (in_vec[1].len != sizeof(psa_key_policy_t))) {
-        return PSA_ERROR_CONNECTION_REFUSED;
+    if (!empty_found) {
+        return PSA_ERROR_INSUFFICIENT_MEMORY;
     }
-    const struct tfm_crypto_pack_iovec *iov = in_vec[0].base;
 
-    psa_key_handle_t key = iov->key_handle;
-    const psa_key_policy_t *policy = in_vec[1].base;
-    psa_status_t status = tfm_crypto_check_handle_owner(key, NULL);
-
-    if (status == PSA_SUCCESS) {
-        return psa_set_key_policy(key, policy);
-    } else {
+    status = tfm_crypto_get_caller_id(&partition_id);
+    if (status != PSA_SUCCESS) {
         return status;
     }
+
+    status = psa_copy_key(source_handle, key_attributes, target_handle);
+
+    if (status == PSA_SUCCESS) {
+        handle_owner[i].owner = partition_id;
+        handle_owner[i].handle = *target_handle;
+        handle_owner[i].in_use = TFM_CRYPTO_IN_USE;
+    }
+
+    return status;
 #endif /* TFM_CRYPTO_KEY_MODULE_DISABLED */
+    return PSA_ERROR_NOT_SUPPORTED;
 }
 
-psa_status_t tfm_crypto_get_key_policy(psa_invec in_vec[],
-                                       size_t in_len,
-                                       psa_outvec out_vec[],
-                                       size_t out_len)
+psa_status_t tfm_crypto_generate_key(psa_invec in_vec[],
+                                     size_t in_len,
+                                     psa_outvec out_vec[],
+                                     size_t out_len)
 {
 #ifdef TFM_CRYPTO_KEY_MODULE_DISABLED
     return PSA_ERROR_NOT_SUPPORTED;
 #else
-    if ((in_len != 1) || (out_len != 1)) {
+    if ((in_len != 2) || (out_len != 1)) {
         return PSA_ERROR_CONNECTION_REFUSED;
     }
 
     if ((in_vec[0].len != sizeof(struct tfm_crypto_pack_iovec)) ||
-        (out_vec[0].len != sizeof(psa_key_policy_t))) {
+        (in_vec[1].len != sizeof(psa_key_attributes_t)) ||
+        (out_vec[0].len != sizeof(psa_key_handle_t))) {
         return PSA_ERROR_CONNECTION_REFUSED;
     }
-    const struct tfm_crypto_pack_iovec *iov = in_vec[0].base;
+    psa_key_handle_t *key_handle = out_vec[0].base;
+    const psa_key_attributes_t *key_attributes = in_vec[1].base;
+    psa_status_t status;
+    uint32_t i = 0;
+    int32_t partition_id = 0;
+    bool empty_found = false;
 
-    psa_key_handle_t key = iov->key_handle;
-    psa_key_policy_t *policy = out_vec[0].base;
-
-    return psa_get_key_policy(key, policy);
-#endif /* TFM_CRYPTO_KEY_MODULE_DISABLED */
-}
-
-psa_status_t tfm_crypto_get_key_lifetime(psa_invec in_vec[],
-                                         size_t in_len,
-                                         psa_outvec out_vec[],
-                                         size_t out_len)
-{
-#ifdef TFM_CRYPTO_KEY_MODULE_DISABLED
-    return PSA_ERROR_NOT_SUPPORTED;
-#else
-    if ((in_len != 1) || (out_len != 1)) {
-        return PSA_ERROR_CONNECTION_REFUSED;
+    for (i = 0; i < TFM_CRYPTO_MAX_KEY_HANDLES; i++) {
+        if (handle_owner[i].in_use == TFM_CRYPTO_NOT_IN_USE) {
+            empty_found = true;
+            break;
+        }
     }
 
-    if ((in_vec[0].len != sizeof(struct tfm_crypto_pack_iovec)) ||
-        (out_vec[0].len != sizeof(psa_key_lifetime_t))) {
-        return PSA_ERROR_CONNECTION_REFUSED;
+    if (!empty_found) {
+        return PSA_ERROR_INSUFFICIENT_MEMORY;
     }
-    const struct tfm_crypto_pack_iovec *iov = in_vec[0].base;
 
-    psa_key_handle_t key = iov->key_handle;
-    psa_key_lifetime_t *lifetime = out_vec[0].base;
+    status = tfm_crypto_get_caller_id(&partition_id);
+    if (status != PSA_SUCCESS) {
+        return status;
+    }
 
-    return psa_get_key_lifetime(key, lifetime);
+    status = psa_generate_key(key_attributes, key_handle);
+
+    if (status == PSA_SUCCESS) {
+        handle_owner[i].owner = partition_id;
+        handle_owner[i].handle = *key_handle;
+        handle_owner[i].in_use = TFM_CRYPTO_IN_USE;
+    }
+
+    return status;
 #endif /* TFM_CRYPTO_KEY_MODULE_DISABLED */
 }
 /*!@}*/