Crypto: Add Crypto service

This change introduces the implementation of the Crypto
service based on the interface psa_crypto.h
This patch introduces changes for:

-- Secure Service, including manifest
-- Platform
-- Non-Secure interface

Change-Id: I3b68266ca80f4cd2bda2a1cd2b28b51c654b4c59
Signed-off-by: Antonio de Angelis <antonio.deangelis@arm.com>
diff --git a/interface/include/crypto_psa_wrappers.h b/interface/include/crypto_psa_wrappers.h
new file mode 100644
index 0000000..c337962
--- /dev/null
+++ b/interface/include/crypto_psa_wrappers.h
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2018, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef __CRYPTO_PSA_WRAPPERS_H__
+#define __CRYPTO_PSA_WRAPPERS_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*!
+ * \struct psa_cipher_update_input
+ *
+ * \brief Input structure for the tfm_crypto_cipher_update_wrapper function
+ *
+ */
+struct psa_cipher_update_input {
+    const uint8_t *input; /*!< Input data to the cipher */
+    size_t input_length;  /*!< Size of the input data */
+};
+
+/*!
+ * \struct psa_cipher_update_output
+ *
+ * \brief Output structure for the tfm_crypto_cipher_update_wrapper function
+ *
+ */
+struct psa_cipher_update_output {
+    unsigned char *output; /*!< Buffer to hold the output data from the cipher*/
+    size_t output_size;    /*!< Size of the output buffer */
+    size_t *output_length; /*!< Size of the output data from the cipher */
+};
+
+/*!
+ * \brief This function is a TF-M compatible wrapper for the
+ *        \ref tfm_crypto_cipher_update implemented in the Crypto service
+ *
+ * \param[in]  input_s  Pointer to the structure containing input parameters
+ *                      associated with \ref psa_cipher_update_input
+ * \param[out] output_s Pointer to the structure containing output parameters
+ *                      associated with \ref psa_cipher_update_output
+ *
+ */
+enum tfm_crypto_err_t tfm_crypto_cipher_update_wrapper(
+                                              psa_cipher_operation_t *operation,
+                                        struct psa_cipher_update_input *input_s,
+                                     struct psa_cipher_update_output *output_s);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __CRYPTO_PSA_WRAPPERS_H__ */
diff --git a/interface/include/psa_crypto.h b/interface/include/psa_crypto.h
index e17ce27..f122841 100644
--- a/interface/include/psa_crypto.h
+++ b/interface/include/psa_crypto.h
@@ -13,13 +13,19 @@
 #ifndef PSA_CRYPTO_H
 #define PSA_CRYPTO_H
 
+/* The psa_crypto_platform.h header provides fundamental definitions used by
+ * this header, which are specific to the platform being used.
+ */
+#include "psa_crypto_platform.h"
+
 #include <stddef.h>
 
 #ifdef __DOXYGEN_ONLY__
 /* This __DOXYGEN_ONLY__ block contains mock definitions for things that
  * must be defined in the psa_crypto_platform.h header. These mock definitions
  * are present in this file as a convenience to generate pretty-printed
- * documentation that includes those definitions. */
+ * documentation that includes those definitions.
+ */
 
 /** \defgroup platform Implementation-specific definitions
  * @{
@@ -84,7 +90,8 @@
  * Implementations should return this error code when an enumeration
  * parameter such as a key type, algorithm, etc. is not recognized.
  * If a combination of parameters is recognized and identified as
- * not valid, return #PSA_ERROR_INVALID_ARGUMENT instead. */
+ * not valid, return #PSA_ERROR_INVALID_ARGUMENT instead.
+ */
 #define PSA_ERROR_NOT_SUPPORTED         ((psa_status_t)1)
 
 /** The requested action is denied by a policy.
@@ -97,7 +104,8 @@
  * forbidden operation, and another subset of the parameters are
  * not valid or not supported, it is unspecified whether the function
  * returns #PSA_ERROR_NOT_PERMITTED, #PSA_ERROR_NOT_SUPPORTED or
- * #PSA_ERROR_INVALID_ARGUMENT. */
+ * #PSA_ERROR_INVALID_ARGUMENT.
+ */
 #define PSA_ERROR_NOT_PERMITTED         ((psa_status_t)2)
 
 /** An output buffer is too small.
@@ -109,7 +117,8 @@
  * in cases when performing the operation with a larger output
  * buffer would succeed. However implementations may return this
  * error if a function has invalid or unsupported parameters in addition
- * to the parameters that determine the necessary output buffer size. */
+ * to the parameters that determine the necessary output buffer size.
+ */
 #define PSA_ERROR_BUFFER_TOO_SMALL      ((psa_status_t)3)
 
 /** A slot is occupied, but must be empty to carry out the
@@ -117,7 +126,8 @@
  *
  * If the slot number is invalid (i.e. the requested action could
  * not be performed even after erasing the slot's content),
- * implementations shall return #PSA_ERROR_INVALID_ARGUMENT instead. */
+ * implementations shall return #PSA_ERROR_INVALID_ARGUMENT instead.
+ */
 #define PSA_ERROR_OCCUPIED_SLOT         ((psa_status_t)4)
 
 /** A slot is empty, but must be occupied to carry out the
@@ -125,7 +135,8 @@
  *
  * If the slot number is invalid (i.e. the requested action could
  * not be performed even after creating appropriate content in the slot),
- * implementations shall return #PSA_ERROR_INVALID_ARGUMENT instead. */
+ * implementations shall return #PSA_ERROR_INVALID_ARGUMENT instead.
+ */
 #define PSA_ERROR_EMPTY_SLOT            ((psa_status_t)5)
 
 /** The requested action cannot be performed in the current state.
@@ -137,7 +148,8 @@
  * Implementations shall not return this error code to indicate
  * that a key slot is occupied when it needs to be free or vice versa,
  * but shall return #PSA_ERROR_OCCUPIED_SLOT or #PSA_ERROR_EMPTY_SLOT
- * as applicable. */
+ * as applicable.
+ */
 #define PSA_ERROR_BAD_STATE             ((psa_status_t)6)
 
 /** The parameters passed to the function are invalid.
@@ -148,13 +160,15 @@
  * Implementations shall not return this error code to indicate
  * that a key slot is occupied when it needs to be free or vice versa,
  * but shall return #PSA_ERROR_OCCUPIED_SLOT or #PSA_ERROR_EMPTY_SLOT
- * as applicable. */
+ * as applicable.
+ */
 #define PSA_ERROR_INVALID_ARGUMENT      ((psa_status_t)7)
 
 /** There is not enough runtime memory.
  *
  * If the action is carried out across multiple security realms, this
- * error can refer to available memory in any of the security realms. */
+ * error can refer to available memory in any of the security realms.
+ */
 #define PSA_ERROR_INSUFFICIENT_MEMORY   ((psa_status_t)8)
 
 /** There is not enough persistent storage.
@@ -163,7 +177,8 @@
  * there is insufficient storage space on the host media. In addition,
  * many functions that do not otherwise access storage may return this
  * error code if the implementation requires a mandatory log entry for
- * the requested action and the log storage space is full. */
+ * the requested action and the log storage space is full.
+ */
 #define PSA_ERROR_INSUFFICIENT_STORAGE  ((psa_status_t)9)
 
 /** There was a communication failure inside the implementation.
@@ -205,13 +220,15 @@
  * Implementations should only use this error code to report a
  * permanent storage corruption. However application writers should
  * keep in mind that transient errors while reading the storage may be
- * reported using this error code. */
+ * reported using this error code.
+ */
 #define PSA_ERROR_STORAGE_FAILURE       ((psa_status_t)11)
 
 /** A hardware failure was detected.
  *
  * A hardware failure may be transient or permanent depending on the
- * cause. */
+ * cause.
+ */
 #define PSA_ERROR_HARDWARE_FAILURE      ((psa_status_t)12)
 
 /** A tampering attempt was detected.
@@ -242,7 +259,8 @@
  *
  * This error indicates an attack against the application. Implementations
  * shall not return this error code as a consequence of the behavior of
- * the application itself. */
+ * the application itself.
+ */
 #define PSA_ERROR_TAMPERING_DETECTED    ((psa_status_t)13)
 
 /** There is not enough entropy to generate random data needed
@@ -261,7 +279,8 @@
  * entropy during initialization and subsequently use a cryptographically
  * secure pseudorandom generator (PRNG). However implementations may return
  * this error at any time if a policy requires the PRNG to be reseeded
- * during normal operation. */
+ * during normal operation.
+ */
 #define PSA_ERROR_INSUFFICIENT_ENTROPY  ((psa_status_t)14)
 
 /** The signature, MAC or hash is incorrect.
@@ -271,7 +290,8 @@
  * was determined to be incorrect.
  *
  * If the value to verify has an invalid size, implementations may return
- * either #PSA_ERROR_INVALID_ARGUMENT or #PSA_ERROR_INVALID_SIGNATURE. */
+ * either #PSA_ERROR_INVALID_ARGUMENT or #PSA_ERROR_INVALID_SIGNATURE.
+ */
 #define PSA_ERROR_INVALID_SIGNATURE     ((psa_status_t)15)
 
 /** The decrypted padding is incorrect.
@@ -287,14 +307,16 @@
  * Implementations should strive to make valid and invalid padding
  * as close as possible to indistinguishable to an external observer.
  * In particular, the timing of a decryption operation should not
- * depend on the validity of the padding. */
+ * depend on the validity of the padding.
+ */
 #define PSA_ERROR_INVALID_PADDING       ((psa_status_t)16)
 
 /** An error occurred that does not correspond to any defined
  * failure cause.
  *
  * Implementations may use this error code if none of the other standard
- * error codes are applicable. */
+ * error codes are applicable.
+ */
 #define PSA_ERROR_UNKNOWN_ERROR         ((psa_status_t)17)
 
 /**
@@ -324,8 +346,7 @@
  * @{
  */
 
-/** \brief Encoding of a key type.
- */
+/** \brief Encoding of a key type. */
 typedef uint32_t psa_key_type_t;
 
 /** An invalid key type value.
@@ -347,7 +368,8 @@
 /** Raw data.
  *
  * A "key" of this type cannot be used for any cryptographic operation.
- * Applications may use this type to store arbitrary data in the keystore. */
+ * Applications may use this type to store arbitrary data in the keystore.
+ */
 #define PSA_KEY_TYPE_RAW_DATA                   ((psa_key_type_t)0x02000000)
 #define PSA_KEY_TYPE_CATEGORY_SYMMETRIC         ((psa_key_type_t)0x04000000)
 #define PSA_KEY_TYPE_CATEGORY_ASYMMETRIC        ((psa_key_type_t)0x06000000)
@@ -360,7 +382,8 @@
  *
  * HMAC keys should generally have the same size as the underlying hash.
  * This size can be calculated with `PSA_HASH_SIZE(alg)` where
- * `alg` is the HMAC algorithm or the underlying hash algorithm. */
+ * `alg` is the HMAC algorithm or the underlying hash algorithm.
+ */
 #define PSA_KEY_TYPE_HMAC                       ((psa_key_type_t)0x02000001)
 /** Key for an cipher, AEAD or MAC algorithm based on the AES block cipher.
  *
@@ -379,12 +402,14 @@
  */
 #define PSA_KEY_TYPE_DES                        ((psa_key_type_t)0x04000002)
 /** Key for an cipher, AEAD or MAC algorithm based on the
- * Camellia block cipher. */
+ * Camellia block cipher.
+ */
 #define PSA_KEY_TYPE_CAMELLIA                   ((psa_key_type_t)0x04000003)
 /** Key for the RC4 stream cipher.
  *
  * Note that RC4 is weak and deprecated and should only be used in
- * legacy protocols. */
+ * legacy protocols.
+ */
 #define PSA_KEY_TYPE_ARC4                       ((psa_key_type_t)0x04000004)
 
 /** RSA public key. */
@@ -415,7 +440,8 @@
     (((type) & (PSA_KEY_TYPE_CATEGORY_MASK | PSA_KEY_TYPE_PAIR_FLAG)) == \
       PSA_KEY_TYPE_CATEGORY_ASYMMETRIC)
 /** Whether a key type is a key pair containing a private part and a public
- * part. */
+ * part.
+ */
 #define PSA_KEY_TYPE_IS_KEYPAIR(type)                                   \
     (((type) & (PSA_KEY_TYPE_CATEGORY_MASK | PSA_KEY_TYPE_PAIR_FLAG)) == \
      (PSA_KEY_TYPE_CATEGORY_ASYMMETRIC | PSA_KEY_TYPE_PAIR_FLAG))
@@ -433,7 +459,7 @@
     ((PSA_KEY_TYPE_PUBLIC_KEY_OF_KEYPAIR(type) &                        \
       ~PSA_KEY_TYPE_ECC_CURVE_MASK) == PSA_KEY_TYPE_ECC_PUBLIC_KEY_BASE)
 
-/** The type of PSA elliptic curve identifiers. */
+/** \brief The type of PSA elliptic curve identifiers. */
 typedef uint16_t psa_ecc_curve_t;
 /** Extract the curve from an elliptic curve key type. */
 #define PSA_KEY_TYPE_GET_CURVE(type)                             \
@@ -444,8 +470,10 @@
 /* The encoding of curve identifiers is currently aligned with the
  * TLS Supported Groups Registry (formerly known as the
  * TLS EC Named Curve Registry)
- * https://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml#tls-parameters-8
- * The values are defined by RFC 4492, RFC 7027 and RFC 7919. */
+ * https://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml
+ * #tls-parameters-8
+ * The values are defined by RFC 4492, RFC 7027 and RFC 7919.
+ */
 #define PSA_ECC_CURVE_SECT163K1         ((psa_ecc_curve_t) 0x0001)
 #define PSA_ECC_CURVE_SECT163R1         ((psa_ecc_curve_t) 0x0002)
 #define PSA_ECC_CURVE_SECT163R2         ((psa_ecc_curve_t) 0x0003)
@@ -860,15 +888,17 @@
  */
 #define PSA_KEY_USAGE_VERIFY                    ((psa_key_usage_t)0x00000800)
 
-/** The type of the key policy data structure.
+/** \brief The type of the key policy data structure.
  *
- * This is an implementation-defined \c struct. Applications should not
- * make any assumptions about the content of this structure except
- * as directed by the documentation of a specific implementation. */
-typedef struct psa_key_policy_s psa_key_policy_t;
+ * This is an implementation-defined type. Applications should not
+ * make any assumptions about this type except
+ * as directed by the documentation of a specific implementation.
+ */
+typedef uint32_t psa_key_policy_t;
 
 /** \brief Initialize a key policy structure to a default that forbids all
- * usage of the key. */
+ * usage of the key.
+ */
 void psa_key_policy_init(psa_key_policy_t *policy);
 
 /** \brief Set the standard fields of a policy structure.
@@ -897,8 +927,7 @@
 psa_status_t psa_set_key_policy(psa_key_slot_t key,
                                 const psa_key_policy_t *policy);
 
-/** \brief Get the usage policy for a key slot.
- */
+/** \brief Get the usage policy for a key slot. */
 psa_status_t psa_get_key_policy(psa_key_slot_t key,
                                 psa_key_policy_t *policy);
 
@@ -908,8 +937,7 @@
  * @{
  */
 
-/** Encoding of key lifetimes.
- */
+/** \brief Encoding of key lifetimes. */
 typedef uint32_t psa_key_lifetime_t;
 
 /** A volatile key slot retains its content as long as the application is
@@ -978,12 +1006,13 @@
  * @{
  */
 
-/** The type of the state data structure for multipart hash operations.
+/** \brief The type of the state data structure for multipart hash operations.
  *
- * This is an implementation-defined \c struct. Applications should not
- * make any assumptions about the content of this structure except
- * as directed by the documentation of a specific implementation. */
-typedef struct psa_hash_operation_s psa_hash_operation_t;
+ * This is an implementation-defined type. Applications should not
+ * make any assumptions about this type except
+ * as directed by the documentation of a specific implementation.
+ */
+typedef uint32_t psa_hash_operation_t;
 
 /** The size of the output of psa_hash_finish(), in bytes.
  *
@@ -1185,12 +1214,13 @@
  * @{
  */
 
-/** The type of the state data structure for multipart MAC operations.
+/** \brief The type of the state data structure for multipart MAC operations.
  *
- * This is an implementation-defined \c struct. Applications should not
- * make any assumptions about the content of this structure except
- * as directed by the documentation of a specific implementation. */
-typedef struct psa_mac_operation_s psa_mac_operation_t;
+ * This is an implementation-defined type. Applications should not
+ * make any assumptions about this type except
+ * as directed by the documentation of a specific implementation.
+ */
+typedef uint32_t psa_mac_operation_t;
 
 /** The size of the output of psa_mac_finish(), in bytes.
  *
@@ -1275,12 +1305,13 @@
  * @{
  */
 
-/** The type of the state data structure for multipart cipher operations.
+/** \brief The type of the state data structure for multipart cipher operations.
  *
- * This is an implementation-defined \c struct. Applications should not
- * make any assumptions about the content of this structure except
- * as directed by the documentation of a specific implementation. */
-typedef struct psa_cipher_operation_s psa_cipher_operation_t;
+ * This is an implementation-defined type. Applications should not
+ * make any assumptions about this type except
+ * as directed by the documentation of a specific implementation.
+ */
+typedef uint32_t psa_cipher_operation_t;
 
 /** Set the key for a multipart symmetric encryption operation.
  *
@@ -1927,4 +1958,9 @@
 }
 #endif
 
+/* The file "psa_crypto_extra.h" contains vendor-specific definitions. This
+ * can include vendor-defined algorithms, extra functions, etc.
+ */
+#include "psa_crypto_extra.h"
+
 #endif /* PSA_CRYPTO_H */
diff --git a/interface/include/psa_crypto_extra.h b/interface/include/psa_crypto_extra.h
new file mode 100644
index 0000000..d8fabf7
--- /dev/null
+++ b/interface/include/psa_crypto_extra.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2018, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+/**
+ * \file psa_crypto_extra.h
+ *
+ * \brief PSA cryptography module: vendor extensions
+ */
+
+#ifndef __PSA_CRYPTO_EXTRA_H__
+#define __PSA_CRYPTO_EXTRA_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \note This file is meant to be included by psa_crypto.h only
+ *
+ */
+
+/**
+ * \brief Library deinitialization.
+ *
+ * This function clears all data associated with the PSA layer,
+ * including the whole key store.
+ *
+ * This is an Mbed TLS extension.
+ */
+void mbedtls_psa_crypto_free(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __PSA_CRYPTO_EXTRA_H__ */
diff --git a/interface/include/psa_crypto_platform.h b/interface/include/psa_crypto_platform.h
new file mode 100644
index 0000000..118897b
--- /dev/null
+++ b/interface/include/psa_crypto_platform.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2018, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+/**
+ * \file psa_crypto_platform.h
+ *
+ * \brief PSA cryptography module: platform definitions
+ */
+
+#ifndef __PSA_CRYPTO_PLATFORM_H__
+#define __PSA_CRYPTO_PLATFORM_H__
+
+/**
+ * \note This file is meant to be included by psa_crypto.h only
+ *
+ */
+
+/* PSA requires several types which C99 provides in stdint.h. */
+#include <stdint.h>
+
+/* The following header is needed for platform specific constants */
+#include <limits.h>
+
+/* Integral type representing a key slot number. */
+typedef uint16_t psa_key_slot_t;
+
+#endif /* __PSA_CRYPTO_PLATFORM_H__ */
diff --git a/interface/include/tfm_crypto_defs.h b/interface/include/tfm_crypto_defs.h
new file mode 100644
index 0000000..1332a00
--- /dev/null
+++ b/interface/include/tfm_crypto_defs.h
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2018, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef __TFM_CRYPTO_DEFS_H__
+#define __TFM_CRYPTO_DEFS_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdint.h>
+#include <limits.h>
+#include "tfm_api.h"
+
+/* The return value is shared with the TFM service status value. The Crypto
+ * return codes shouldn't overlap with predefined TFM status values.
+ */
+#define TFM_CRYPTO_ERR_PSA_ERROR_OFFSET (TFM_PARTITION_SPECIFIC_ERROR_MIN)
+
+/**
+ * \brief This defines the maximum supported key length in bytes
+ *
+ */
+#define TFM_CRYPTO_MAX_KEY_LENGTH (16)
+
+/**
+  * \brief Define miscellaneous literal constants that are used in the module
+  *
+  */
+enum {
+    TFM_CRYPTO_NOT_IN_USE = 0,
+    TFM_CRYPTO_IN_USE = 1
+};
+
+enum tfm_crypto_err_t {
+    TFM_CRYPTO_ERR_PSA_SUCCESS = 0,
+    TFM_CRYPTO_ERR_PSA_ERROR_NOT_SUPPORTED = TFM_CRYPTO_ERR_PSA_ERROR_OFFSET,
+    TFM_CRYPTO_ERR_PSA_ERROR_NOT_PERMITTED,
+    TFM_CRYPTO_ERR_PSA_ERROR_BUFFER_TOO_SMALL,
+    TFM_CRYPTO_ERR_PSA_ERROR_OCCUPIED_SLOT,
+    TFM_CRYPTO_ERR_PSA_ERROR_EMPTY_SLOT,
+    TFM_CRYPTO_ERR_PSA_ERROR_BAD_STATE,
+    TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT,
+    TFM_CRYPTO_ERR_PSA_ERROR_INSUFFICIENT_MEMORY,
+    TFM_CRYPTO_ERR_PSA_ERROR_INSUFFICIENT_STORAGE,
+    TFM_CRYPTO_ERR_PSA_ERROR_COMMUNICATION_FAILURE,
+    TFM_CRYPTO_ERR_PSA_ERROR_STORAGE_FAILURE,
+    TFM_CRYPTO_ERR_PSA_ERROR_HARDWARE_FAILURE,
+    TFM_CRYPTO_ERR_PSA_ERROR_TAMPERING_DETECTED,
+    TFM_CRYPTO_ERR_PSA_ERROR_INSUFFICIENT_ENTROPY,
+    TFM_CRYPTO_ERR_PSA_ERROR_INVALID_SIGNATURE,
+    TFM_CRYPTO_ERR_PSA_ERROR_INVALID_PADDING,
+    TFM_CRYPTO_ERR_PSA_ERROR_UNKNOWN_ERROR,
+
+    /* Add an invalid return code which forces the size of the type as well */
+    TFM_CRYPTO_ERR_INVALID = INT_MAX
+};
+
+/**
+ * \brief A macro to translate PSA API return values including the offset
+ *        needed by TFM, to the corresponding PSA value
+ */
+#define TFM_CRYPTO_PSA_RETURN(val) \
+                        ( (val == TFM_CRYPTO_ERR_PSA_SUCCESS) ? val : \
+                         ((val >= TFM_CRYPTO_ERR_PSA_ERROR_NOT_SUPPORTED) ? \
+                          (val - (TFM_CRYPTO_ERR_PSA_ERROR_NOT_SUPPORTED-1)) : \
+                           TFM_CRYPTO_ERR_INVALID) )
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __TFM_CRYPTO_DEFS_H__ */
diff --git a/interface/include/tfm_crypto_veneers.h b/interface/include/tfm_crypto_veneers.h
new file mode 100644
index 0000000..b158f51
--- /dev/null
+++ b/interface/include/tfm_crypto_veneers.h
@@ -0,0 +1,160 @@
+/*
+ * Copyright (c) 2018, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef __TFM_CRYPTO_VENEERS_H__
+#define __TFM_CRYPTO_VENEERS_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "tfm_crypto_defs.h"
+
+#include "psa_crypto.h"
+
+#include "crypto_psa_wrappers.h"
+
+/**
+ * \brief Import the key data on the provided key slot (veneer function)
+ *
+ * \param[in] key         Key slot
+ * \param[in] type        Key type
+ * \param[in] data        Key data to import
+ * \param[in] data_length Length in bytes of the data field
+ *
+ * \return Return values as described in \ref tfm_crypto_err_t
+ */
+enum tfm_crypto_err_t tfm_crypto_veneer_import_key(psa_key_slot_t key,
+                                                   psa_key_type_t type,
+                                                   const uint8_t *data,
+                                                   size_t data_length);
+/**
+ * \brief Destroy the key in the provided key slot (veneer function)
+ *
+ * \param[in] key         Key slot
+ *
+ * \return Return values as described in \ref tfm_crypto_err_t
+ */
+enum tfm_crypto_err_t tfm_crypto_veneer_destroy_key(psa_key_slot_t key);
+
+/**
+ * \brief Retrieve key information for the provided key slot (veneer function)
+ *
+ * \param[in]  key  Key slot
+ * \param[out] type Key type associated to the key slot requested
+ * \param[out] bits Length in bits of the key in the requested slot
+ *
+ * \return Return values as described in \ref tfm_crypto_err_t
+ */
+enum tfm_crypto_err_t tfm_crypto_veneer_get_key_information(
+                                                           psa_key_slot_t key,
+                                                           psa_key_type_t *type,
+                                                           size_t *bits);
+/**
+ * \brief Export the key contained in the provided key slot (veneer function)
+ *
+ * \param[in] key          Key slot
+ * \param[out] data        Buffer to hold the exported key
+ * \param[in] data_size    Length of the buffer pointed to by data
+ * \param[out] data_length Length of the exported key
+ *
+ * \return Return values as described in \ref tfm_crypto_err_t
+ */
+enum tfm_crypto_err_t tfm_crypto_veneer_export_key(psa_key_slot_t key,
+                                                   uint8_t *data,
+                                                   size_t data_size,
+                                                   size_t *data_length);
+/**
+ * \brief Set the initialisation vector on the provided cipher operation (veneer
+ *        function)
+ *
+ * \param[in] operation  Cipher operation context
+ * \param[in] iv         Buffer that contains the IV
+ * \param[in] iv_length  Length of the provided IV
+ *
+ * \return Return values as described in \ref tfm_crypto_err_t
+ */
+enum tfm_crypto_err_t tfm_crypto_veneer_encrypt_set_iv(
+                                              psa_cipher_operation_t *operation,
+                                              const unsigned char *iv,
+                                              size_t iv_length);
+/**
+ * \brief Set the cipher operation using the provided algorithm and key slot,
+ *        for encryption context (veneer function)
+ *
+ * \param[in] operation Cipher operation context
+ * \param[in] key       Key slot to bind to the cipher context
+ * \param[in] alg       Algorithm to use for the cipher operation
+ *
+ * \return Return values as described in \ref tfm_crypto_err_t
+ */
+enum tfm_crypto_err_t tfm_crypto_veneer_encrypt_setup(
+                                              psa_cipher_operation_t *operation,
+                                              psa_key_slot_t key,
+                                              psa_algorithm_t alg);
+/**
+ * \brief Set the cipher operation using the provided algorithm and key slot,
+ *        for decryption context (veneer function)
+ *
+ * \param[in] operation Cipher operation context
+ * \param[in] key       Key slot to bind to the cipher context
+ * \param[in] alg       Algorithm to use for the cipher operation
+ *
+ * \return Return values as described in \ref tfm_crypto_err_t
+ */
+enum tfm_crypto_err_t tfm_crypto_veneer_decrypt_setup(
+                                              psa_cipher_operation_t *operation,
+                                              psa_key_slot_t key,
+                                              psa_algorithm_t alg);
+/**
+ * \brief Update the cipher context with a chunk of input data to create a
+ *        chunk of encrypted output data (for encryption contexts), or to
+ *        decrypt a chunk of encrypted input data to obtain decrypted data
+ *        (for decryption contexts) (veneer function)
+ *
+ * \param[in]  operation Cipher operation context
+ * \param[in]  input_s   Pointer to the struct containing input parameters
+ * \param[out] output_s  Pointer to the struct containing output parameters
+ *
+ * \return Return values as described in \ref tfm_crypto_err_t
+ */
+enum tfm_crypto_err_t tfm_crypto_veneer_cipher_update(
+                                     psa_cipher_operation_t *operation,
+                                     struct psa_cipher_update_input *input_s,
+                                     struct psa_cipher_update_output *output_s);
+/**
+ * \brief Abort a cipher operation, clears the operation context provided
+ *        (veneer function)
+ *
+ * \param[in]  operation     Cipher operation context
+ *
+ * \return Return values as described in \ref tfm_crypto_err_t
+ */
+enum tfm_crypto_err_t tfm_crypto_veneer_cipher_abort(
+                                             psa_cipher_operation_t *operation);
+
+/**
+ * \brief Finalise a cipher context flushing out any remaining block of
+ *        output data (veneer function)
+ *
+ * \param[in]  operation     Cipher operation context
+ * \param[out] output        Buffer containing output data
+ * \param[in]  output_size   Size of the output buffer
+ * \param[out] output_length Size of the produced output
+ *
+ * \return Return values as described in \ref tfm_crypto_err_t
+ */
+enum tfm_crypto_err_t tfm_crypto_veneer_cipher_finish(
+                                             psa_cipher_operation_t *operation,
+                                             uint8_t *output,
+                                             size_t output_size,
+                                             size_t *output_length);
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __TFM_CRYPTO_VENEERS_H__ */
diff --git a/interface/src/tfm_crypto_api.c b/interface/src/tfm_crypto_api.c
new file mode 100644
index 0000000..d98f85f
--- /dev/null
+++ b/interface/src/tfm_crypto_api.c
@@ -0,0 +1,190 @@
+/*
+ * Copyright (c) 2018, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#include "tfm_crypto_veneers.h"
+#include "psa_crypto.h"
+#include "tfm_ns_lock.h"
+#include "crypto_psa_wrappers.h"
+
+psa_status_t psa_crypto_init(void)
+{
+    /* Service init is performed during TFM boot up,
+     * so application level initialisation is empty
+     */
+    return PSA_SUCCESS;
+}
+
+psa_status_t psa_import_key(psa_key_slot_t key,
+                            psa_key_type_t type,
+                            const uint8_t *data,
+                            size_t data_length)
+{
+    enum tfm_crypto_err_t err;
+
+    err = tfm_ns_lock_dispatch((veneer_fn)tfm_crypto_veneer_import_key,
+                               (uint32_t)key,
+                               (uint32_t)type,
+                               (uint32_t)data,
+                               (uint32_t)data_length);
+
+    return TFM_CRYPTO_PSA_RETURN(err);
+}
+
+psa_status_t psa_destroy_key(psa_key_slot_t key)
+{
+    enum tfm_crypto_err_t err;
+
+    err = tfm_ns_lock_dispatch((veneer_fn)tfm_crypto_veneer_destroy_key,
+                               (uint32_t)key,
+                               0,
+                               0,
+                               0);
+
+    return TFM_CRYPTO_PSA_RETURN(err);
+}
+
+psa_status_t psa_get_key_information(psa_key_slot_t key,
+                                     psa_key_type_t *type,
+                                     size_t *bits)
+{
+    enum tfm_crypto_err_t err;
+
+    err = tfm_ns_lock_dispatch((veneer_fn)tfm_crypto_veneer_get_key_information,
+                               (uint32_t)key,
+                               (uint32_t)type,
+                               (uint32_t)bits,
+                               0);
+
+    return TFM_CRYPTO_PSA_RETURN(err);
+}
+
+psa_status_t psa_export_key(psa_key_slot_t key,
+                            uint8_t *data,
+                            size_t data_size,
+                            size_t *data_length)
+{
+    enum tfm_crypto_err_t err;
+
+    err = tfm_ns_lock_dispatch((veneer_fn)tfm_crypto_veneer_export_key,
+                               (uint32_t)key,
+                               (uint32_t)data,
+                               (uint32_t)data_size,
+                               (uint32_t)data_length);
+
+    return TFM_CRYPTO_PSA_RETURN(err);
+}
+
+psa_status_t psa_export_public_key(psa_key_slot_t key,
+                                   uint8_t *data,
+                                   size_t data_size,
+                                   size_t *data_length)
+{
+    /* TODO: This API is not supported yet */
+    return PSA_ERROR_NOT_SUPPORTED;
+}
+
+psa_status_t psa_encrypt_set_iv(psa_cipher_operation_t *operation,
+                                const unsigned char *iv,
+                                size_t iv_length)
+{
+    enum tfm_crypto_err_t err;
+
+    err = tfm_ns_lock_dispatch((veneer_fn)tfm_crypto_veneer_encrypt_set_iv,
+                               (uint32_t)operation,
+                               (uint32_t)iv,
+                               (uint32_t)iv_length,
+                               0);
+
+    return TFM_CRYPTO_PSA_RETURN(err);
+}
+
+psa_status_t psa_encrypt_setup(psa_cipher_operation_t *operation,
+                               psa_key_slot_t key,
+                               psa_algorithm_t alg)
+{
+    enum tfm_crypto_err_t err;
+
+    err = tfm_ns_lock_dispatch((veneer_fn)tfm_crypto_veneer_encrypt_setup,
+                               (uint32_t)operation,
+                               (uint32_t)key,
+                               (uint32_t)alg,
+                               0);
+
+    return TFM_CRYPTO_PSA_RETURN(err);
+}
+
+psa_status_t psa_decrypt_setup(psa_cipher_operation_t *operation,
+                               psa_key_slot_t key,
+                               psa_algorithm_t alg)
+{
+    enum tfm_crypto_err_t err;
+
+    err = tfm_ns_lock_dispatch((veneer_fn)tfm_crypto_veneer_decrypt_setup,
+                               (uint32_t)operation,
+                               (uint32_t)key,
+                               (uint32_t)alg,
+                               0);
+
+    return TFM_CRYPTO_PSA_RETURN(err);
+}
+
+psa_status_t psa_cipher_update(psa_cipher_operation_t *operation,
+                               const uint8_t *input,
+                               size_t input_length,
+                               unsigned char *output,
+                               size_t output_size,
+                               size_t *output_length)
+{
+    enum tfm_crypto_err_t err;
+
+    /* Packing in structures is needed to overcome the 4 parameters
+     * per call limit
+     */
+    struct psa_cipher_update_input input_s = {.input = input,
+                                              .input_length = input_length};
+    struct psa_cipher_update_output output_s = {.output = output,
+                                                .output_size = output_size,
+                                                .output_length =
+                                                               output_length};
+
+    err = tfm_ns_lock_dispatch((veneer_fn)tfm_crypto_veneer_cipher_update,
+                               (uint32_t)operation,
+                               (uint32_t)&input_s,
+                               (uint32_t)&output_s,
+                               0);
+
+    return TFM_CRYPTO_PSA_RETURN(err);
+}
+
+psa_status_t psa_cipher_abort(psa_cipher_operation_t *operation)
+{
+    enum tfm_crypto_err_t err;
+
+    err = tfm_ns_lock_dispatch((veneer_fn)tfm_crypto_veneer_cipher_abort,
+                               (uint32_t)operation,
+                               0,
+                               0,
+                               0);
+
+    return TFM_CRYPTO_PSA_RETURN(err);
+}
+
+psa_status_t psa_cipher_finish(psa_cipher_operation_t *operation,
+                               uint8_t *output,
+                               size_t output_size,
+                               size_t *output_length)
+{
+    enum tfm_crypto_err_t err;
+
+    err = tfm_ns_lock_dispatch((veneer_fn)tfm_crypto_veneer_cipher_finish,
+                               (uint32_t)operation,
+                               (uint32_t)output,
+                               (uint32_t)output_size,
+                               (uint32_t)output_length);
+
+    return TFM_CRYPTO_PSA_RETURN(err);
+}