Crypto: Use uniform signatures

This patch amends the Crypto service to use the
Uniform Signatures interfaces supported by TF-M.

Change-Id: Ia1e269075bf94e1d60281da789dd43bb2be3f265
Signed-off-by: Antonio de Angelis <antonio.deangelis@arm.com>
diff --git a/secure_fw/services/crypto/crypto_aead.c b/secure_fw/services/crypto/crypto_aead.c
index 1698fd0..7978d7f 100644
--- a/secure_fw/services/crypto/crypto_aead.c
+++ b/secure_fw/services/crypto/crypto_aead.c
@@ -14,7 +14,6 @@
 #include "psa_crypto.h"
 
 #include "tfm_crypto_api.h"
-#include "crypto_utils.h"
 
 /**
  * \def CRYPTO_AEAD_MAX_KEY_LENGTH
@@ -26,108 +25,102 @@
 #define CRYPTO_AEAD_MAX_KEY_LENGTH (32)
 #endif
 
+static psa_status_t _psa_get_key_information(psa_key_slot_t key,
+                                             psa_key_type_t *type,
+                                             size_t *bits)
+{
+    psa_invec in_vec[] = {
+        {.base = &key, .len = sizeof(psa_key_slot_t)},
+    };
+    psa_outvec out_vec[] = {
+        {.base = type, .len = sizeof(psa_key_type_t)},
+        {.base = bits, .len = sizeof(size_t)}
+    };
+
+    return tfm_crypto_get_key_information(
+                 in_vec, sizeof(in_vec)/sizeof(in_vec[0]),
+                 out_vec, sizeof(out_vec)/sizeof(out_vec[0]));
+}
+
 /*!
  * \defgroup public_psa Public functions, PSA
  *
  */
 
 /*!@{*/
-enum tfm_crypto_err_t tfm_crypto_aead_encrypt(psa_key_slot_t key,
-                                              psa_algorithm_t alg,
-                                              const uint8_t *nonce,
-                                              size_t nonce_length,
-                                              const uint8_t *additional_data,
-                                              size_t additional_data_length,
-                                              const uint8_t *plaintext,
-                                              size_t plaintext_length,
-                                              uint8_t *ciphertext,
-                                              size_t ciphertext_size,
-                                              size_t *ciphertext_length)
+psa_status_t tfm_crypto_aead_encrypt(psa_invec in_vec[],
+                                     size_t in_len,
+                                     psa_outvec out_vec[],
+                                     size_t out_len)
 {
     psa_status_t status = PSA_SUCCESS;
-    enum tfm_crypto_err_t err;
     uint8_t key_data[CRYPTO_AEAD_MAX_KEY_LENGTH];
     uint32_t key_size;
     psa_key_type_t key_type;
 
+    if ((in_len != 3) || (out_len != 1)) {
+        return PSA_CONNECTION_REFUSED;
+    }
+
+    if ((in_vec[0].len < (sizeof(psa_key_slot_t) + sizeof(psa_algorithm_t))) ||
+        (in_vec[0].len > (TFM_CRYPTO_MAX_NONCE_LENGTH
+                       + (sizeof(psa_key_slot_t) + sizeof(psa_algorithm_t))))) {
+        return PSA_CONNECTION_REFUSED;
+    }
+
+    const struct tfm_crypto_aead_pack_input *input_s = in_vec[0].base;
+    psa_key_slot_t key = input_s->key;
+    psa_algorithm_t alg = input_s->alg;
+    const uint8_t *nonce = input_s->nonce;
+    size_t nonce_length = in_vec[0].len - sizeof(psa_key_slot_t)
+                                        - sizeof(psa_algorithm_t);
+    const uint8_t *additional_data = in_vec[1].base;
+    size_t additional_data_length = in_vec[1].len;
+    const uint8_t *plaintext = in_vec[2].base;
+    size_t plaintext_length = in_vec[2].len;
+    uint8_t *ciphertext = out_vec[0].base;
+    size_t ciphertext_size = out_vec[0].len;
+
     /* Initialise ciphertext_length to zero */
-    *ciphertext_length = 0;
+    out_vec[0].len = 0;
 
     if (PSA_ALG_IS_AEAD(alg) == 0) {
-        return TFM_CRYPTO_ERR_PSA_ERROR_NOT_SUPPORTED;
+        return PSA_ERROR_NOT_SUPPORTED;
     }
 
     if (PSA_AEAD_TAG_SIZE(alg) == 0) {
-        return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
+        return PSA_ERROR_INVALID_ARGUMENT;
     }
 
     if (PSA_AEAD_ENCRYPT_OUTPUT_SIZE(alg, plaintext_length) > ciphertext_size) {
-        return TFM_CRYPTO_ERR_PSA_ERROR_BUFFER_TOO_SMALL;
+        return PSA_ERROR_BUFFER_TOO_SMALL;
     }
 
     if ((nonce_length == 0) ||
         ((additional_data_length == 0) && (additional_data != NULL))) {
-        return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
-    }
-
-    /* Validate pointers */
-    err = tfm_crypto_memory_check((void *)nonce,
-                                  nonce_length,
-                                  TFM_MEMORY_ACCESS_RO);
-    if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
-        return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
-    }
-
-    if ((additional_data != NULL) || (additional_data_length != 0)) {
-        err = tfm_crypto_memory_check((void *)additional_data,
-                                      additional_data_length,
-                                      TFM_MEMORY_ACCESS_RO);
-        if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
-            return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
-        }
-    }
-
-    err = tfm_crypto_memory_check((void *)plaintext,
-                                  plaintext_length,
-                                  TFM_MEMORY_ACCESS_RO);
-    if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
-        return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
-    }
-
-    err = tfm_crypto_memory_check((void *)ciphertext,
-                                  ciphertext_size,
-                                  TFM_MEMORY_ACCESS_RW);
-    if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
-        return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
-    }
-
-    err = tfm_crypto_memory_check((void *)ciphertext_length,
-                                  sizeof(size_t),
-                                  TFM_MEMORY_ACCESS_RW);
-    if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
-        return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
+        return PSA_ERROR_INVALID_ARGUMENT;
     }
 
     /* Access the key data */
-    err = tfm_crypto_get_key_information(key, &key_type, (size_t *)&key_size);
-    if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
-        return err;
+    status = _psa_get_key_information(key, &key_type, (size_t *)&key_size);
+    if (status != PSA_SUCCESS) {
+        return status;
     }
 
     /* Support only AES based AEAD */
     if (key_type != PSA_KEY_TYPE_AES) {
-        return TFM_CRYPTO_ERR_PSA_ERROR_NOT_SUPPORTED;
+        return PSA_ERROR_NOT_SUPPORTED;
     }
 
     /* Access the crypto service key module to retrieve key data */
-    err = tfm_crypto_get_key(key,
-                             PSA_KEY_USAGE_ENCRYPT,
-                             alg,
-                             key_data,
-                             CRYPTO_AEAD_MAX_KEY_LENGTH,
-                             (size_t *)&key_size);
-    if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
-        return err;
+    status = tfm_crypto_get_key(key,
+                                PSA_KEY_USAGE_ENCRYPT,
+                                alg,
+                                key_data,
+                                CRYPTO_AEAD_MAX_KEY_LENGTH,
+                                (size_t *)&key_size);
+    if (status != PSA_SUCCESS) {
+        return status;
     }
 
     /* Request AEAD encryption on the crypto engine */
@@ -143,115 +136,88 @@
                                             plaintext_length,
                                             ciphertext,
                                             ciphertext_size,
-                                            (uint32_t *)ciphertext_length);
+                                            (uint32_t *)&(out_vec[0].len));
     if (status == PSA_SUCCESS) {
         /* The ciphertext_length needs to take into account the tag length */
-        *ciphertext_length += PSA_AEAD_TAG_SIZE(alg);
+        out_vec[0].len += PSA_AEAD_TAG_SIZE(alg);
     } else {
         /* In case of failure set the ciphertext_length to zero */
-        *ciphertext_length = 0;
+        out_vec[0].len = 0;
     }
 
-    return PSA_STATUS_TO_TFM_CRYPTO_ERR(status);
+    return status;
 }
 
-enum tfm_crypto_err_t tfm_crypto_aead_decrypt(psa_key_slot_t key,
-                                              psa_algorithm_t alg,
-                                              const uint8_t *nonce,
-                                              size_t nonce_length,
-                                              const uint8_t *additional_data,
-                                              size_t additional_data_length,
-                                              const uint8_t *ciphertext,
-                                              size_t ciphertext_length,
-                                              uint8_t *plaintext,
-                                              size_t plaintext_size,
-                                              size_t *plaintext_length)
+psa_status_t tfm_crypto_aead_decrypt(psa_invec in_vec[],
+                                     size_t in_len,
+                                     psa_outvec out_vec[],
+                                     size_t out_len)
 {
     psa_status_t status = PSA_SUCCESS;
-    enum tfm_crypto_err_t err;
     uint8_t key_data[CRYPTO_AEAD_MAX_KEY_LENGTH];
     uint32_t key_size;
     psa_key_type_t key_type;
 
+    if ((in_vec[0].len < (sizeof(psa_key_slot_t) + sizeof(psa_algorithm_t))) ||
+        (in_vec[0].len > (TFM_CRYPTO_MAX_NONCE_LENGTH
+                       + (sizeof(psa_key_slot_t) + sizeof(psa_algorithm_t))))) {
+        return PSA_CONNECTION_REFUSED;
+    }
+
+    const struct tfm_crypto_aead_pack_input *input_s = in_vec[0].base;
+    psa_key_slot_t key = input_s->key;
+    psa_algorithm_t alg = input_s->alg;
+    const uint8_t *nonce = input_s->nonce;
+    size_t nonce_length = in_vec[0].len - sizeof(psa_key_slot_t)
+                                        - sizeof(psa_algorithm_t);
+    const uint8_t *additional_data = in_vec[1].base;
+    size_t additional_data_length = in_vec[1].len;
+    const uint8_t *ciphertext = in_vec[2].base;
+    size_t ciphertext_length = in_vec[2].len;
+    uint8_t *plaintext = out_vec[0].base;
+    size_t plaintext_size = out_vec[0].len;
+
     /* Initialise plaintext_length to zero */
-    *plaintext_length = 0;
+    out_vec[0].len = 0;
 
     if (PSA_ALG_IS_AEAD(alg) == 0) {
-        return TFM_CRYPTO_ERR_PSA_ERROR_NOT_SUPPORTED;
+        return PSA_ERROR_NOT_SUPPORTED;
     }
 
     if ((PSA_AEAD_TAG_SIZE(alg) == 0) ||
         (ciphertext_length < PSA_AEAD_TAG_SIZE(alg))) {
-        return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
+        return PSA_ERROR_INVALID_ARGUMENT;
     }
 
     if (PSA_AEAD_DECRYPT_OUTPUT_SIZE(alg,ciphertext_length) > plaintext_size) {
-        return TFM_CRYPTO_ERR_PSA_ERROR_BUFFER_TOO_SMALL;
+        return PSA_ERROR_BUFFER_TOO_SMALL;
     }
 
     if ((nonce_length == 0) ||
         ((additional_data_length == 0) && (additional_data != NULL))) {
-        return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
-    }
-
-    /* Validate pointers */
-    err = tfm_crypto_memory_check((void *)nonce,
-                                  nonce_length,
-                                  TFM_MEMORY_ACCESS_RO);
-    if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
-        return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
-    }
-
-    if ((additional_data != NULL) || (additional_data_length != 0)) {
-        err = tfm_crypto_memory_check((void *)additional_data,
-                                      additional_data_length,
-                                      TFM_MEMORY_ACCESS_RO);
-        if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
-            return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
-        }
-    }
-
-    err = tfm_crypto_memory_check((void *)ciphertext,
-                                  ciphertext_length,
-                                  TFM_MEMORY_ACCESS_RO);
-    if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
-        return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
-    }
-
-    err = tfm_crypto_memory_check((void *)plaintext,
-                                  plaintext_size,
-                                  TFM_MEMORY_ACCESS_RW);
-    if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
-        return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
-    }
-
-    err = tfm_crypto_memory_check((void *)plaintext_length,
-                                  sizeof(size_t),
-                                  TFM_MEMORY_ACCESS_RW);
-    if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
-        return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
+        return PSA_ERROR_INVALID_ARGUMENT;
     }
 
     /* Access the key data */
-    err = tfm_crypto_get_key_information(key, &key_type, (size_t *)&key_size);
-    if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
-        return err;
+    status = _psa_get_key_information(key, &key_type, (size_t *)&key_size);
+    if (status != PSA_SUCCESS) {
+        return status;
     }
 
     /* Support only AES based AEAD */
     if (key_type != PSA_KEY_TYPE_AES) {
-        return TFM_CRYPTO_ERR_PSA_ERROR_NOT_SUPPORTED;
+        return PSA_ERROR_NOT_SUPPORTED;
     }
 
     /* Access the crypto service key module to retrieve key data */
-    err = tfm_crypto_get_key(key,
-                             PSA_KEY_USAGE_DECRYPT,
-                             alg,
-                             key_data,
-                             CRYPTO_AEAD_MAX_KEY_LENGTH,
-                             (size_t *)&key_size);
-    if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
-        return err;
+    status = tfm_crypto_get_key(key,
+                                PSA_KEY_USAGE_DECRYPT,
+                                alg,
+                                key_data,
+                                CRYPTO_AEAD_MAX_KEY_LENGTH,
+                                (size_t *)&key_size);
+    if (status != PSA_SUCCESS) {
+        return status;
     }
 
     /* Request AEAD decryption on the crypto engine */
@@ -267,11 +233,11 @@
                                             ciphertext_length,
                                             plaintext,
                                             plaintext_size,
-                                            (uint32_t *)plaintext_length);
+                                            (uint32_t *)&(out_vec[0].len));
     if (status != PSA_SUCCESS) {
-        *plaintext_length = 0;
+        out_vec[0].len = 0;
     }
 
-    return PSA_STATUS_TO_TFM_CRYPTO_ERR(status);
+    return status;
 }
 /*!@}*/