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/CommonConfig.cmake b/CommonConfig.cmake
index 175c628..8996fe6 100644
--- a/CommonConfig.cmake
+++ b/CommonConfig.cmake
@@ -186,8 +186,8 @@
 	endif()
 endif()
 
-##Set mbedTLS compiler flags and variables for secure storage and audit log
-set(MBEDTLS_C_FLAGS_SST_LOG "-D__ARM_FEATURE_CMSE=3 -D__thumb2__ ${COMMON_COMPILE_FLAGS_STR} -DMBEDTLS_CONFIG_FILE=\\\\\\\"tfm_mbedtls_config.h\\\\\\\" -I${CMAKE_CURRENT_LIST_DIR}/platform/ext/common")
+##Set mbedTLS compiler flags and variables for secure storage, audit log and crypto
+set(MBEDTLS_C_FLAGS_SERVICES "-D__ARM_FEATURE_CMSE=3 -D__thumb2__ ${COMMON_COMPILE_FLAGS_STR} -DMBEDTLS_CONFIG_FILE=\\\\\\\"tfm_mbedtls_config.h\\\\\\\" -I${CMAKE_CURRENT_LIST_DIR}/platform/ext/common")
 
 #Default TF-M secure storage flags.
 #These flags values can be overwritten by setting them in platform/ext/<TARGET_NAME>.cmake
diff --git a/app/CMakeLists.txt b/app/CMakeLists.txt
index 5edb868..f0fa6f1 100755
--- a/app/CMakeLists.txt
+++ b/app/CMakeLists.txt
@@ -45,6 +45,7 @@
 	"${APP_DIR}/os_wrapper_rtx.c"
 	"${INTERFACE_DIR}/src/tfm_sst_api.c"
 	"${INTERFACE_DIR}/src/tfm_audit_api.c"
+	"${INTERFACE_DIR}/src/tfm_crypto_api.c"
 	"${INTERFACE_DIR}/src/tfm_nspm_svc_handler.c"
 	"${INTERFACE_DIR}/src/tfm_nspm_api.c"
 	"${INTERFACE_DIR}/src/tfm_ns_lock_rtx.c"
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);
+}
diff --git a/platform/ext/target/mps2/an519/armclang/mps2_an519_s.sct b/platform/ext/target/mps2/an519/armclang/mps2_an519_s.sct
index 030259f..a6b510c 100644
--- a/platform/ext/target/mps2/an519/armclang/mps2_an519_s.sct
+++ b/platform/ext/target/mps2/an519/armclang/mps2_an519_s.sct
@@ -58,6 +58,10 @@
         *tfm_audit* (+RO)
     }
 
+    TFM_SP_CRYPTO +0 ALIGN 32 {
+        *tfm_crypto* (+RO)
+    }
+
 #ifdef TFM_PARTITION_TEST_CORE
     TFM_SP_CORE_TEST +0 ALIGN 32 {
         *tfm_ss_core_test.* (+RO)
@@ -113,6 +117,13 @@
     TFM_SP_AUDIT_LOG_STACK +0 ALIGN 128 EMPTY 0x1000 {
     }
 
+    TFM_SP_CRYPTO_DATA +0 ALIGN 32 {
+        *tfm_crypto* (+RW +ZI)
+    }
+
+    TFM_SP_CRYPTO_STACK +0 ALIGN 128 EMPTY 0x2000 {
+    }
+
 #ifdef TFM_PARTITION_TEST_CORE
     TFM_SP_CORE_TEST_DATA +0 ALIGN 32 {
         tfm_ss_core_test.o (+RW +ZI)
diff --git a/platform/ext/target/mps2/an519/gcc/mps2_an519_s.ld b/platform/ext/target/mps2/an519/gcc/mps2_an519_s.ld
index 25f41ee..9f216ea 100644
--- a/platform/ext/target/mps2/an519/gcc/mps2_an519_s.ld
+++ b/platform/ext/target/mps2/an519/gcc/mps2_an519_s.ld
@@ -97,6 +97,9 @@
         LONG (LOADADDR(.TFM_SP_AUDIT_LOG_DATA))
         LONG (ADDR(.TFM_SP_AUDIT_LOG_DATA))
         LONG (SIZEOF(.TFM_SP_AUDIT_LOG_DATA))
+        LONG (LOADADDR(.TFM_SP_CRYPTO_DATA))
+        LONG (ADDR(.TFM_SP_CRYPTO_DATA))
+        LONG (SIZEOF(.TFM_SP_CRYPTO_DATA))
 #ifdef TFM_PARTITION_TEST_CORE
         LONG (LOADADDR(.TFM_SP_CORE_TEST_DATA))
         LONG (ADDR(.TFM_SP_CORE_TEST_DATA))
@@ -135,6 +138,10 @@
         LONG (SIZEOF(.TFM_SP_AUDIT_LOG_BSS))
         LONG (ADDR(.TFM_SP_AUDIT_LOG_STACK))
         LONG (SIZEOF(.TFM_SP_AUDIT_LOG_STACK))
+        LONG (ADDR(.TFM_SP_CRYPTO_BSS))
+        LONG (SIZEOF(.TFM_SP_CRYPTO_BSS))
+        LONG (ADDR(.TFM_SP_CRYPTO_STACK))
+        LONG (SIZEOF(.TFM_SP_CRYPTO_STACK))
 #ifdef TFM_PARTITION_TEST_CORE
         LONG (ADDR(.TFM_SP_CORE_TEST_BSS))
         LONG (SIZEOF(.TFM_SP_CORE_TEST_BSS))
@@ -204,6 +211,17 @@
     Image$$TFM_SP_AUDIT_LOG$$Base = ADDR(.TFM_SP_AUDIT_LOG);
     Image$$TFM_SP_AUDIT_LOG$$Limit = ADDR(.TFM_SP_AUDIT_LOG) + SIZEOF(.TFM_SP_AUDIT_LOG);
 
+    .TFM_SP_CRYPTO : ALIGN(32)
+    {
+        *tfm_crypto*:*(.text*)
+        *tfm_crypto*:*(.rodata*)
+        . = ALIGN(32);
+    } > FLASH
+    Image$$TFM_SP_CRYPTO$$RO$$Base = ADDR(.TFM_SP_CRYPTO);
+    Image$$TFM_SP_CRYPTO$$RO$$Limit = ADDR(.TFM_SP_CRYPTO) + SIZEOF(.TFM_SP_CRYPTO);
+    Image$$TFM_SP_CRYPTO$$Base = ADDR(.TFM_SP_CRYPTO);
+    Image$$TFM_SP_CRYPTO$$Limit = ADDR(.TFM_SP_CRYPTO) + SIZEOF(.TFM_SP_CRYPTO);
+
 #ifdef TFM_PARTITION_TEST_CORE
     .TFM_SP_CORE_TEST : ALIGN(32)
     {
@@ -410,6 +428,30 @@
     Image$$TFM_SP_AUDIT_LOG_STACK$$ZI$$Base = ADDR(.TFM_SP_AUDIT_LOG_STACK);
     Image$$TFM_SP_AUDIT_LOG_STACK$$ZI$$Limit = ADDR(.TFM_SP_AUDIT_LOG_STACK) + SIZEOF(.TFM_SP_AUDIT_LOG_STACK);
 
+    .TFM_SP_CRYPTO_DATA : ALIGN(32)
+    {
+        *tfm_crypto*:*(.data*)
+        . = ALIGN(32);
+    } > RAM AT> FLASH
+    Image$$TFM_SP_CRYPTO_DATA$$RW$$Base = ADDR(.TFM_SP_CRYPTO_DATA);
+    Image$$TFM_SP_CRYPTO_DATA$$RW$$Limit = ADDR(.TFM_SP_CRYPTO_DATA) + SIZEOF(.TFM_SP_CRYPTO_DATA);
+
+    .TFM_SP_CRYPTO_BSS : ALIGN(32)
+    {
+        *tfm_crypto*:*(.bss*)
+        *tfm_crypto*:*(COMMON)
+        . = ALIGN(32);
+    } > RAM AT> FLASH
+    Image$$TFM_SP_CRYPTO_DATA$$ZI$$Base = ADDR(.TFM_SP_CRYPTO_BSS);
+    Image$$TFM_SP_CRYPTO_DATA$$ZI$$Limit = ADDR(.TFM_SP_CRYPTO_BSS) + SIZEOF(.TFM_SP_CRYPTO_BSS);
+
+    .TFM_SP_CRYPTO_STACK : ALIGN(128)
+    {
+        . += 0x2000;
+    } > RAM AT> FLASH
+    Image$$TFM_SP_CRYPTO_STACK$$ZI$$Base = ADDR(.TFM_SP_CRYPTO_STACK);
+    Image$$TFM_SP_CRYPTO_STACK$$ZI$$Limit = ADDR(.TFM_SP_CRYPTO_STACK) + SIZEOF(.TFM_SP_CRYPTO_STACK);
+
 #ifdef TFM_PARTITION_TEST_CORE
     .TFM_SP_CORE_TEST_DATA : ALIGN(32)
     {
diff --git a/platform/ext/target/mps2/an519/partition/region_defs.h b/platform/ext/target/mps2/an519/partition/region_defs.h
index dbf55aa..aea1f52 100644
--- a/platform/ext/target/mps2/an519/partition/region_defs.h
+++ b/platform/ext/target/mps2/an519/partition/region_defs.h
@@ -67,7 +67,7 @@
 #define IMAGE_CODE_SIZE \
             (FLASH_PARTITION_SIZE - BL2_HEADER_SIZE - BL2_TRAILER_SIZE)
 
-#define CMSE_VENEER_REGION_SIZE     (0x00000100)
+#define CMSE_VENEER_REGION_SIZE     (0x000001C0)
 
 /* Use SRAM1 memory to store Code data */
 #define S_ROM_ALIAS_BASE  (0x10000000)
diff --git a/platform/ext/target/mps2/an521/armclang/mps2_an521_s.sct b/platform/ext/target/mps2/an521/armclang/mps2_an521_s.sct
index 030259f..c8d4ac6 100644
--- a/platform/ext/target/mps2/an521/armclang/mps2_an521_s.sct
+++ b/platform/ext/target/mps2/an521/armclang/mps2_an521_s.sct
@@ -58,6 +58,10 @@
         *tfm_audit* (+RO)
     }
 
+    TFM_SP_CRYPTO +0 ALIGN 32 {
+        *tfm_crypto* (+RO)
+    }
+
 #ifdef TFM_PARTITION_TEST_CORE
     TFM_SP_CORE_TEST +0 ALIGN 32 {
         *tfm_ss_core_test.* (+RO)
@@ -113,6 +117,14 @@
     TFM_SP_AUDIT_LOG_STACK +0 ALIGN 128 EMPTY 0x1000 {
     }
 
+    TFM_SP_CRYPTO_DATA +0 ALIGN 32 {
+        *tfm_crypto* (+RW +ZI)
+    }
+
+    TFM_SP_CRYPTO_STACK +0 ALIGN 128 EMPTY 0x2000 {
+    }
+
+
 #ifdef TFM_PARTITION_TEST_CORE
     TFM_SP_CORE_TEST_DATA +0 ALIGN 32 {
         tfm_ss_core_test.o (+RW +ZI)
diff --git a/platform/ext/target/mps2/an521/gcc/mps2_an521_s.ld b/platform/ext/target/mps2/an521/gcc/mps2_an521_s.ld
index 8255618..aabe969 100644
--- a/platform/ext/target/mps2/an521/gcc/mps2_an521_s.ld
+++ b/platform/ext/target/mps2/an521/gcc/mps2_an521_s.ld
@@ -97,6 +97,9 @@
         LONG (LOADADDR(.TFM_SP_AUDIT_LOG_DATA))
         LONG (ADDR(.TFM_SP_AUDIT_LOG_DATA))
         LONG (SIZEOF(.TFM_SP_AUDIT_LOG_DATA))
+        LONG (LOADADDR(.TFM_SP_CRYPTO_DATA))
+        LONG (ADDR(.TFM_SP_CRYPTO_DATA))
+        LONG (SIZEOF(.TFM_SP_CRYPTO_DATA))
 #ifdef TFM_PARTITION_TEST_CORE
         LONG (LOADADDR(.TFM_SP_CORE_TEST_DATA))
         LONG (ADDR(.TFM_SP_CORE_TEST_DATA))
@@ -135,6 +138,10 @@
         LONG (SIZEOF(.TFM_SP_AUDIT_LOG_BSS))
         LONG (ADDR(.TFM_SP_AUDIT_LOG_STACK))
         LONG (SIZEOF(.TFM_SP_AUDIT_LOG_STACK))
+        LONG (ADDR(.TFM_SP_CRYPTO_BSS))
+        LONG (SIZEOF(.TFM_SP_CRYPTO_BSS))
+        LONG (ADDR(.TFM_SP_CRYPTO_STACK))
+        LONG (SIZEOF(.TFM_SP_CRYPTO_STACK))
 #ifdef TFM_PARTITION_TEST_CORE
         LONG (ADDR(.TFM_SP_CORE_TEST_BSS))
         LONG (SIZEOF(.TFM_SP_CORE_TEST_BSS))
@@ -204,6 +211,17 @@
     Image$$TFM_SP_AUDIT_LOG$$Base = ADDR(.TFM_SP_AUDIT_LOG);
     Image$$TFM_SP_AUDIT_LOG$$Limit = ADDR(.TFM_SP_AUDIT_LOG) + SIZEOF(.TFM_SP_AUDIT_LOG);
 
+    .TFM_SP_CRYPTO : ALIGN(32)
+    {
+        *tfm_crypto*:*(.text*)
+        *tfm_crypto*:*(.rodata*)
+        . = ALIGN(32);
+    } > FLASH
+    Image$$TFM_SP_CRYPTO$$RO$$Base = ADDR(.TFM_SP_CRYPTO);
+    Image$$TFM_SP_CRYPTO$$RO$$Limit = ADDR(.TFM_SP_CRYPTO) + SIZEOF(.TFM_SP_CRYPTO);
+    Image$$TFM_SP_CRYPTO$$Base = ADDR(.TFM_SP_CRYPTO);
+    Image$$TFM_SP_CRYPTO$$Limit = ADDR(.TFM_SP_CRYPTO) + SIZEOF(.TFM_SP_CRYPTO);
+
 #ifdef TFM_PARTITION_TEST_CORE
     .TFM_SP_CORE_TEST : ALIGN(32)
     {
@@ -410,6 +428,30 @@
     Image$$TFM_SP_AUDIT_LOG_STACK$$ZI$$Base = ADDR(.TFM_SP_AUDIT_LOG_STACK);
     Image$$TFM_SP_AUDIT_LOG_STACK$$ZI$$Limit = ADDR(.TFM_SP_AUDIT_LOG_STACK) + SIZEOF(.TFM_SP_AUDIT_LOG_STACK);
 
+    .TFM_SP_CRYPTO_DATA : ALIGN(32)
+    {
+        *tfm_crypto*:*(.data*)
+        . = ALIGN(32);
+    } > RAM AT> FLASH
+    Image$$TFM_SP_CRYPTO_DATA$$RW$$Base = ADDR(.TFM_SP_CRYPTO_DATA);
+    Image$$TFM_SP_CRYPTO_DATA$$RW$$Limit = ADDR(.TFM_SP_CRYPTO_DATA) + SIZEOF(.TFM_SP_CRYPTO_DATA);
+
+    .TFM_SP_CRYPTO_BSS : ALIGN(32)
+    {
+        *tfm_crypto*:*(.bss*)
+        *tfm_crypto*:*(COMMON)
+        . = ALIGN(32);
+    } > RAM AT> FLASH
+    Image$$TFM_SP_CRYPTO_DATA$$ZI$$Base = ADDR(.TFM_SP_CRYPTO_BSS);
+    Image$$TFM_SP_CRYPTO_DATA$$ZI$$Limit = ADDR(.TFM_SP_CRYPTO_BSS) + SIZEOF(.TFM_SP_CRYPTO_BSS);
+
+    .TFM_SP_CRYPTO_STACK : ALIGN(128)
+    {
+        . += 0x2000;
+    } > RAM AT> FLASH
+    Image$$TFM_SP_CRYPTO_STACK$$ZI$$Base = ADDR(.TFM_SP_CRYPTO_STACK);
+    Image$$TFM_SP_CRYPTO_STACK$$ZI$$Limit = ADDR(.TFM_SP_CRYPTO_STACK) + SIZEOF(.TFM_SP_CRYPTO_STACK);
+
 #ifdef TFM_PARTITION_TEST_CORE
     .TFM_SP_CORE_TEST_DATA : ALIGN(32)
     {
diff --git a/platform/ext/target/mps2/an521/partition/region_defs.h b/platform/ext/target/mps2/an521/partition/region_defs.h
index 3487d2f..0709627 100644
--- a/platform/ext/target/mps2/an521/partition/region_defs.h
+++ b/platform/ext/target/mps2/an521/partition/region_defs.h
@@ -67,7 +67,7 @@
 #define IMAGE_CODE_SIZE \
             (FLASH_PARTITION_SIZE - BL2_HEADER_SIZE - BL2_TRAILER_SIZE)
 
-#define CMSE_VENEER_REGION_SIZE     (0x00000100)
+#define CMSE_VENEER_REGION_SIZE     (0x000001C0)
 
 /* Use SRAM1 memory to store Code data */
 #define S_ROM_ALIAS_BASE  (0x10000000)
diff --git a/platform/ext/target/musca_a/Device/Source/armclang/musca_s.sct b/platform/ext/target/musca_a/Device/Source/armclang/musca_s.sct
index 053c3aa..b0ad519 100755
--- a/platform/ext/target/musca_a/Device/Source/armclang/musca_s.sct
+++ b/platform/ext/target/musca_a/Device/Source/armclang/musca_s.sct
@@ -58,6 +58,10 @@
         *tfm_audit* (+RO)
     }
 
+    TFM_SP_CRYPTO +0 ALIGN 32 {
+        *tfm_crypto* (+RO)
+    }
+
 #ifdef TFM_PARTITION_TEST_CORE
     TFM_SP_CORE_TEST +0 ALIGN 32 {
         *tfm_ss_core_test.* (+RO)
@@ -114,6 +118,13 @@
     TFM_SP_AUDIT_LOG_STACK +0 ALIGN 128 EMPTY 0x1000 {
     }
 
+    TFM_SP_CRYPTO_DATA +0 ALIGN 32 {
+        *tfm_crypto* (+RW +ZI)
+    }
+
+    TFM_SP_CRYPTO_STACK +0 ALIGN 128 EMPTY 0x2000 {
+    }
+
 #ifdef TFM_PARTITION_TEST_CORE
     TFM_SP_CORE_TEST_DATA +0 ALIGN 32 {
         tfm_ss_core_test.o (+RW +ZI)
diff --git a/platform/ext/target/musca_a/Device/Source/gcc/musca_s.ld b/platform/ext/target/musca_a/Device/Source/gcc/musca_s.ld
index 54b4a61..6adf125 100644
--- a/platform/ext/target/musca_a/Device/Source/gcc/musca_s.ld
+++ b/platform/ext/target/musca_a/Device/Source/gcc/musca_s.ld
@@ -97,6 +97,9 @@
         LONG (LOADADDR(.TFM_SP_AUDIT_LOG_DATA))
         LONG (ADDR(.TFM_SP_AUDIT_LOG_DATA))
         LONG (SIZEOF(.TFM_SP_AUDIT_LOG_DATA))
+        LONG (LOADADDR(.TFM_SP_CRYPTO_DATA))
+        LONG (ADDR(.TFM_SP_CRYPTO_DATA))
+        LONG (SIZEOF(.TFM_SP_CRYPTO_DATA))
 #ifdef TFM_PARTITION_TEST_CORE
         LONG (LOADADDR(.TFM_SP_CORE_TEST_DATA))
         LONG (ADDR(.TFM_SP_CORE_TEST_DATA))
@@ -135,6 +138,10 @@
         LONG (SIZEOF(.TFM_SP_AUDIT_LOG_BSS))
         LONG (ADDR(.TFM_SP_AUDIT_LOG_STACK))
         LONG (SIZEOF(.TFM_SP_AUDIT_LOG_STACK))
+        LONG (ADDR(.TFM_SP_CRYPTO_BSS))
+        LONG (SIZEOF(.TFM_SP_CRYPTO_BSS))
+        LONG (ADDR(.TFM_SP_CRYPTO_STACK))
+        LONG (SIZEOF(.TFM_SP_CRYPTO_STACK))
 #ifdef TFM_PARTITION_TEST_CORE
         LONG (ADDR(.TFM_SP_CORE_TEST_BSS))
         LONG (SIZEOF(.TFM_SP_CORE_TEST_BSS))
@@ -204,6 +211,17 @@
     Image$$TFM_SP_AUDIT_LOG$$Base = ADDR(.TFM_SP_AUDIT_LOG);
     Image$$TFM_SP_AUDIT_LOG$$Limit = ADDR(.TFM_SP_AUDIT_LOG) + SIZEOF(.TFM_SP_AUDIT_LOG);
 
+    .TFM_SP_CRYPTO : ALIGN(32)
+    {
+        *tfm_crypto*:*(.text*)
+        *tfm_crypto*:*(.rodata*)
+        . = ALIGN(32);
+    } > FLASH
+    Image$$TFM_SP_CRYPTO$$RO$$Base = ADDR(.TFM_SP_CRYPTO);
+    Image$$TFM_SP_CRYPTO$$RO$$Limit = ADDR(.TFM_SP_CRYPTO) + SIZEOF(.TFM_SP_CRYPTO);
+    Image$$TFM_SP_CRYPTO$$Base = ADDR(.TFM_SP_CRYPTO);
+    Image$$TFM_SP_CRYPTO$$Limit = ADDR(.TFM_SP_CRYPTO) + SIZEOF(.TFM_SP_CRYPTO);
+
 #ifdef TFM_PARTITION_TEST_CORE
     .TFM_SP_CORE_TEST : ALIGN(32)
     {
@@ -410,6 +428,30 @@
     Image$$TFM_SP_AUDIT_LOG_STACK$$ZI$$Base = ADDR(.TFM_SP_AUDIT_LOG_STACK);
     Image$$TFM_SP_AUDIT_LOG_STACK$$ZI$$Limit = ADDR(.TFM_SP_AUDIT_LOG_STACK) + SIZEOF(.TFM_SP_AUDIT_LOG_STACK);
 
+    .TFM_SP_CRYPTO_DATA : ALIGN(32)
+    {
+        *tfm_crypto*:*(.data*)
+        . = ALIGN(32);
+    } > RAM AT> FLASH
+    Image$$TFM_SP_CRYPTO_DATA$$RW$$Base = ADDR(.TFM_SP_CRYPTO_DATA);
+    Image$$TFM_SP_CRYPTO_DATA$$RW$$Limit = ADDR(.TFM_SP_CRYPTO_DATA) + SIZEOF(.TFM_SP_CRYPTO_DATA);
+
+    .TFM_SP_CRYPTO_BSS : ALIGN(32)
+    {
+        *tfm_crypto*:*(.bss*)
+        *tfm_crypto*:*(COMMON)
+        . = ALIGN(32);
+    } > RAM AT> FLASH
+    Image$$TFM_SP_CRYPTO_DATA$$ZI$$Base = ADDR(.TFM_SP_CRYPTO_BSS);
+    Image$$TFM_SP_CRYPTO_DATA$$ZI$$Limit = ADDR(.TFM_SP_CRYPTO_BSS) + SIZEOF(.TFM_SP_CRYPTO_BSS);
+
+    .TFM_SP_CRYPTO_STACK : ALIGN(128)
+    {
+        . += 0x2000;
+    } > RAM AT> FLASH
+    Image$$TFM_SP_CRYPTO_STACK$$ZI$$Base = ADDR(.TFM_SP_CRYPTO_STACK);
+    Image$$TFM_SP_CRYPTO_STACK$$ZI$$Limit = ADDR(.TFM_SP_CRYPTO_STACK) + SIZEOF(.TFM_SP_CRYPTO_STACK);
+
 #ifdef TFM_PARTITION_TEST_CORE
     .TFM_SP_CORE_TEST_DATA : ALIGN(32)
     {
diff --git a/platform/ext/target/musca_a/partition/region_defs.h b/platform/ext/target/musca_a/partition/region_defs.h
index 013a76d..c8ad0b0 100755
--- a/platform/ext/target/musca_a/partition/region_defs.h
+++ b/platform/ext/target/musca_a/partition/region_defs.h
@@ -51,7 +51,7 @@
 #define IMAGE_CODE_SIZE \
             (FLASH_PARTITION_SIZE - BL2_HEADER_SIZE - BL2_TRAILER_SIZE)
 
-#define CMSE_VENEER_REGION_SIZE     (0x00000100)
+#define CMSE_VENEER_REGION_SIZE     (0x000001C0)
 
 /*
  * Since we enable/disable flash during s/ns code copy to code sram we cannot
diff --git a/secure_fw/CMakeLists.txt b/secure_fw/CMakeLists.txt
index c57e657..39b1897 100644
--- a/secure_fw/CMakeLists.txt
+++ b/secure_fw/CMakeLists.txt
@@ -118,8 +118,10 @@
 		embedded_set_target_link_defines(TARGET ${EXE_NAME} DEFINES "${flag}")
 	endforeach(flag)
 
+
 	embedded_set_target_linker_file(TARGET ${EXE_NAME} PATH "${S_SCATTER_FILE_NAME}")
 
+	add_dependencies(${EXE_NAME} tfm_crypto)
 	add_dependencies(${EXE_NAME} tfm_storage)
 	add_dependencies(${EXE_NAME} tfm_audit)
 	add_dependencies(${EXE_NAME} tfm_secure_tests)
@@ -131,16 +133,17 @@
 		#The test service veneers may not be referenced in the secure binary so the
 		#veneer objects are explicitly loaded from the secure tests library.
 		if(${COMPILER} STREQUAL "ARMCLANG")
-			target_link_libraries(${EXE_NAME} tfm_storage tfm_audit $<TARGET_LINKER_FILE:tfm_secure_tests>\(*veneers.o\) tfm_secure_tests)
+			target_link_libraries(${EXE_NAME} tfm_crypto tfm_storage tfm_audit $<TARGET_LINKER_FILE:tfm_secure_tests>\(*veneers.o\) tfm_secure_tests)
 		elseif(${COMPILER} STREQUAL "GNUARM")
-			target_link_libraries(${EXE_NAME} tfm_secure_tests tfm_storage tfm_audit)
+			target_link_libraries(${EXE_NAME} tfm_secure_tests tfm_crypto tfm_storage tfm_audit)
 		else()
 			message(FATAL_ERROR "unknown compiler" )
 		endif()
 	else()
-		target_link_libraries(${EXE_NAME} tfm_storage tfm_audit)
+		target_link_libraries(${EXE_NAME} tfm_crypto tfm_storage tfm_audit)
 	endif()
 
+
 	embedded_set_target_link_defines(TARGET ${EXE_NAME} DEFINES "TFM_LVL=${TFM_LVL}")
 
 	if (NOT DEFINED TFM_PARTITION_TEST_CORE)
@@ -223,6 +226,9 @@
 #Adds the test directory
 add_subdirectory(${TFM_ROOT_DIR}/test ${CMAKE_BINARY_DIR}/test)
 
+#Add the crypto library target
+add_subdirectory(${SECURE_FW_DIR}/services/crypto)
+
 #Add the secure storage library target
 add_subdirectory(${SECURE_FW_DIR}/services/secure_storage)
 
diff --git a/secure_fw/ns_callable/CMakeLists.inc b/secure_fw/ns_callable/CMakeLists.inc
index 70a071f..1a4a521 100644
--- a/secure_fw/ns_callable/CMakeLists.inc
+++ b/secure_fw/ns_callable/CMakeLists.inc
@@ -24,7 +24,8 @@
 endif()
 
 set (SS_NS_CALLABLE_C_SRC "${CMAKE_CURRENT_LIST_DIR}/tfm_sst_veneers.c"
-                          "${CMAKE_CURRENT_LIST_DIR}/tfm_audit_veneers.c")
+                          "${CMAKE_CURRENT_LIST_DIR}/tfm_audit_veneers.c"
+                          "${CMAKE_CURRENT_LIST_DIR}/tfm_crypto_veneers.c")
 
 #Append all our source files to global lists.
 list(APPEND ALL_SRC_C ${SS_NS_CALLABLE_C_SRC})
diff --git a/secure_fw/ns_callable/tfm_crypto_veneers.c b/secure_fw/ns_callable/tfm_crypto_veneers.c
new file mode 100644
index 0000000..b91f02c
--- /dev/null
+++ b/secure_fw/ns_callable/tfm_crypto_veneers.c
@@ -0,0 +1,113 @@
+/*
+ * Copyright (c) 2018, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#include "tfm_crypto_veneers.h"
+#include "secure_fw/services/crypto/tfm_crypto_api.h"
+#include "tfm_secure_api.h"
+#include "tfm_api.h"
+#include "spm_api.h"
+
+#include "psa_crypto.h"
+
+#include "crypto_psa_wrappers.h"
+
+__tfm_secure_gateway_attributes__
+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)
+{
+    TFM_CORE_SFN_REQUEST(TFM_SP_CRYPTO_ID, tfm_crypto_import_key,
+                         key, type, data, data_length);
+}
+
+__tfm_secure_gateway_attributes__
+enum tfm_crypto_err_t tfm_crypto_veneer_destroy_key(psa_key_slot_t key)
+{
+    TFM_CORE_SFN_REQUEST(TFM_SP_CRYPTO_ID, tfm_crypto_destroy_key,
+                         key, 0, 0, 0);
+}
+
+__tfm_secure_gateway_attributes__
+enum tfm_crypto_err_t tfm_crypto_veneer_get_key_information(
+                                                           psa_key_slot_t key,
+                                                           psa_key_type_t *type,
+                                                           size_t *bits)
+{
+    TFM_CORE_SFN_REQUEST(TFM_SP_CRYPTO_ID, tfm_crypto_get_key_information,
+                         key, type, bits, 0);
+}
+
+__tfm_secure_gateway_attributes__
+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)
+{
+    TFM_CORE_SFN_REQUEST(TFM_SP_CRYPTO_ID, tfm_crypto_export_key,
+                         key, data, data_size, data_length);
+}
+
+
+__tfm_secure_gateway_attributes__
+enum tfm_crypto_err_t tfm_crypto_veneer_encrypt_set_iv(
+                                              psa_cipher_operation_t *operation,
+                                              const unsigned char *iv,
+                                              size_t iv_length)
+{
+    TFM_CORE_SFN_REQUEST(TFM_SP_CRYPTO_ID, tfm_crypto_encrypt_set_iv,
+                         operation, iv, iv_length, 0);
+}
+
+__tfm_secure_gateway_attributes__
+enum tfm_crypto_err_t tfm_crypto_veneer_encrypt_setup(
+                                              psa_cipher_operation_t *operation,
+                                              psa_key_slot_t key,
+                                              psa_algorithm_t alg)
+{
+    TFM_CORE_SFN_REQUEST(TFM_SP_CRYPTO_ID, tfm_crypto_encrypt_setup,
+                         operation, key, alg, 0);
+}
+
+__tfm_secure_gateway_attributes__
+enum tfm_crypto_err_t tfm_crypto_veneer_decrypt_setup(
+                                              psa_cipher_operation_t *operation,
+                                              psa_key_slot_t key,
+                                              psa_algorithm_t alg)
+{
+    TFM_CORE_SFN_REQUEST(TFM_SP_CRYPTO_ID, tfm_crypto_decrypt_setup,
+                         operation, key, alg, 0);
+}
+
+__tfm_secure_gateway_attributes__
+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)
+{
+    TFM_CORE_SFN_REQUEST(TFM_SP_CRYPTO_ID, tfm_crypto_cipher_update_wrapper,
+                         operation, input_s, output_s, 0);
+}
+
+__tfm_secure_gateway_attributes__
+enum tfm_crypto_err_t tfm_crypto_veneer_cipher_abort(
+                                              psa_cipher_operation_t *operation)
+{
+    TFM_CORE_SFN_REQUEST(TFM_SP_CRYPTO_ID, tfm_crypto_cipher_abort,
+                         operation, 0, 0, 0);
+}
+
+__tfm_secure_gateway_attributes__
+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)
+{
+    TFM_CORE_SFN_REQUEST(TFM_SP_CRYPTO_ID, tfm_crypto_cipher_finish,
+                         operation, output, output_size, output_length);
+}
diff --git a/secure_fw/services/audit_logging/CMakeLists.txt b/secure_fw/services/audit_logging/CMakeLists.txt
index d864d47..b7849c7 100644
--- a/secure_fw/services/audit_logging/CMakeLists.txt
+++ b/secure_fw/services/audit_logging/CMakeLists.txt
@@ -28,7 +28,7 @@
 set (MBEDTLS_TARGET_NAME "mbedtls_log_lib")
 
 #Set mbedTLS compiler flags
-set(MBEDTLS_C_FLAGS ${MBEDTLS_C_FLAGS_SST_LOG})
+set(MBEDTLS_C_FLAGS ${MBEDTLS_C_FLAGS_SERVICES})
 
 ###Get the definition of what files we need to build
 set (ENABLE_AUDIT_LOGGING ON)
diff --git a/secure_fw/services/crypto/CMakeLists.inc b/secure_fw/services/crypto/CMakeLists.inc
new file mode 100644
index 0000000..cfaa709
--- /dev/null
+++ b/secure_fw/services/crypto/CMakeLists.inc
@@ -0,0 +1,57 @@
+#-------------------------------------------------------------------------------
+# Copyright (c) 2018, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#-------------------------------------------------------------------------------
+
+#Definitions to compile the "crypto" module.
+#This file assumes it will be included from a project specific cmakefile, and
+#will not create a library or executable.
+#Inputs:
+#       MBEDTLS_INSTALL_DIR - directory where mbed TLS headers and libraries can be found.
+#       TFM_ROOT_DIR        - root directory of the TF-M repository.
+#Outputs:
+#       Will modify include directories to make the source compile.
+#       ALL_SRC_C: C source files to be compiled will be added to this list. This shall be added to your add_executable or add_library command.
+#       ALL_SRC_CXX: C++ source files to be compiled will be added to this list. This shall be added to your add_executable or add_library command.
+#       ALL_SRC_ASM: assembly source files to be compiled will be added to this list. This shall be added to your add_executable or add_library command.
+#       Include directories will be modified by using the include_directories() commands as needed.
+
+#Get the current directory where this file is located.
+set(CRYPTO_DIR ${CMAKE_CURRENT_LIST_DIR})
+
+#Check input variables
+if (NOT DEFINED ENABLE_CRYPTO)
+  message(FATAL_ERROR "Incomplete build configuration: ENABLE_CRYPTO is undefined. ")
+endif()
+
+if (ENABLE_CRYPTO)
+  if (NOT DEFINED MBEDTLS_INSTALL_DIR)
+    message(FATAL_ERROR "Please set MBEDTLS_INSTALL_DIR before including this file.")
+  endif()
+
+  if (NOT DEFINED TFM_ROOT_DIR)
+    message(FATAL_ERROR "Please set TFM_ROOT_DIR before including this file.")
+  endif()
+
+  set (CRYPTO_C_SRC "${CRYPTO_DIR}/crypto_init.c"
+                    "${CRYPTO_DIR}/crypto_alloc.c"
+                    "${CRYPTO_DIR}/crypto_cipher.c"
+                    "${CRYPTO_DIR}/crypto_key.c"
+                    "${CRYPTO_DIR}/crypto_wrappers.c"
+                    "${CRYPTO_DIR}/crypto_utils.c"
+      )
+
+  #Append all our source files to global lists.
+  list(APPEND ALL_SRC_C ${CRYPTO_C_SRC})
+  unset(CRYPTO_C_SRC)
+
+  #Setting include directories
+  embedded_include_directories(PATH ${TFM_ROOT_DIR} ABSOLUTE)
+  embedded_include_directories(PATH ${TFM_ROOT_DIR}/interface/include ABSOLUTE)
+  embedded_include_directories(PATH ${MBEDTLS_INSTALL_DIR}/include ABSOLUTE)
+
+else()
+  message(FATAL_ERROR "Build system currently doesn't support selectively disabling of a service.")
+endif()
diff --git a/secure_fw/services/crypto/CMakeLists.txt b/secure_fw/services/crypto/CMakeLists.txt
new file mode 100644
index 0000000..8d42a5d
--- /dev/null
+++ b/secure_fw/services/crypto/CMakeLists.txt
@@ -0,0 +1,72 @@
+#-------------------------------------------------------------------------------
+# Copyright (c) 2018, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#-------------------------------------------------------------------------------
+
+cmake_minimum_required(VERSION 3.7)
+
+#Tell cmake where our modules can be found
+list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_LIST_DIR}/../../../cmake)
+
+#Include common stuff to control cmake.
+include("Common/BuildSys")
+
+#Start an embedded project.
+embedded_project_start(CONFIG "${CMAKE_CURRENT_LIST_DIR}/../../../ConfigDefault.cmake")
+project(tfm_crypto LANGUAGES ASM C)
+embedded_project_fixup()
+
+###Some project global settings
+set (CRYPTO_DIR "${CMAKE_CURRENT_LIST_DIR}")
+get_filename_component(TFM_ROOT_DIR "${CRYPTO_DIR}/../../.." ABSOLUTE)
+#Define location of mbed TLS source, build, and installation directory.
+get_filename_component(MBEDTLS_SOURCE_DIR "${TFM_ROOT_DIR}/../mbedtls" ABSOLUTE)
+set (MBEDTLS_BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}/mbedtls")
+set (MBEDTLS_INSTALL_DIR ${MBEDTLS_BINARY_DIR}/mbedtls_install)
+set (MBEDTLS_TARGET_NAME "mbedtls_crypto_lib")
+
+#Set mbed TLS compiler flags
+set(MBEDTLS_C_FLAGS ${MBEDTLS_C_FLAGS_SERVICES})
+
+###Get the definition of what files we need to build
+set (ENABLE_CRYPTO ON)
+include(CMakeLists.inc)
+
+###Configure how we build our target
+if(DEFINED CORE_TEST)
+  set (TFM_LVL 3)
+else()
+  set (TFM_LVL 1)
+endif()
+
+#Set build type for mbed TLS libraries
+if (MBEDTLS_DEBUG)
+  set(MBEDTLS_BUILD_TYPE "Debug")
+else()
+  set(MBEDTLS_BUILD_TYPE "Release")
+endif()
+
+#Set preinclude header options for mbed TLS
+set(MBEDTLS_PREINCLUDE_PREFIX __tfm_crypto__)
+set(MBEDTLS_PREINCLUDE_HEADER ${CRYPTO_DIR}/mbedtls_global_symbols.h)
+
+#Build mbed TLS as external project.
+#This ensures mbed TLS is built with exactly defined settings.
+#mbed TLS will be used from its install location
+include(${TFM_ROOT_DIR}/BuildMbedtls.cmake)
+
+#Specify what we build (for the crypto service, build as a static library)
+add_library(tfm_crypto STATIC ${ALL_SRC_ASM} ${ALL_SRC_C})
+embedded_set_target_compile_defines(TARGET tfm_crypto LANGUAGE C DEFINES __ARM_FEATURE_CMSE=3 __thumb2__ TFM_LVL=${TFM_LVL} MBEDTLS_CONFIG_FILE="platform/ext/common/tfm_mbedtls_config.h")
+#Add a dependency on the mbed_tls_lib_install target.
+add_dependencies(tfm_crypto ${MBEDTLS_TARGET_NAME}_install)
+#Ask the compiler to merge the mbed TLS and the secure storage libraries.
+compiler_merge_library(DEST tfm_crypto LIBS "${MBEDTLS_INSTALL_DIR}/lib/${CMAKE_STATIC_LIBRARY_PREFIX_C}mbedcrypto${CMAKE_STATIC_LIBRARY_SUFFIX_C}")
+
+#Set common compiler and linker flags
+config_setting_shared_compiler_flags(tfm_crypto)
+config_setting_shared_linker_flags(tfm_crypto)
+
+embedded_project_end(tfm_crypto)
diff --git a/secure_fw/services/crypto/crypto_alloc.c b/secure_fw/services/crypto/crypto_alloc.c
new file mode 100644
index 0000000..c7ffec3
--- /dev/null
+++ b/secure_fw/services/crypto/crypto_alloc.c
@@ -0,0 +1,141 @@
+/*
+ * Copyright (c) 2018, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#include <limits.h>
+
+#include "tfm_crypto_defs.h"
+
+/* Pre include Mbed TLS headers */
+#define LIB_PREFIX_NAME __tfm_crypto__
+#include "mbedtls_global_symbols.h"
+
+/* Include the Mbed TLS configuration file, the way Mbed TLS does it
+ * in each of its header files.
+ */
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "platform/ext/common/tfm_mbedtls_config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#include "psa_crypto.h"
+#include "tfm_crypto_api.h"
+
+/* The file "psa_crypto_struct.h" contains definitions for
+ * implementation-specific structs that are declared in "psa_crypto.h".
+ */
+#include "psa_crypto_struct.h"
+
+/**
+ * \brief This value defines the maximum number of simultaneous operations
+ *        supported by this implementation.
+ */
+#define TFM_CRYPTO_CONC_OPER_NUM (8)
+
+/**
+ * \brief This value is used to mark an handle as invalid.
+ *
+ */
+#define INVALID_HANDLE (0xFFFFFFFF)
+
+struct tfm_crypto_operation_s {
+    uint32_t in_use;                /*!< Indicates if the operation is in use */
+    enum tfm_crypto_operation_type type; /*!< Type of the operation */
+    union {
+        struct psa_cipher_operation_s cipher;   /*!< Cipher operation context */
+        struct psa_mac_operation_s mac;         /*!< MAC operation context */
+        struct psa_hash_operation_s hash;       /*!< Hash operation context */
+    } operation;
+};
+
+static struct tfm_crypto_operation_s operation[TFM_CRYPTO_CONC_OPER_NUM] ={{0}};
+
+static void memset_operation_context(uint32_t index)
+{
+    uint32_t i, mem_size;
+
+    volatile uint8_t *mem_ptr = (uint8_t *) &(operation[index].operation);
+
+    switch(operation[index].type) {
+    case TFM_CRYPTO_CIPHER_OPERATION:
+        mem_size = sizeof(struct psa_cipher_operation_s);
+        break;
+    case TFM_CRYPTO_MAC_OPERATION:
+        mem_size = sizeof(struct psa_mac_operation_s);
+        break;
+    case TFM_CRYPTO_HASH_OPERATION:
+        mem_size = sizeof(struct psa_hash_operation_s);
+        break;
+    case TFM_CRYPTO_OPERATION_NONE:
+    default:
+        mem_size = 0;
+        break;
+    }
+
+    for (i=0; i<mem_size; i++) {
+        mem_ptr[i] = 0;
+    }
+}
+
+/*!
+ * \defgroup public Public functions
+ *
+ */
+
+/*!@{*/
+enum tfm_crypto_err_t tfm_crypto_operation_alloc(
+                                        enum tfm_crypto_operation_type type,
+                                        uint32_t *handle)
+{
+    uint32_t i = 0;
+
+    for (i=0; i<TFM_CRYPTO_CONC_OPER_NUM; i++) {
+        if (operation[i].in_use == TFM_CRYPTO_NOT_IN_USE) {
+            operation[i].in_use = TFM_CRYPTO_IN_USE;
+            operation[i].type = type;
+            *handle = i;
+            return TFM_CRYPTO_ERR_PSA_SUCCESS;
+        }
+    }
+
+
+    return TFM_CRYPTO_ERR_PSA_ERROR_NOT_PERMITTED;
+}
+
+enum tfm_crypto_err_t tfm_crypto_operation_release(uint32_t *handle)
+{
+    uint32_t i = *handle;
+
+    if ( (i<TFM_CRYPTO_CONC_OPER_NUM) &&
+         (operation[i].in_use == TFM_CRYPTO_IN_USE) ) {
+        memset_operation_context(i);
+        operation[i].in_use = TFM_CRYPTO_NOT_IN_USE;
+        operation[i].type = TFM_CRYPTO_OPERATION_NONE;
+        *handle = INVALID_HANDLE;
+        return TFM_CRYPTO_ERR_PSA_SUCCESS;
+    }
+
+    return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
+}
+
+enum tfm_crypto_err_t tfm_crypto_operation_lookup(
+                                        enum tfm_crypto_operation_type type,
+                                        uint32_t *handle,
+                                        void **oper)
+{
+    uint32_t i = *handle;
+
+    if ( (i<TFM_CRYPTO_CONC_OPER_NUM) &&
+         (operation[i].in_use == TFM_CRYPTO_IN_USE) &&
+         (operation[i].type == type) ) {
+        *oper = (void *) &(operation[i].operation);
+        return TFM_CRYPTO_ERR_PSA_SUCCESS;
+    }
+
+    return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
+}
+/*!@}*/
diff --git a/secure_fw/services/crypto/crypto_cipher.c b/secure_fw/services/crypto/crypto_cipher.c
new file mode 100644
index 0000000..96980d2
--- /dev/null
+++ b/secure_fw/services/crypto/crypto_cipher.c
@@ -0,0 +1,471 @@
+/*
+ * Copyright (c) 2018, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#include <limits.h>
+
+#include "tfm_crypto_defs.h"
+
+/* Pre include Mbed TLS headers */
+#define LIB_PREFIX_NAME __tfm_crypto__
+#include "mbedtls_global_symbols.h"
+
+/* Include the Mbed TLS configuration file, the way Mbed TLS does it
+ * in each of its header files.
+ */
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "platform/ext/common/tfm_mbedtls_config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#include "psa_crypto.h"
+
+/* The file "psa_crypto_struct.h" contains definitions for
+ * implementation-specific structs that are declared in "psa_crypto.h".
+ */
+#include "psa_crypto_struct.h"
+
+#include "tfm_crypto_api.h"
+#include "crypto_utils.h"
+
+/**
+ * \brief For a TFM_CRYPTO_CIPHER_OPERATION, define the possible
+ *        modes of configuration.
+ *
+ */
+enum tfm_crypto_cipher_mode_t {
+   TFM_CRYPTO_CIPHER_MODE_DECRYPT = 0,
+   TFM_CRYPTO_CIPHER_MODE_ENCRYPT = 1,
+};
+
+static enum tfm_crypto_err_t tfm_crypto_cipher_setup(
+                                           psa_cipher_operation_t *handle,
+                                           psa_key_slot_t key,
+                                           psa_algorithm_t alg,
+                                           enum tfm_crypto_cipher_mode_t c_mode)
+{
+    const mbedtls_cipher_info_t *info = NULL;
+    psa_algorithm_t padding_mode = PSA_ALG_BLOCK_CIPHER_PAD_NONE;
+    psa_key_type_t key_type;
+    size_t key_size;
+    enum tfm_crypto_err_t err;
+    uint8_t key_data[TFM_CRYPTO_MAX_KEY_LENGTH];
+    uint32_t ret;
+    mbedtls_cipher_type_t type = MBEDTLS_CIPHER_NONE;
+    mbedtls_cipher_padding_t mbedtls_padding_mode = MBEDTLS_PADDING_NONE;
+
+    struct psa_cipher_operation_s *operation = NULL;
+
+    /* Validate pointers */
+    err = tfm_crypto_memory_check(handle,
+                                  sizeof(psa_cipher_operation_t),
+                                  TFM_MEMORY_ACCESS_RW);
+    if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
+        return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
+    }
+
+    if (!PSA_ALG_IS_CIPHER(alg)) {
+        return TFM_CRYPTO_ERR_PSA_ERROR_NOT_SUPPORTED;
+    }
+
+    /* FIXME: Check that key is compatible with alg */
+    err = tfm_crypto_get_key_information(key, &key_type, &key_size);
+    if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
+        return err;
+    }
+
+    err = tfm_crypto_export_key(key, &key_data[0], TFM_CRYPTO_MAX_KEY_LENGTH,
+                                                                     &key_size);
+    if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
+        return err;
+    }
+
+    /* Mbed TLS cipher setup */
+    if (PSA_BYTES_TO_BITS(key_size) == 128) {
+        if (alg == PSA_ALG_CBC_BASE) {
+            type = MBEDTLS_CIPHER_AES_128_CBC;
+        } else if (alg == PSA_ALG_CFB_BASE) {
+            if (c_mode == TFM_CRYPTO_CIPHER_MODE_ENCRYPT) {
+                type = MBEDTLS_CIPHER_AES_128_CFB128;
+            }
+        }
+    }
+
+    /* The requested alg/key/mode is not supported */
+    if (type == MBEDTLS_CIPHER_NONE) {
+        return TFM_CRYPTO_ERR_PSA_ERROR_NOT_SUPPORTED;
+    }
+
+    /* Allocate the operation context in the TFM space */
+    err = tfm_crypto_operation_alloc(TFM_CRYPTO_CIPHER_OPERATION, handle);
+    if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
+        return err;
+    }
+
+
+
+    /* Look up the corresponding operation context */
+    err = tfm_crypto_operation_lookup(TFM_CRYPTO_CIPHER_OPERATION,
+                                      handle,
+                                      (void **)&operation);
+
+    if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
+        return err;
+    }
+
+    /* Bind the algorithm to the cipher operation */
+    operation->alg = alg;
+
+    /* Mbed TLS cipher init */
+    mbedtls_cipher_init(&(operation->ctx.cipher));
+    info = mbedtls_cipher_info_from_type(type);
+    ret = mbedtls_cipher_setup(&(operation->ctx.cipher), info);
+    if (ret != 0) {
+        /* Release the operation context */
+        tfm_crypto_operation_release(handle);
+        return TFM_CRYPTO_ERR_PSA_ERROR_COMMUNICATION_FAILURE;
+    }
+
+    /* FIXME: Check based on the algorithm, if we need to have an IV */
+    operation->iv_required = 1;
+
+    /* Bind the key to the cipher operation */
+    operation->key = key;
+    operation->key_set = 1;
+
+    /* Mbed TLS cipher set key */
+    if (c_mode == TFM_CRYPTO_CIPHER_MODE_ENCRYPT) {
+
+        ret = mbedtls_cipher_setkey(&(operation->ctx.cipher),
+                                    &key_data[0],
+                                    PSA_BYTES_TO_BITS(key_size),
+                                    MBEDTLS_ENCRYPT);
+
+    } else if (c_mode == TFM_CRYPTO_CIPHER_MODE_DECRYPT) {
+
+        ret = mbedtls_cipher_setkey(&(operation->ctx.cipher),
+                                    &key_data[0],
+                                    PSA_BYTES_TO_BITS(key_size),
+                                    MBEDTLS_DECRYPT);
+    } else {
+        /* Release the operation context */
+        tfm_crypto_operation_release(handle);
+        return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
+    }
+
+    if (ret != 0) {
+        /* Release the operation context */
+        tfm_crypto_operation_release(handle);
+        return TFM_CRYPTO_ERR_PSA_ERROR_COMMUNICATION_FAILURE;
+    }
+
+    /* Mbed TLS cipher set padding mode in case of CBC */
+    if ((alg & ~PSA_ALG_BLOCK_CIPHER_PADDING_MASK) == PSA_ALG_CBC_BASE) {
+
+        /* Check the value of padding field */
+        padding_mode = alg & PSA_ALG_BLOCK_CIPHER_PADDING_MASK;
+
+        switch (padding_mode) {
+        case PSA_ALG_BLOCK_CIPHER_PAD_PKCS7:
+            mbedtls_padding_mode = MBEDTLS_PADDING_PKCS7;
+            break;
+        case PSA_ALG_BLOCK_CIPHER_PAD_NONE:
+            mbedtls_padding_mode = MBEDTLS_PADDING_NONE;
+            break;
+        default:
+            return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
+        }
+
+        ret = mbedtls_cipher_set_padding_mode(&(operation->ctx.cipher),
+                                              mbedtls_padding_mode);
+        if (ret != 0) {
+            /* Release the operation context */
+            tfm_crypto_operation_release(handle);
+            return TFM_CRYPTO_ERR_PSA_ERROR_COMMUNICATION_FAILURE;
+        }
+    }
+
+    return TFM_CRYPTO_ERR_PSA_SUCCESS;
+}
+
+/*!
+ * \defgroup public_psa Public functions, PSA
+ *
+ */
+
+/*!@{*/
+enum tfm_crypto_err_t tfm_crypto_encrypt_set_iv(
+                                              psa_cipher_operation_t *handle,
+                                              const unsigned char *iv,
+                                              size_t iv_length)
+{
+    int ret;
+    enum tfm_crypto_err_t err;
+    struct psa_cipher_operation_s *operation = NULL;
+
+    /* Validate pointers */
+    err = tfm_crypto_memory_check(handle,
+                                  sizeof(psa_cipher_operation_t),
+                                  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 *)iv, iv_length, TFM_MEMORY_ACCESS_RO);
+    if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
+        return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
+    }
+
+    /* Look up the corresponding operation context */
+    err = tfm_crypto_operation_lookup(TFM_CRYPTO_CIPHER_OPERATION,
+                                      handle,
+                                      (void **)&operation);
+
+    if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
+        return err;
+    }
+
+    if (operation->iv_required == 0) {
+        /* Release the operation context */
+        tfm_crypto_operation_release(handle);
+        return TFM_CRYPTO_ERR_PSA_ERROR_NOT_PERMITTED;
+    }
+
+    if (iv_length > PSA_CIPHER_IV_MAX_SIZE) {
+        /* Release the operation context */
+        tfm_crypto_operation_release(handle);
+        return TFM_CRYPTO_ERR_PSA_ERROR_NOT_SUPPORTED;
+    }
+
+    /* Bind the IV to the cipher operation */
+    ret = mbedtls_cipher_set_iv(&(operation->ctx.cipher), iv, iv_length);
+    if (ret != 0) {
+        /* Release the operation context */
+        tfm_crypto_operation_release(handle);
+        return TFM_CRYPTO_ERR_PSA_ERROR_COMMUNICATION_FAILURE;
+    }
+    operation->iv_set = 1;
+    operation->iv_size = iv_length;
+
+    /* Reset the context after IV is set */
+    ret = mbedtls_cipher_reset(&(operation->ctx.cipher));
+    if (ret != 0) {
+        /* Release the operation context */
+        tfm_crypto_operation_release(handle);
+        return TFM_CRYPTO_ERR_PSA_ERROR_COMMUNICATION_FAILURE;
+    }
+
+    return TFM_CRYPTO_ERR_PSA_SUCCESS;
+}
+
+enum tfm_crypto_err_t tfm_crypto_encrypt_setup(
+                                              psa_cipher_operation_t *handle,
+                                              psa_key_slot_t key,
+                                              psa_algorithm_t alg)
+{
+    return tfm_crypto_cipher_setup(handle,
+                                   key,
+                                   alg,
+                                   TFM_CRYPTO_CIPHER_MODE_ENCRYPT);
+}
+
+enum tfm_crypto_err_t tfm_crypto_decrypt_setup(
+                                              psa_cipher_operation_t *handle,
+                                              psa_key_slot_t key,
+                                              psa_algorithm_t alg)
+{
+    return tfm_crypto_cipher_setup(handle,
+                                   key,
+                                   alg,
+                                   TFM_CRYPTO_CIPHER_MODE_DECRYPT);
+}
+
+enum tfm_crypto_err_t tfm_crypto_cipher_update(
+                                              psa_cipher_operation_t *handle,
+                                              const uint8_t *input,
+                                              size_t input_length,
+                                              unsigned char *output,
+                                              size_t output_size,
+                                              size_t *output_length)
+{
+    int ret;
+    enum tfm_crypto_err_t err;
+    size_t olen;
+    struct psa_cipher_operation_s *operation = NULL;
+
+    /* Validate pointers */
+    err = tfm_crypto_memory_check(handle,
+                                  sizeof(psa_cipher_operation_t),
+                                  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 *)input,
+                                  input_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(output,
+                                  output_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(output_length,
+                                  sizeof(size_t),
+                                  TFM_MEMORY_ACCESS_RW);
+    if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
+        return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
+    }
+
+    /* Look up the corresponding operation context */
+    err = tfm_crypto_operation_lookup(TFM_CRYPTO_CIPHER_OPERATION,
+                                      handle,
+                                      (void **)&operation);
+
+    if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
+        return err;
+    }
+
+    /* If the IV is required and it's not been set yet */
+    if ((operation->iv_required == 1) && (operation->iv_set == 0)) {
+
+        if (operation->ctx.cipher.operation != MBEDTLS_DECRYPT) {
+            /* Release the operation context */
+            tfm_crypto_operation_release(handle);
+            return TFM_CRYPTO_ERR_PSA_ERROR_BAD_STATE;
+        }
+
+        /* This call is used to set the IV on the object */
+        err = tfm_crypto_encrypt_set_iv(handle, input, input_length);
+
+        *output_length = 0;
+
+        return err;
+    }
+
+    /* If the key is not set, setup phase has not been completed */
+    if (operation->key_set == 0) {
+        /* Release the operation context */
+        tfm_crypto_operation_release(handle);
+        return TFM_CRYPTO_ERR_PSA_ERROR_BAD_STATE;
+    }
+
+    *output_length = 0;
+
+    ret = mbedtls_cipher_update(&(operation->ctx.cipher), input, input_length,
+                                output, &olen);
+
+    if ((ret != 0) || (olen == 0)) {
+        /* Release the operation context */
+        tfm_crypto_operation_release(handle);
+        return TFM_CRYPTO_ERR_PSA_ERROR_COMMUNICATION_FAILURE;
+    }
+
+    /* Assign the output buffer length */
+    *output_length = olen;
+
+    return TFM_CRYPTO_ERR_PSA_SUCCESS;
+}
+
+enum tfm_crypto_err_t tfm_crypto_cipher_finish(
+                                              psa_cipher_operation_t *handle,
+                                              uint8_t *output,
+                                              size_t output_size,
+                                              size_t *output_length)
+{
+    int ret;
+    enum tfm_crypto_err_t err;
+    size_t olen;
+    struct psa_cipher_operation_s *operation = NULL;
+
+    /* Validate pointers */
+    err = tfm_crypto_memory_check(handle,
+                                  sizeof(psa_cipher_operation_t),
+                                  TFM_MEMORY_ACCESS_RW);
+    if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
+        return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
+    }
+    err = tfm_crypto_memory_check(output,
+                                  output_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(output_length,
+                                  sizeof(size_t),
+                                  TFM_MEMORY_ACCESS_RW);
+    if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
+        return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
+    }
+
+    *output_length = 0;
+
+    /* Look up the corresponding operation context */
+    err = tfm_crypto_operation_lookup(TFM_CRYPTO_CIPHER_OPERATION,
+                                      handle,
+                                      (void **)&operation);
+
+    if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
+        return err;
+    }
+
+    ret = mbedtls_cipher_finish(&(operation->ctx.cipher), output, &olen);
+    if (ret != 0) {
+        /* Release the operation context */
+        tfm_crypto_operation_release(handle);
+        return TFM_CRYPTO_ERR_PSA_ERROR_COMMUNICATION_FAILURE;
+    }
+
+    *output_length = olen;
+
+    /* Clear the Mbed TLS context */
+    mbedtls_cipher_free(&(operation->ctx.cipher));
+
+    /* Release the operation context */
+    err = tfm_crypto_operation_release(handle);
+    if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
+        return err;
+    }
+
+    return TFM_CRYPTO_ERR_PSA_SUCCESS;
+}
+
+enum tfm_crypto_err_t tfm_crypto_cipher_abort(psa_cipher_operation_t *handle)
+{
+    enum tfm_crypto_err_t err;
+    struct psa_cipher_operation_s *operation = NULL;
+
+    /* Validate pointers */
+    err = tfm_crypto_memory_check(handle,
+                                  sizeof(psa_cipher_operation_t),
+                                  TFM_MEMORY_ACCESS_RW);
+    if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
+        return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
+    }
+
+    /* Look up the corresponding operation context */
+    err = tfm_crypto_operation_lookup(TFM_CRYPTO_CIPHER_OPERATION,
+                                      handle,
+                                      (void **)&operation);
+
+    if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
+        return err;
+    }
+
+    /* Clear the Mbed TLS context */
+    mbedtls_cipher_free(&(operation->ctx.cipher));
+
+    /* Release the operation context */
+    err = tfm_crypto_operation_release(handle);
+    if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
+        return err;
+    }
+
+    return TFM_CRYPTO_ERR_PSA_SUCCESS;
+}
+/*!@}*/
diff --git a/secure_fw/services/crypto/crypto_init.c b/secure_fw/services/crypto/crypto_init.c
new file mode 100644
index 0000000..4243466
--- /dev/null
+++ b/secure_fw/services/crypto/crypto_init.c
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2018, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#include "tfm_crypto_defs.h"
+#include "tfm_crypto_api.h"
+
+/* Pre include Mbed TLS headers */
+#define LIB_PREFIX_NAME __tfm_crypto__
+#include "mbedtls_global_symbols.h"
+
+/* Include the Mbed TLS configuration file, the way Mbed TLS does it
+ * in each of its header files.
+ */
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "platform/ext/common/tfm_mbedtls_config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#include "mbedtls/memory_buffer_alloc.h"
+
+/**
+ * \brief Buffer size used by Mbed TLS for its allocations
+ */
+#define TFM_CRYPTO_MBEDTLS_MEM_BUF_LEN (1024)
+
+/**
+ * \brief Static buffer to be used by Mbed TLS for memory allocations
+ *
+ */
+static uint8_t mbedtls_mem_buf[TFM_CRYPTO_MBEDTLS_MEM_BUF_LEN] = {0};
+
+enum tfm_crypto_err_t tfm_crypto_init(void)
+{
+    /* Initialise everything that is needed */
+
+    /* Initialise the Mbed TLS static memory allocator so that Mbed TLS
+     * allocates memory from the provided static buffer instead of from
+     * the heap.
+     */
+    mbedtls_memory_buffer_alloc_init(mbedtls_mem_buf,
+                                     TFM_CRYPTO_MBEDTLS_MEM_BUF_LEN);
+
+    return TFM_CRYPTO_ERR_PSA_SUCCESS;
+}
diff --git a/secure_fw/services/crypto/crypto_key.c b/secure_fw/services/crypto/crypto_key.c
new file mode 100644
index 0000000..18ca931
--- /dev/null
+++ b/secure_fw/services/crypto/crypto_key.c
@@ -0,0 +1,162 @@
+/*
+ * Copyright (c) 2018, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#include <limits.h>
+
+#include "tfm_crypto_defs.h"
+
+/* Pre include Mbed TLS headers */
+#define LIB_PREFIX_NAME __tfm_crypto__
+#include "mbedtls_global_symbols.h"
+
+/* Include the Mbed TLS configuration file, the way Mbed TLS does it
+ * in each of its header files.
+ */
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "platform/ext/common/tfm_mbedtls_config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#include "psa_crypto.h"
+
+/* The file "psa_crypto_struct.h" contains definitions for
+ * implementation-specific structs that are declared in "psa_crypto.h".
+ */
+#include "psa_crypto_struct.h"
+
+/**
+ * \brief This value defines the maximum number of simultaneous key stores
+ *        supported by this implementation.
+ */
+#define TFM_CRYPTO_KEY_STORAGE_NUM (4)
+
+struct tfm_crypto_key_storage_s {
+    uint8_t in_use;                 /*!< Indicates if the key store is in use */
+    psa_key_type_t type;            /*!< Type of the key stored */
+    size_t data_length;             /*!< Length of the key stored */
+    uint8_t data[TFM_CRYPTO_MAX_KEY_LENGTH]; /*!< Buffer containining the key */
+};
+
+static struct tfm_crypto_key_storage_s
+                                key_storage[TFM_CRYPTO_KEY_STORAGE_NUM] = {{0}};
+/*!
+ * \defgroup public Public functions
+ *
+ */
+
+/*!@{*/
+enum tfm_crypto_err_t tfm_crypto_import_key(psa_key_slot_t key,
+                                            psa_key_type_t type,
+                                            const uint8_t *data,
+                                            size_t data_length)
+{
+    size_t i;
+
+    if (key >= TFM_CRYPTO_KEY_STORAGE_NUM) {
+        return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
+    }
+
+    if (key_storage[key].in_use != TFM_CRYPTO_NOT_IN_USE) {
+        return TFM_CRYPTO_ERR_PSA_ERROR_OCCUPIED_SLOT;
+    }
+
+    if (data_length > TFM_CRYPTO_MAX_KEY_LENGTH) {
+        return TFM_CRYPTO_ERR_PSA_ERROR_NOT_SUPPORTED;
+    }
+
+    key_storage[key].in_use = TFM_CRYPTO_IN_USE;
+    key_storage[key].type = type;
+
+    for (i=0; i<data_length; i++) {
+        key_storage[key].data[i] = data[i];
+    }
+
+    key_storage[key].data_length = data_length;
+
+
+    return TFM_CRYPTO_ERR_PSA_SUCCESS;
+}
+
+enum tfm_crypto_err_t tfm_crypto_destroy_key(psa_key_slot_t key)
+{
+    uint32_t i;
+
+    if (key >= TFM_CRYPTO_KEY_STORAGE_NUM) {
+        return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
+    }
+
+    volatile uint8_t *p_mem = (uint8_t *) &(key_storage[key]);
+    uint32_t size_mem = sizeof(struct tfm_crypto_key_storage_s);
+
+    /* memset the key_storage */
+    for (i=0; i<size_mem; i++) {
+        p_mem[i] = 0;
+    }
+
+    /* Set default values */
+    key_storage[key].in_use = TFM_CRYPTO_NOT_IN_USE;
+
+    return TFM_CRYPTO_ERR_PSA_SUCCESS;
+}
+
+enum tfm_crypto_err_t tfm_crypto_get_key_information(psa_key_slot_t key,
+                                                     psa_key_type_t *type,
+                                                     size_t *bits)
+{
+    if (key >= TFM_CRYPTO_KEY_STORAGE_NUM) {
+        return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
+    }
+
+    if (key_storage[key].in_use == TFM_CRYPTO_NOT_IN_USE) {
+        return TFM_CRYPTO_ERR_PSA_ERROR_EMPTY_SLOT;
+    }
+
+    /* Get basic metadata */
+    *type = key_storage[key].type;
+    *bits = PSA_BYTES_TO_BITS(key_storage[key].data_length);
+
+    return TFM_CRYPTO_ERR_PSA_SUCCESS;
+}
+
+enum tfm_crypto_err_t tfm_crypto_export_key(psa_key_slot_t key,
+                                            uint8_t *data,
+                                            size_t data_size,
+                                            size_t *data_length)
+{
+    size_t i;
+
+    if (key >= TFM_CRYPTO_KEY_STORAGE_NUM) {
+        return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
+    }
+
+    if (key_storage[key].in_use == TFM_CRYPTO_NOT_IN_USE) {
+        return TFM_CRYPTO_ERR_PSA_ERROR_EMPTY_SLOT;
+    }
+
+    if (key_storage[key].data_length > data_size) {
+        return TFM_CRYPTO_ERR_PSA_ERROR_NOT_SUPPORTED;
+    }
+
+    for (i=0; i<key_storage[key].data_length; i++) {
+        data[i] = key_storage[key].data[i];
+    }
+
+    *data_length = key_storage[key].data_length;
+
+    return TFM_CRYPTO_ERR_PSA_SUCCESS;
+}
+
+enum tfm_crypto_err_t tfm_crypto_export_public_key(psa_key_slot_t key,
+                                                   uint8_t *data,
+                                                   size_t data_size,
+                                                   size_t *data_length)
+{
+    /* FIXME: This API is not supported yet */
+    return TFM_CRYPTO_ERR_PSA_ERROR_NOT_SUPPORTED;
+}
+/*!@}*/
diff --git a/secure_fw/services/crypto/crypto_utils.c b/secure_fw/services/crypto/crypto_utils.c
new file mode 100644
index 0000000..e318f17
--- /dev/null
+++ b/secure_fw/services/crypto/crypto_utils.c
@@ -0,0 +1,17 @@
+/*
+ * Copyright (c) 2018, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#include <stdint.h>
+#include "tfm_crypto_defs.h"
+#include "tfm_secure_api.h"
+
+enum tfm_crypto_err_t tfm_crypto_memory_check(void *addr,
+                                              uint32_t size,                                
+                                              uint32_t access)
+{
+    return tfm_core_memory_permission_check(addr, size, access);
+}
diff --git a/secure_fw/services/crypto/crypto_utils.h b/secure_fw/services/crypto/crypto_utils.h
new file mode 100644
index 0000000..afab51e
--- /dev/null
+++ b/secure_fw/services/crypto/crypto_utils.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2018, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef __TFM_CRYPTO_UTILS_H__
+#define __TFM_CRYPTO_UTILS_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "tfm_secure_api.h"
+
+/**
+ * \brief Checks that a given type of access on a memory address with a
+ *        a given size is allowed
+ *
+ * \param[in] addr   Base address to be checked
+ * \param[in] size   Size of the buffer to checked
+ * \param[in] access Type of access (1: READ ONLY, 2: READ/WRITE)
+ *
+ * \return Returns values as described in \ref tfm_crypto_err_t
+ */
+enum tfm_crypto_err_t tfm_crypto_memory_check(void *addr,
+                                              uint32_t size,                                
+                                              uint32_t access);
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __TFM_CRYPTO_UTILS_H__ */
diff --git a/secure_fw/services/crypto/crypto_wrappers.c b/secure_fw/services/crypto/crypto_wrappers.c
new file mode 100644
index 0000000..cb68600
--- /dev/null
+++ b/secure_fw/services/crypto/crypto_wrappers.c
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2018, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+#include "tfm_crypto_defs.h"
+
+#include "psa_crypto.h"
+
+#include "crypto_psa_wrappers.h"
+
+#include "tfm_crypto_api.h"
+
+/*!
+ * \defgroup public Public functions, TF-M compatible wrappers
+ *
+ */
+
+/*!@{*/
+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)
+{
+    /* Extract the following fields from the input and output structures */
+
+    const uint8_t *input = input_s->input;
+    size_t input_length = input_s->input_length;
+
+    unsigned char *output = output_s->output;
+    size_t output_size = output_s->output_size;
+    size_t *output_length = output_s->output_length;
+
+    return tfm_crypto_cipher_update(operation, input, input_length,
+                                    output, output_size, output_length);
+}
+/*!@}*/
diff --git a/secure_fw/services/crypto/manifest.yaml b/secure_fw/services/crypto/manifest.yaml
new file mode 100644
index 0000000..8f222b6
--- /dev/null
+++ b/secure_fw/services/crypto/manifest.yaml
@@ -0,0 +1,138 @@
+#-------------------------------------------------------------------------------
+# Copyright (c) 2018, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#-------------------------------------------------------------------------------
+
+{
+  "name": "CRYPTO",
+  "type": "TRUSTED",
+  "tfm_partition_name": "TFM_SP_CRYPTO",
+  "tfm_trusted": true,
+  "priority": "NORMAL",
+  "id": "0x00000102",
+  "entry_point": "main",
+  "stack_size": "0x2000",
+  "heap_size": "0x0400",
+  "tfm_init_symbol": "tfm_crypto_init",
+  "secure_functions": [
+    {
+      "sfid": "TFM_CRYPTO_ALLOC_OPERATION_SFID",
+      "signal": "TFM_CRYPTO_ALLOC_OPERATION",
+      "tfm_symbol": "tfm_crypto_alloc_operation",
+      "non_secure_clients": true,
+      "minor_version": 1,
+      "minor_policy": "strict"
+    },
+    {
+      "sfid": "TFM_CRYPTO_CHECK_OPERATION_SFID",
+      "signal": "TFM_CRYPTO_CHECK_OPERATION",
+      "tfm_symbol": "tfm_crypto_check_operation",
+      "non_secure_clients": true,
+      "minor_version": 1,
+      "minor_policy": "strict"
+    },
+    {
+      "sfid": "TFM_CRYPTO_RELEASE_OPERATION_SFID",
+      "signal": "TFM_CRYPTO_RELEASE_OPERATION",
+      "tfm_symbol": "tfm_crypto_release_operation",
+      "non_secure_clients": true,
+      "minor_version": 1,
+      "minor_policy": "strict"
+    },
+    {
+      "sfid": "TFM_CRYPTO_IMPORT_KEY_SFID",
+      "signal": "TFM_CRYPTO_IMPORT_KEY",
+      "tfm_symbol": "tfm_crypto_import_key",
+      "non_secure_clients": true,
+      "minor_version": 1,
+      "minor_policy": "strict"
+    },
+    {
+      "sfid": "TFM_CRYPTO_DESTROY_KEY_SFID",
+      "signal": "TFM_CRYPTO_DESTROY_KEY",
+      "tfm_symbol": "tfm_crypto_destroy_key",
+      "non_secure_clients": true,
+      "minor_version": 1,
+      "minor_policy": "strict"
+    },
+    {
+      "sfid": "TFM_CRYPTO_GET_KEY_INFORMATION_SFID",
+      "signal": "TFM_CRYPTO_GET_KEY_INFORMATION",
+      "tfm_symbol": "tfm_crypto_get_key_information",
+      "non_secure_clients": true,
+      "minor_version": 1,
+      "minor_policy": "strict"
+    },
+    {
+      "sfid": "TFM_CRYPTO_EXPORT_KEY_SFID",
+      "signal": "TFM_CRYPTO_EXPORT_KEY",
+      "tfm_symbol": "tfm_crypto_export_key",
+      "non_secure_clients": true,
+      "minor_version": 1,
+      "minor_policy": "strict"
+    },
+    {
+      "sfid": "TFM_CRYPTO_ENCRYPT_SET_IV_SFID",
+      "signal": "TFM_CRYPTO_ENCRYPT_SET_IV",
+      "tfm_symbol": "tfm_crypto_encrypt_set_iv",
+      "non_secure_clients": true,
+      "minor_version": 1,
+      "minor_policy": "strict"
+    },
+    {
+      "sfid": "TFM_CRYPTO_ENCRYPT_SETUP_SFID",
+      "signal": "TFM_CRYPTO_ENCRYPT_SETUP",
+      "tfm_symbol": "tfm_crypto_encrypt_setup",
+      "non_secure_clients": true,
+      "minor_version": 1,
+      "minor_policy": "strict"
+    },
+    {
+      "sfid": "TFM_CRYPTO_DECRYPT_SETUP_SFID",
+      "signal": "TFM_CRYPTO_DECRYPT_SETUP",
+      "tfm_symbol": "tfm_crypto_decrypt_setup",
+      "non_secure_clients": true,
+      "minor_version": 1,
+      "minor_policy": "strict"
+    },
+    {
+      "sfid": "TFM_CRYPTO_CIPHER_UPDATE_SFID",
+      "signal": "TFM_CRYPTO_CIPHER_UPDATE",
+      "tfm_symbol": "tfm_crypto_cipher_update_wrapper",
+      "non_secure_clients": true,
+      "minor_version": 1,
+      "minor_policy": "strict"
+    },
+    {
+      "sfid": "TFM_CRYPTO_CIPHER_ABORT_SFID",
+      "signal": "TFM_CRYPTO_CIPHER_ABORT",
+      "tfm_symbol": "tfm_crypto_cipher_abort",
+      "non_secure_clients": true,
+      "minor_version": 1,
+      "minor_policy": "strict"
+    },
+    {
+      "sfid": "TFM_CRYPTO_CIPHER_FINISH_SFID",
+      "signal": "TFM_CRYPTO_CIPHER_FINISH",
+      "tfm_symbol": "tfm_crypto_cipher_finish",
+      "non_secure_clients": true,
+      "minor_version": 1,
+      "minor_policy": "strict"
+    }
+  ],
+  "source_files": [
+    "crypto_alloc.c",
+    "crypto_cipher.c",
+    "crypto_key.c",
+    "crypto_init.c",
+    "crypto_wrappers.c",
+    "crypto_utils.c",
+  ],
+  "tfm_linker_pattern": [
+    "library_list": [
+      "*tfm_crypto*"
+    ]
+  ]
+}
diff --git a/secure_fw/services/crypto/mbedtls_global_symbols.h b/secure_fw/services/crypto/mbedtls_global_symbols.h
new file mode 100644
index 0000000..b48b5ad
--- /dev/null
+++ b/secure_fw/services/crypto/mbedtls_global_symbols.h
@@ -0,0 +1,874 @@
+/*
+ * Copyright (c) 2018, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef __MBEDTLS_GLOBAL_SYMBOLS_H__
+#define __MBEDTLS_GLOBAL_SYMBOLS_H__
+
+#ifndef LIB_PREFIX_NAME
+#warning "LIB_PREFIX_NAME is undefined!!!"
+#define LIB_PREFIX_NAME
+#endif
+
+#define _CONCAT(A,B) A##B
+#define CONCAT(A,B) _CONCAT(A,B)
+
+#define mbedtls_aes_crypt_cbc \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_aes_crypt_cbc)
+#define mbedtls_aes_crypt_cfb128 \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_aes_crypt_cfb128)
+#define mbedtls_aes_crypt_cfb8 \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_aes_crypt_cfb8)
+#define mbedtls_aes_crypt_ctr \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_aes_crypt_ctr)
+#define mbedtls_aes_crypt_ecb \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_aes_crypt_ecb)
+#define mbedtls_aes_decrypt \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_aes_decrypt)
+#define mbedtls_aes_encrypt \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_aes_encrypt)
+#define mbedtls_aes_free \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_aes_free)
+#define mbedtls_aes_init \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_aes_init)
+#define mbedtls_aes_self_test \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_aes_self_test)
+#define mbedtls_aes_setkey_dec \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_aes_setkey_dec)
+#define mbedtls_aes_setkey_enc \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_aes_setkey_enc)
+#define mbedtls_arc4_crypt \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_arc4_crypt)
+#define mbedtls_arc4_free \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_arc4_free)
+#define mbedtls_arc4_init \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_arc4_init)
+#define mbedtls_arc4_self_test \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_arc4_self_test)
+#define mbedtls_arc4_setup \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_arc4_setup)
+#define mbedtls_asn1_find_named_data \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_asn1_find_named_data)
+#define mbedtls_asn1_free_named_data \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_asn1_free_named_data)
+#define mbedtls_asn1_free_named_data_list \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_asn1_free_named_data_list)
+#define mbedtls_asn1_get_alg \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_asn1_get_alg)
+#define mbedtls_asn1_get_alg_null \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_asn1_get_alg_null)
+#define mbedtls_asn1_get_bitstring \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_asn1_get_bitstring)
+#define mbedtls_asn1_get_bitstring_null \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_asn1_get_bitstring_null)
+#define mbedtls_asn1_get_bool \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_asn1_get_bool)
+#define mbedtls_asn1_get_int \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_asn1_get_int)
+#define mbedtls_asn1_get_len \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_asn1_get_len)
+#define mbedtls_asn1_get_mpi \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_asn1_get_mpi)
+#define mbedtls_asn1_get_sequence_of \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_asn1_get_sequence_of)
+#define mbedtls_asn1_get_tag \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_asn1_get_tag)
+#define mbedtls_asn1_store_named_data \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_asn1_store_named_data)
+#define mbedtls_asn1_write_algorithm_identifier \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_asn1_write_algorithm_identifier)
+#define mbedtls_asn1_write_bitstring \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_asn1_write_bitstring)
+#define mbedtls_asn1_write_bool \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_asn1_write_bool)
+#define mbedtls_asn1_write_ia5_string \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_asn1_write_ia5_string)
+#define mbedtls_asn1_write_int \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_asn1_write_int)
+#define mbedtls_asn1_write_len \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_asn1_write_len)
+#define mbedtls_asn1_write_mpi \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_asn1_write_mpi)
+#define mbedtls_asn1_write_null \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_asn1_write_null)
+#define mbedtls_asn1_write_octet_string \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_asn1_write_octet_string)
+#define mbedtls_asn1_write_oid \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_asn1_write_oid)
+#define mbedtls_asn1_write_printable_string \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_asn1_write_printable_string)
+#define mbedtls_asn1_write_raw_buffer \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_asn1_write_raw_buffer)
+#define mbedtls_asn1_write_tag \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_asn1_write_tag)
+#define mbedtls_base64_decode \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_base64_decode)
+#define mbedtls_base64_encode \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_base64_encode)
+#define mbedtls_base64_self_test \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_base64_self_test)
+#define mbedtls_blowfish_crypt_cbc \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_blowfish_crypt_cbc)
+#define mbedtls_blowfish_crypt_cfb64 \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_blowfish_crypt_cfb64)
+#define mbedtls_blowfish_crypt_ctr \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_blowfish_crypt_ctr)
+#define mbedtls_blowfish_crypt_ecb \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_blowfish_crypt_ecb)
+#define mbedtls_blowfish_free \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_blowfish_free)
+#define mbedtls_blowfish_init \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_blowfish_init)
+#define mbedtls_blowfish_setkey \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_blowfish_setkey)
+#define mbedtls_calloc \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_calloc)
+#define mbedtls_camellia_crypt_cbc \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_camellia_crypt_cbc)
+#define mbedtls_camellia_crypt_cfb128 \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_camellia_crypt_cfb128)
+#define mbedtls_camellia_crypt_ctr \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_camellia_crypt_ctr)
+#define mbedtls_camellia_crypt_ecb \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_camellia_crypt_ecb)
+#define mbedtls_camellia_free \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_camellia_free)
+#define mbedtls_camellia_init \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_camellia_init)
+#define mbedtls_camellia_self_test \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_camellia_self_test)
+#define mbedtls_camellia_setkey_dec \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_camellia_setkey_dec)
+#define mbedtls_camellia_setkey_enc \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_camellia_setkey_enc)
+#define mbedtls_ccm_auth_decrypt \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_ccm_auth_decrypt)
+#define mbedtls_ccm_encrypt_and_tag \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_ccm_encrypt_and_tag)
+#define mbedtls_ccm_free \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_ccm_free)
+#define mbedtls_ccm_init \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_ccm_init)
+#define mbedtls_ccm_self_test \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_ccm_self_test)
+#define mbedtls_ccm_setkey \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_ccm_setkey)
+#define mbedtls_cipher_auth_decrypt \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_cipher_auth_decrypt)
+#define mbedtls_cipher_auth_encrypt \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_cipher_auth_encrypt)
+#define mbedtls_cipher_check_tag \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_cipher_check_tag)
+#define mbedtls_cipher_crypt \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_cipher_crypt)
+#define mbedtls_cipher_definitions \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_cipher_definitions)
+#define mbedtls_cipher_finish \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_cipher_finish)
+#define mbedtls_cipher_free \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_cipher_free)
+#define mbedtls_cipher_info_from_string \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_cipher_info_from_string)
+#define mbedtls_cipher_info_from_type \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_cipher_info_from_type)
+#define mbedtls_cipher_info_from_values \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_cipher_info_from_values)
+#define mbedtls_cipher_init \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_cipher_init)
+#define mbedtls_cipher_list \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_cipher_list)
+#define mbedtls_cipher_reset \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_cipher_reset)
+#define mbedtls_cipher_set_iv \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_cipher_set_iv)
+#define mbedtls_cipher_setkey \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_cipher_setkey)
+#define mbedtls_cipher_set_padding_mode \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_cipher_set_padding_mode)
+#define mbedtls_cipher_setup \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_cipher_setup)
+#define mbedtls_cipher_supported \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_cipher_supported)
+#define mbedtls_cipher_update \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_cipher_update)
+#define mbedtls_cipher_update_ad \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_cipher_update_ad)
+#define mbedtls_cipher_write_tag \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_cipher_write_tag)
+#define mbedtls_ctr_drbg_free \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_ctr_drbg_free)
+#define mbedtls_ctr_drbg_init \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_ctr_drbg_init)
+#define mbedtls_ctr_drbg_random \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_ctr_drbg_random)
+#define mbedtls_ctr_drbg_random_with_add \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_ctr_drbg_random_with_add)
+#define mbedtls_ctr_drbg_reseed \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_ctr_drbg_reseed)
+#define mbedtls_ctr_drbg_seed \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_ctr_drbg_seed)
+#define mbedtls_ctr_drbg_seed_entropy_len \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_ctr_drbg_seed_entropy_len)
+#define mbedtls_ctr_drbg_self_test \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_ctr_drbg_self_test)
+#define mbedtls_ctr_drbg_set_entropy_len \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_ctr_drbg_set_entropy_len)
+#define mbedtls_ctr_drbg_set_prediction_resistance \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_ctr_drbg_set_prediction_resistance)
+#define mbedtls_ctr_drbg_set_reseed_interval \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_ctr_drbg_set_reseed_interval)
+#define mbedtls_ctr_drbg_update \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_ctr_drbg_update)
+#define mbedtls_des3_crypt_cbc \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_des3_crypt_cbc)
+#define mbedtls_des3_crypt_ecb \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_des3_crypt_ecb)
+#define mbedtls_des3_free \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_des3_free)
+#define mbedtls_des3_init \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_des3_init)
+#define mbedtls_des3_set2key_dec \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_des3_set2key_dec)
+#define mbedtls_des3_set2key_enc \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_des3_set2key_enc)
+#define mbedtls_des3_set3key_dec \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_des3_set3key_dec)
+#define mbedtls_des3_set3key_enc \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_des3_set3key_enc)
+#define mbedtls_des_crypt_cbc \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_des_crypt_cbc)
+#define mbedtls_des_crypt_ecb \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_des_crypt_ecb)
+#define mbedtls_des_free \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_des_free)
+#define mbedtls_des_init \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_des_init)
+#define mbedtls_des_key_check_key_parity \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_des_key_check_key_parity)
+#define mbedtls_des_key_check_weak \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_des_key_check_weak)
+#define mbedtls_des_key_set_parity \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_des_key_set_parity)
+#define mbedtls_des_self_test \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_des_self_test)
+#define mbedtls_des_setkey \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_des_setkey)
+#define mbedtls_des_setkey_dec \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_des_setkey_dec)
+#define mbedtls_des_setkey_enc \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_des_setkey_enc)
+#define mbedtls_dhm_calc_secret \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_dhm_calc_secret)
+#define mbedtls_dhm_free \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_dhm_free)
+#define mbedtls_dhm_init \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_dhm_init)
+#define mbedtls_dhm_make_params \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_dhm_make_params)
+#define mbedtls_dhm_make_public \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_dhm_make_public)
+#define mbedtls_dhm_parse_dhm \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_dhm_parse_dhm)
+#define mbedtls_dhm_read_params \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_dhm_read_params)
+#define mbedtls_dhm_read_public \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_dhm_read_public)
+#define mbedtls_dhm_self_test \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_dhm_self_test)
+#define mbedtls_ecdh_calc_secret \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_ecdh_calc_secret)
+#define mbedtls_ecdh_compute_shared \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_ecdh_compute_shared)
+#define mbedtls_ecdh_free \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_ecdh_free)
+#define mbedtls_ecdh_gen_public \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_ecdh_gen_public)
+#define mbedtls_ecdh_get_params \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_ecdh_get_params)
+#define mbedtls_ecdh_init \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_ecdh_init)
+#define mbedtls_ecdh_make_params \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_ecdh_make_params)
+#define mbedtls_ecdh_make_public \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_ecdh_make_public)
+#define mbedtls_ecdh_read_params \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_ecdh_read_params)
+#define mbedtls_ecdh_read_public \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_ecdh_read_public)
+#define mbedtls_ecdsa_free \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_ecdsa_free)
+#define mbedtls_ecdsa_from_keypair \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_ecdsa_from_keypair)
+#define mbedtls_ecdsa_genkey \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_ecdsa_genkey)
+#define mbedtls_ecdsa_info \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_ecdsa_info)
+#define mbedtls_ecdsa_init \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_ecdsa_init)
+#define mbedtls_ecdsa_read_signature \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_ecdsa_read_signature)
+#define mbedtls_ecdsa_sign \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_ecdsa_sign)
+#define mbedtls_ecdsa_sign_det \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_ecdsa_sign_det)
+#define mbedtls_ecdsa_verify \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_ecdsa_verify)
+#define mbedtls_ecdsa_write_signature \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_ecdsa_write_signature)
+#define mbedtls_ecdsa_write_signature_det \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_ecdsa_write_signature_det)
+#define mbedtls_eckeydh_info \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_eckeydh_info)
+#define mbedtls_eckey_info \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_eckey_info)
+#define mbedtls_ecp_check_privkey \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_ecp_check_privkey)
+#define mbedtls_ecp_check_pubkey \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_ecp_check_pubkey)
+#define mbedtls_ecp_check_pub_priv \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_ecp_check_pub_priv)
+#define mbedtls_ecp_copy \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_ecp_copy)
+#define mbedtls_ecp_curve_info_from_grp_id \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_ecp_curve_info_from_grp_id)
+#define mbedtls_ecp_curve_info_from_name \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_ecp_curve_info_from_name)
+#define mbedtls_ecp_curve_info_from_tls_id \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_ecp_curve_info_from_tls_id)
+#define mbedtls_ecp_curve_list \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_ecp_curve_list)
+#define mbedtls_ecp_gen_key \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_ecp_gen_key)
+#define mbedtls_ecp_gen_keypair \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_ecp_gen_keypair)
+#define mbedtls_ecp_gen_keypair_base \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_ecp_gen_keypair_base)
+#define mbedtls_ecp_group_copy \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_ecp_group_copy)
+#define mbedtls_ecp_group_free \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_ecp_group_free)
+#define mbedtls_ecp_group_init \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_ecp_group_init)
+#define mbedtls_ecp_group_load \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_ecp_group_load)
+#define mbedtls_ecp_grp_id_list \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_ecp_grp_id_list)
+#define mbedtls_ecp_is_zero \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_ecp_is_zero)
+#define mbedtls_ecp_keypair_free \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_ecp_keypair_free)
+#define mbedtls_ecp_keypair_init \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_ecp_keypair_init)
+#define mbedtls_ecp_mul \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_ecp_mul)
+#define mbedtls_ecp_muladd \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_ecp_muladd)
+#define mbedtls_ecp_point_cmp \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_ecp_point_cmp)
+#define mbedtls_ecp_point_free \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_ecp_point_free)
+#define mbedtls_ecp_point_init \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_ecp_point_init)
+#define mbedtls_ecp_point_read_binary \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_ecp_point_read_binary)
+#define mbedtls_ecp_point_read_string \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_ecp_point_read_string)
+#define mbedtls_ecp_point_write_binary \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_ecp_point_write_binary)
+#define mbedtls_ecp_self_test \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_ecp_self_test)
+#define mbedtls_ecp_set_zero \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_ecp_set_zero)
+#define mbedtls_ecp_tls_read_group \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_ecp_tls_read_group)
+#define mbedtls_ecp_tls_read_point \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_ecp_tls_read_point)
+#define mbedtls_ecp_tls_write_group \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_ecp_tls_write_group)
+#define mbedtls_ecp_tls_write_point \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_ecp_tls_write_point)
+#define mbedtls_entropy_add_source \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_entropy_add_source)
+#define mbedtls_entropy_free \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_entropy_free)
+#define mbedtls_entropy_func \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_entropy_func)
+#define mbedtls_entropy_gather \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_entropy_gather)
+#define mbedtls_entropy_init \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_entropy_init)
+#define mbedtls_entropy_self_test \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_entropy_self_test)
+#define mbedtls_entropy_update_manual \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_entropy_update_manual)
+#define mbedtls_free \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_free)
+#define mbedtls_gcm_auth_decrypt \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_gcm_auth_decrypt)
+#define mbedtls_gcm_crypt_and_tag \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_gcm_crypt_and_tag)
+#define mbedtls_gcm_finish \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_gcm_finish)
+#define mbedtls_gcm_free \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_gcm_free)
+#define mbedtls_gcm_init \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_gcm_init)
+#define mbedtls_gcm_self_test \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_gcm_self_test)
+#define mbedtls_gcm_setkey \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_gcm_setkey)
+#define mbedtls_gcm_starts \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_gcm_starts)
+#define mbedtls_gcm_update \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_gcm_update)
+#define mbedtls_hmac_drbg_free \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_hmac_drbg_free)
+#define mbedtls_hmac_drbg_init \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_hmac_drbg_init)
+#define mbedtls_hmac_drbg_random \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_hmac_drbg_random)
+#define mbedtls_hmac_drbg_random_with_add \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_hmac_drbg_random_with_add)
+#define mbedtls_hmac_drbg_reseed \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_hmac_drbg_reseed)
+#define mbedtls_hmac_drbg_seed \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_hmac_drbg_seed)
+#define mbedtls_hmac_drbg_seed_buf \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_hmac_drbg_seed_buf)
+#define mbedtls_hmac_drbg_self_test \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_hmac_drbg_self_test)
+#define mbedtls_hmac_drbg_set_entropy_len \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_hmac_drbg_set_entropy_len)
+#define mbedtls_hmac_drbg_set_prediction_resistance \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_hmac_drbg_set_prediction_resistance)
+#define mbedtls_hmac_drbg_set_reseed_interval \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_hmac_drbg_set_reseed_interval)
+#define mbedtls_hmac_drbg_update \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_hmac_drbg_update)
+#define mbedtls_internal_aes_decrypt \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_internal_aes_decrypt)
+#define mbedtls_internal_aes_encrypt \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_internal_aes_encrypt)
+#define mbedtls_md \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_md)
+#define mbedtls_md5 \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_md5)
+#define mbedtls_md5_clone \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_md5_clone)
+#define mbedtls_md5_finish \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_md5_finish)
+#define mbedtls_md5_free \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_md5_free)
+#define mbedtls_md5_info \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_md5_info)
+#define mbedtls_md5_init \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_md5_init)
+#define mbedtls_md5_process \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_md5_process)
+#define mbedtls_md5_self_test \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_md5_self_test)
+#define mbedtls_md5_starts \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_md5_starts)
+#define mbedtls_md5_update \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_md5_update)
+#define mbedtls_md_clone \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_md_clone)
+#define mbedtls_md_finish \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_md_finish)
+#define mbedtls_md_free \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_md_free)
+#define mbedtls_md_get_name \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_md_get_name)
+#define mbedtls_md_get_size \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_md_get_size)
+#define mbedtls_md_get_type \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_md_get_type)
+#define mbedtls_md_hmac \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_md_hmac)
+#define mbedtls_md_hmac_finish \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_md_hmac_finish)
+#define mbedtls_md_hmac_reset \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_md_hmac_reset)
+#define mbedtls_md_hmac_starts \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_md_hmac_starts)
+#define mbedtls_md_hmac_update \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_md_hmac_update)
+#define mbedtls_md_info_from_string \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_md_info_from_string)
+#define mbedtls_md_info_from_type \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_md_info_from_type)
+#define mbedtls_md_init \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_md_init)
+#define mbedtls_md_init_ctx \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_md_init_ctx)
+#define mbedtls_md_list \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_md_list)
+#define mbedtls_md_process \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_md_process)
+#define mbedtls_md_setup \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_md_setup)
+#define mbedtls_md_starts \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_md_starts)
+#define mbedtls_md_update \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_md_update)
+#define mbedtls_memory_buffer_alloc_free \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_memory_buffer_alloc_free)
+#define mbedtls_memory_buffer_alloc_init \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_memory_buffer_alloc_init)
+#define mbedtls_memory_buffer_alloc_self_test \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_memory_buffer_alloc_self_test)
+#define mbedtls_memory_buffer_alloc_verify \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_memory_buffer_alloc_verify)
+#define mbedtls_memory_buffer_set_verify \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_memory_buffer_set_verify)
+#define mbedtls_mpi_add_abs \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_mpi_add_abs)
+#define mbedtls_mpi_add_int \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_mpi_add_int)
+#define mbedtls_mpi_add_mpi \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_mpi_add_mpi)
+#define mbedtls_mpi_bitlen \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_mpi_bitlen)
+#define mbedtls_mpi_cmp_abs \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_mpi_cmp_abs)
+#define mbedtls_mpi_cmp_int \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_mpi_cmp_int)
+#define mbedtls_mpi_cmp_mpi \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_mpi_cmp_mpi)
+#define mbedtls_mpi_copy \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_mpi_copy)
+#define mbedtls_mpi_div_int \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_mpi_div_int)
+#define mbedtls_mpi_div_mpi \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_mpi_div_mpi)
+#define mbedtls_mpi_exp_mod \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_mpi_exp_mod)
+#define mbedtls_mpi_fill_random \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_mpi_fill_random)
+#define mbedtls_mpi_free \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_mpi_free)
+#define mbedtls_mpi_gcd \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_mpi_gcd)
+#define mbedtls_mpi_gen_prime \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_mpi_gen_prime)
+#define mbedtls_mpi_get_bit \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_mpi_get_bit)
+#define mbedtls_mpi_grow \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_mpi_grow)
+#define mbedtls_mpi_init \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_mpi_init)
+#define mbedtls_mpi_inv_mod \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_mpi_inv_mod)
+#define mbedtls_mpi_is_prime \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_mpi_is_prime)
+#define mbedtls_mpi_lsb \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_mpi_lsb)
+#define mbedtls_mpi_lset \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_mpi_lset)
+#define mbedtls_mpi_mod_int \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_mpi_mod_int)
+#define mbedtls_mpi_mod_mpi \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_mpi_mod_mpi)
+#define mbedtls_mpi_mul_int \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_mpi_mul_int)
+#define mbedtls_mpi_mul_mpi \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_mpi_mul_mpi)
+#define mbedtls_mpi_read_binary \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_mpi_read_binary)
+#define mbedtls_mpi_read_string \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_mpi_read_string)
+#define mbedtls_mpi_safe_cond_assign \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_mpi_safe_cond_assign)
+#define mbedtls_mpi_safe_cond_swap \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_mpi_safe_cond_swap)
+#define mbedtls_mpi_self_test \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_mpi_self_test)
+#define mbedtls_mpi_set_bit \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_mpi_set_bit)
+#define mbedtls_mpi_shift_l \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_mpi_shift_l)
+#define mbedtls_mpi_shift_r \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_mpi_shift_r)
+#define mbedtls_mpi_shrink \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_mpi_shrink)
+#define mbedtls_mpi_size \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_mpi_size)
+#define mbedtls_mpi_sub_abs \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_mpi_sub_abs)
+#define mbedtls_mpi_sub_int \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_mpi_sub_int)
+#define mbedtls_mpi_sub_mpi \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_mpi_sub_mpi)
+#define mbedtls_mpi_swap \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_mpi_swap)
+#define mbedtls_mpi_write_binary \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_mpi_write_binary)
+#define mbedtls_mpi_write_string \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_mpi_write_string)
+#define mbedtls_oid_get_attr_short_name \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_oid_get_attr_short_name)
+#define mbedtls_oid_get_cipher_alg \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_oid_get_cipher_alg)
+#define mbedtls_oid_get_ec_grp \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_oid_get_ec_grp)
+#define mbedtls_oid_get_extended_key_usage \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_oid_get_extended_key_usage)
+#define mbedtls_oid_get_md_alg \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_oid_get_md_alg)
+#define mbedtls_oid_get_numeric_string \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_oid_get_numeric_string)
+#define mbedtls_oid_get_oid_by_ec_grp \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_oid_get_oid_by_ec_grp)
+#define mbedtls_oid_get_oid_by_md \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_oid_get_oid_by_md)
+#define mbedtls_oid_get_oid_by_pk_alg \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_oid_get_oid_by_pk_alg)
+#define mbedtls_oid_get_oid_by_sig_alg \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_oid_get_oid_by_sig_alg)
+#define mbedtls_oid_get_pk_alg \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_oid_get_pk_alg)
+#define mbedtls_oid_get_pkcs12_pbe_alg \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_oid_get_pkcs12_pbe_alg)
+#define mbedtls_oid_get_sig_alg \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_oid_get_sig_alg)
+#define mbedtls_oid_get_sig_alg_desc \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_oid_get_sig_alg_desc)
+#define mbedtls_oid_get_x509_ext_type \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_oid_get_x509_ext_type)
+#define mbedtls_pem_free \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_pem_free)
+#define mbedtls_pem_init \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_pem_init)
+#define mbedtls_pem_read_buffer \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_pem_read_buffer)
+#define mbedtls_pem_write_buffer \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_pem_write_buffer)
+#define mbedtls_pk_can_do \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_pk_can_do)
+#define mbedtls_pk_check_pair \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_pk_check_pair)
+#define mbedtls_pkcs12_derivation \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_pkcs12_derivation)
+#define mbedtls_pkcs12_pbe \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_pkcs12_pbe)
+#define mbedtls_pkcs12_pbe_sha1_rc4_128 \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_pkcs12_pbe_sha1_rc4_128)
+#define mbedtls_pkcs5_pbes2 \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_pkcs5_pbes2)
+#define mbedtls_pkcs5_pbkdf2_hmac \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_pkcs5_pbkdf2_hmac)
+#define mbedtls_pkcs5_self_test \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_pkcs5_self_test)
+#define mbedtls_pk_debug \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_pk_debug)
+#define mbedtls_pk_decrypt \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_pk_decrypt)
+#define mbedtls_pk_encrypt \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_pk_encrypt)
+#define mbedtls_pk_free \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_pk_free)
+#define mbedtls_pk_get_bitlen \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_pk_get_bitlen)
+#define mbedtls_pk_get_name \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_pk_get_name)
+#define mbedtls_pk_get_type \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_pk_get_type)
+#define mbedtls_pk_info_from_type \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_pk_info_from_type)
+#define mbedtls_pk_init \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_pk_init)
+#define mbedtls_pk_parse_key \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_pk_parse_key)
+#define mbedtls_pk_parse_public_key \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_pk_parse_public_key)
+#define mbedtls_pk_parse_subpubkey \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_pk_parse_subpubkey)
+#define mbedtls_pk_setup \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_pk_setup)
+#define mbedtls_pk_setup_rsa_alt \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_pk_setup_rsa_alt)
+#define mbedtls_pk_sign \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_pk_sign)
+#define mbedtls_pk_verify \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_pk_verify)
+#define mbedtls_pk_verify_ext \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_pk_verify_ext)
+#define mbedtls_pk_write_key_der \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_pk_write_key_der)
+#define mbedtls_pk_write_key_pem \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_pk_write_key_pem)
+#define mbedtls_pk_write_pubkey \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_pk_write_pubkey)
+#define mbedtls_pk_write_pubkey_der \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_pk_write_pubkey_der)
+#define mbedtls_pk_write_pubkey_pem \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_pk_write_pubkey_pem)
+#define mbedtls_platform_set_calloc_free \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_platform_set_calloc_free)
+#define mbedtls_platform_setup \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_platform_setup)
+#define mbedtls_platform_teardown \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_platform_teardown)
+#define mbedtls_ripemd160 \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_ripemd160)
+#define mbedtls_ripemd160_clone \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_ripemd160_clone)
+#define mbedtls_ripemd160_finish \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_ripemd160_finish)
+#define mbedtls_ripemd160_free \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_ripemd160_free)
+#define mbedtls_ripemd160_info \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_ripemd160_info)
+#define mbedtls_ripemd160_init \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_ripemd160_init)
+#define mbedtls_ripemd160_process \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_ripemd160_process)
+#define mbedtls_ripemd160_self_test \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_ripemd160_self_test)
+#define mbedtls_ripemd160_starts \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_ripemd160_starts)
+#define mbedtls_ripemd160_update \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_ripemd160_update)
+#define mbedtls_rsa_alt_info \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_rsa_alt_info)
+#define mbedtls_rsa_check_privkey \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_rsa_check_privkey)
+#define mbedtls_rsa_check_pubkey \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_rsa_check_pubkey)
+#define mbedtls_rsa_check_pub_priv \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_rsa_check_pub_priv)
+#define mbedtls_rsa_copy \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_rsa_copy)
+#define mbedtls_rsa_free \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_rsa_free)
+#define mbedtls_rsa_gen_key \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_rsa_gen_key)
+#define mbedtls_rsa_info \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_rsa_info)
+#define mbedtls_rsa_init \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_rsa_init)
+#define mbedtls_rsa_pkcs1_decrypt \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_rsa_pkcs1_decrypt)
+#define mbedtls_rsa_pkcs1_encrypt \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_rsa_pkcs1_encrypt)
+#define mbedtls_rsa_pkcs1_sign \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_rsa_pkcs1_sign)
+#define mbedtls_rsa_pkcs1_verify \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_rsa_pkcs1_verify)
+#define mbedtls_rsa_private \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_rsa_private)
+#define mbedtls_rsa_public \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_rsa_public)
+#define mbedtls_rsa_rsaes_oaep_decrypt \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_rsa_rsaes_oaep_decrypt)
+#define mbedtls_rsa_rsaes_oaep_encrypt \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_rsa_rsaes_oaep_encrypt)
+#define mbedtls_rsa_rsaes_pkcs1_v15_decrypt \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_rsa_rsaes_pkcs1_v15_decrypt)
+#define mbedtls_rsa_rsaes_pkcs1_v15_encrypt \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_rsa_rsaes_pkcs1_v15_encrypt)
+#define mbedtls_rsa_rsassa_pkcs1_v15_sign \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_rsa_rsassa_pkcs1_v15_sign)
+#define mbedtls_rsa_rsassa_pkcs1_v15_verify \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_rsa_rsassa_pkcs1_v15_verify)
+#define mbedtls_rsa_rsassa_pss_sign \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_rsa_rsassa_pss_sign)
+#define mbedtls_rsa_rsassa_pss_verify \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_rsa_rsassa_pss_verify)
+#define mbedtls_rsa_rsassa_pss_verify_ext \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_rsa_rsassa_pss_verify_ext)
+#define mbedtls_rsa_self_test \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_rsa_self_test)
+#define mbedtls_rsa_set_padding \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_rsa_set_padding)
+#define mbedtls_sha1 \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_sha1)
+#define mbedtls_sha1_clone \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_sha1_clone)
+#define mbedtls_sha1_finish \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_sha1_finish)
+#define mbedtls_sha1_free \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_sha1_free)
+#define mbedtls_sha1_info \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_sha1_info)
+#define mbedtls_sha1_init \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_sha1_init)
+#define mbedtls_sha1_process \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_sha1_process)
+#define mbedtls_sha1_self_test \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_sha1_self_test)
+#define mbedtls_sha1_starts \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_sha1_starts)
+#define mbedtls_sha1_update \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_sha1_update)
+#define mbedtls_sha224_info \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_sha224_info)
+#define mbedtls_sha256 \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_sha256)
+#define mbedtls_sha256_clone \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_sha256_clone)
+#define mbedtls_sha256_finish \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_sha256_finish)
+#define mbedtls_sha256_free \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_sha256_free)
+#define mbedtls_sha256_info \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_sha256_info)
+#define mbedtls_sha256_init \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_sha256_init)
+#define mbedtls_sha256_process \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_sha256_process)
+#define mbedtls_sha256_self_test \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_sha256_self_test)
+#define mbedtls_sha256_starts \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_sha256_starts)
+#define mbedtls_sha256_update \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_sha256_update)
+#define mbedtls_sha384_info \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_sha384_info)
+#define mbedtls_sha512 \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_sha512)
+#define mbedtls_sha512_clone \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_sha512_clone)
+#define mbedtls_sha512_finish \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_sha512_finish)
+#define mbedtls_sha512_free \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_sha512_free)
+#define mbedtls_sha512_info \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_sha512_info)
+#define mbedtls_sha512_init \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_sha512_init)
+#define mbedtls_sha512_process \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_sha512_process)
+#define mbedtls_sha512_self_test \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_sha512_self_test)
+#define mbedtls_sha512_starts \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_sha512_starts)
+#define mbedtls_sha512_update \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_sha512_update)
+#define mbedtls_strerror \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_strerror)
+#define mbedtls_version_check_feature \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_version_check_feature)
+#define mbedtls_version_get_number \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_version_get_number)
+#define mbedtls_version_get_string \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_version_get_string)
+#define mbedtls_version_get_string_full \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_version_get_string_full)
+#define mbedtls_xtea_crypt_cbc \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_xtea_crypt_cbc)
+#define mbedtls_xtea_crypt_ecb \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_xtea_crypt_ecb)
+#define mbedtls_xtea_free \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_xtea_free)
+#define mbedtls_xtea_init \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_xtea_init)
+#define mbedtls_xtea_self_test \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_xtea_self_test)
+#define mbedtls_xtea_setup \
+        CONCAT(LIB_PREFIX_NAME, mbedtls_xtea_setup)
+
+#endif /* __MBEDTLS_GLOBAL_SYMBOLS_H__ */
diff --git a/secure_fw/services/crypto/psa_crypto_struct.h b/secure_fw/services/crypto/psa_crypto_struct.h
new file mode 100644
index 0000000..de724dd
--- /dev/null
+++ b/secure_fw/services/crypto/psa_crypto_struct.h
@@ -0,0 +1,131 @@
+/*
+ * Copyright (c) 2018, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+/**
+ * \file psa_crypto_struct.h
+ *
+ * \brief PSA cryptography module: Mbed TLS structured type implementations
+ */
+
+#ifndef __PSA_CRYPTO_STRUCT_H__
+#define __PSA_CRYPTO_STRUCT_H__
+
+/* Include the Mbed TLS configuration file, the way Mbed TLS does it
+ * in each of its header files.
+ */
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "platform/ext/common/tfm_mbedtls_config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#include "mbedtls/cipher.h"
+#include "mbedtls/cmac.h"
+#include "mbedtls/gcm.h"
+#include "mbedtls/md.h"
+#include "mbedtls/md2.h"
+#include "mbedtls/md4.h"
+#include "mbedtls/md5.h"
+#include "mbedtls/ripemd160.h"
+#include "mbedtls/sha1.h"
+#include "mbedtls/sha256.h"
+#include "mbedtls/sha512.h"
+
+#if defined(MBEDTLS_SHA512_C)
+#define PSA_HASH_MAX_SIZE 64
+#define PSA_HMAC_MAX_HASH_BLOCK_SIZE 128
+#else
+#define PSA_HASH_MAX_SIZE 32
+#define PSA_HMAC_MAX_HASH_BLOCK_SIZE 64
+#endif
+
+struct psa_hash_operation_s
+{
+    psa_algorithm_t alg;
+    union
+    {
+        uint32_t dummy; /* Make the union non-empty in any case */
+#if defined(MBEDTLS_MD2_C)
+        mbedtls_md2_context md2;
+#endif
+#if defined(MBEDTLS_MD4_C)
+        mbedtls_md4_context md4;
+#endif
+#if defined(MBEDTLS_MD5_C)
+        mbedtls_md5_context md5;
+#endif
+#if defined(MBEDTLS_RIPEMD160_C)
+        mbedtls_ripemd160_context ripemd160;
+#endif
+#if defined(MBEDTLS_SHA1_C)
+        mbedtls_sha1_context sha1;
+#endif
+#if defined(MBEDTLS_SHA256_C)
+        mbedtls_sha256_context sha256;
+#endif
+#if defined(MBEDTLS_SHA512_C)
+        mbedtls_sha512_context sha512;
+#endif
+    } ctx;
+};
+
+
+typedef struct
+{
+    /* The hash context. */
+    struct psa_hash_operation_s hash_ctx;
+    /* The HMAC part of the context. */
+    uint8_t opad[PSA_HMAC_MAX_HASH_BLOCK_SIZE];
+} psa_hmac_internal_data;
+
+
+struct psa_mac_operation_s
+{
+    psa_algorithm_t alg;
+    uint8_t key_set;
+    uint8_t iv_required;
+    uint8_t iv_set;
+    uint8_t has_input;
+    uint8_t key_usage_sign;
+    uint8_t key_usage_verify;
+    uint8_t mac_size;
+    union
+    {
+        uint32_t dummy; /* Make the union non-empty in any case */
+#if defined(MBEDTLS_MD_C)
+        psa_hmac_internal_data hmac;
+#endif
+#if defined(MBEDTLS_CMAC_C)
+        mbedtls_cipher_context_t cmac;
+#endif
+    } ctx;
+};
+
+#define PSA_CIPHER_IV_MAX_SIZE 16
+
+struct psa_cipher_operation_s
+{
+    psa_algorithm_t alg;
+    uint8_t key_set;
+    uint8_t iv_required;
+    uint8_t iv_set;
+    uint8_t iv_size;
+    uint8_t block_size;
+    psa_key_slot_t key;
+    union
+    {
+        mbedtls_cipher_context_t cipher;
+    } ctx;
+};
+
+struct psa_key_policy_s
+{
+    psa_key_usage_t usage;
+    psa_algorithm_t alg;
+};
+
+#endif /* __PSA_CRYPTO_STRUCT_H__ */
diff --git a/secure_fw/services/crypto/tfm_crypto_api.h b/secure_fw/services/crypto/tfm_crypto_api.h
new file mode 100644
index 0000000..c415c09
--- /dev/null
+++ b/secure_fw/services/crypto/tfm_crypto_api.h
@@ -0,0 +1,235 @@
+/*
+ * Copyright (c) 2018, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef __TFM_CRYPTO_API_H__
+#define __TFM_CRYPTO_API_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdint.h>
+#include "tfm_crypto_defs.h"
+#include "psa_crypto.h"
+
+/**
+ * \brief List of possible operation types supported by the TFM based
+ *        implementation. This type is needed by the operation allocation,
+ *        lookup and release functions.
+ *
+ */
+enum tfm_crypto_operation_type {
+    TFM_CRYPTO_OPERATION_NONE = 0,
+    TFM_CRYPTO_CIPHER_OPERATION = 1,
+    TFM_CRYPTO_MAC_OPERATION = 2,
+    TFM_CRYPTO_HASH_OPERATION = 3,
+    TFM_CRYPTO_KEY_POLICY = 4,
+
+    /* Used to force the enum size */
+    TFM_CRYPTO_OPERATION_TYPE_MAX = INT_MAX
+};
+
+/**
+ * \brief Initialises the service
+ *
+ * \return Returns values as described in \ref tfm_crypto_err_t
+ */
+enum tfm_crypto_err_t tfm_crypto_init(void);
+
+/**
+ * \brief Allocates an operation object
+ *
+ * \param[in]  type   Type of the operation object to allocate
+ * \param[out] handle Pointer to the corresponding handle assigned
+ *
+ * \return Returns values as described in \ref tfm_crypto_err_t
+ */
+enum tfm_crypto_err_t tfm_crypto_operation_alloc(
+                                        enum tfm_crypto_operation_type type,
+                                        uint32_t *handle);
+/**
+ * \brief Releases an operation object
+ *
+ * \param[in] handle Pointer to the handle for the release of the
+ *                   corresponding object
+ *
+ * \return Returns values as described in \ref tfm_crypto_err_t
+ */
+enum tfm_crypto_err_t tfm_crypto_operation_release(uint32_t *handle);
+
+/**
+ * \brief Looks up an operation object pointer from the corresponding handle
+ *
+ * \param[in]  type   Type of the operation object to look up
+ * \param[in]  handle Handle to the operation object to look up
+ * \param[out] oper   Double pointer to the corresponding object
+ *
+ * \return Returns values as described in \ref tfm_crypto_err_t
+ */
+enum tfm_crypto_err_t tfm_crypto_operation_lookup(
+                                        enum tfm_crypto_operation_type type,
+                                        uint32_t *handle,
+                                        void **oper);
+/**
+ * \brief Import the key data in the provided key slot
+ *
+ * \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 Returns values as described in \ref tfm_crypto_err_t
+ */
+enum tfm_crypto_err_t tfm_crypto_import_key(psa_key_slot_t key,
+                                            psa_key_type_t type,
+                                            const uint8_t *data,
+                                            size_t data_length);
+/**
+ * \brief Destroy the key on the provided key slot
+ *
+ * \param[in] key         Key slot
+ *
+ * \return Returns values as described in \ref tfm_crypto_err_t
+ */
+enum tfm_crypto_err_t tfm_crypto_destroy_key(psa_key_slot_t key);
+
+/**
+ * \brief Retrieve key information for the provided key slot
+ *
+ * \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 Returns values as described in \ref tfm_crypto_err_t
+ */
+enum tfm_crypto_err_t tfm_crypto_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
+ *
+ * \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 Returns values as described in \ref tfm_crypto_err_t
+ */
+enum tfm_crypto_err_t tfm_crypto_export_key(psa_key_slot_t key,
+                                            uint8_t *data,
+                                            size_t data_size,
+                                            size_t *data_length);
+/**
+ * \brief Export the public key contained in the provided key slot
+ *        for an asymmetric key pair.
+ *
+ * \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 Returns values as described in \ref tfm_crypto_err_t
+ */
+enum tfm_crypto_err_t tfm_crypto_export_public_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
+ *
+ * \param[in] operation  Cipher operation context
+ * \param[in] iv         Buffer that contains the IV
+ * \param[in] iv_length  Length of the provided IV
+ *
+ * \return Returns values as described in \ref tfm_crypto_err_t
+ */
+enum tfm_crypto_err_t tfm_crypto_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.
+ *
+ * \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 Returns values as described in \ref tfm_crypto_err_t
+ */
+enum tfm_crypto_err_t tfm_crypto_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.
+ *
+ * \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 Returns values as described in \ref tfm_crypto_err_t
+ */
+enum tfm_crypto_err_t tfm_crypto_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).
+ *
+ * \param[in]  operation     Cipher operation context
+ * \param[in]  input         Buffer containing input data
+ * \param[in]  input_length  Input length
+ * \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 Returns values as described in \ref tfm_crypto_err_t
+ */
+enum tfm_crypto_err_t tfm_crypto_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);
+/**
+ * \brief Finalises a cipher context flushing out any remaining block of
+ *        output data
+ *
+ * \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 Returns values as described in \ref tfm_crypto_err_t
+ */
+enum tfm_crypto_err_t tfm_crypto_cipher_finish(
+                                              psa_cipher_operation_t *operation,
+                                              uint8_t *output,
+                                              size_t output_size,
+                                              size_t *output_length);
+/**
+ * \brief Aborts a cipher operation, clears the operation context provided
+ *
+ * \param[in]  operation     Cipher operation context
+ *
+ * \return Returns values as described in \ref tfm_crypto_err_t
+ */
+enum tfm_crypto_err_t tfm_crypto_cipher_abort(
+                                             psa_cipher_operation_t *operation);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __TFM_CRYPTO_API_H__ */
diff --git a/secure_fw/services/secure_storage/CMakeLists.txt b/secure_fw/services/secure_storage/CMakeLists.txt
index dafeea6..21d3f53 100644
--- a/secure_fw/services/secure_storage/CMakeLists.txt
+++ b/secure_fw/services/secure_storage/CMakeLists.txt
@@ -28,7 +28,7 @@
 set (MBEDTLS_TARGET_NAME "mbedtls_sst_lib")
 
 #Set mbedTLS compiler flags
-set(MBEDTLS_C_FLAGS ${MBEDTLS_C_FLAGS_SST_LOG})
+set(MBEDTLS_C_FLAGS ${MBEDTLS_C_FLAGS_SERVICES})
 
 ###Get the definition of what files we need to build
 set (ENABLE_SECURE_STORAGE ON)
diff --git a/secure_fw/services/tfm_partition_defs.inc b/secure_fw/services/tfm_partition_defs.inc
index 0c6afa1..e06ba4e 100644
--- a/secure_fw/services/tfm_partition_defs.inc
+++ b/secure_fw/services/tfm_partition_defs.inc
@@ -14,22 +14,24 @@
 
 #define TFM_SP_AUDIT_LOG_ID (TFM_SP_BASE + 1)
 
+#define TFM_SP_CRYPTO_ID (TFM_SP_BASE + 2)
+
 #ifdef TFM_PARTITION_TEST_CORE
-#define TFM_SP_CORE_TEST_ID (TFM_SP_BASE + 2)
+#define TFM_SP_CORE_TEST_ID (TFM_SP_BASE + 3)
 #endif /* TFM_PARTITION_TEST_CORE */
 
 #ifdef TFM_PARTITION_TEST_CORE
-#define TFM_SP_CORE_TEST_2_ID (TFM_SP_BASE + 3)
+#define TFM_SP_CORE_TEST_2_ID (TFM_SP_BASE + 4)
 #endif /* TFM_PARTITION_TEST_CORE */
 
 #ifdef TFM_PARTITION_TEST_SST
-#define TFM_SP_SST_TEST_PARTITION_ID (TFM_SP_BASE + 4)
+#define TFM_SP_SST_TEST_PARTITION_ID (TFM_SP_BASE + 5)
 #endif /* TFM_PARTITION_TEST_SST */
 
 #ifdef TFM_PARTITION_TEST_SECURE_SERVICES
-#define TFM_SP_SECURE_TEST_PARTITION_ID (TFM_SP_BASE + 5)
+#define TFM_SP_SECURE_TEST_PARTITION_ID (TFM_SP_BASE + 6)
 #endif /* TFM_PARTITION_TEST_SECURE_SERVICES */
 
-#define TFM_MAX_USER_PARTITIONS (6)
+#define TFM_MAX_USER_PARTITIONS (7)
 
 #endif /* __TFM_PARTITION_DEFS_INC__ */
diff --git a/secure_fw/services/tfm_partition_list.inc b/secure_fw/services/tfm_partition_list.inc
index 6ae61bb..f3fe5f4 100644
--- a/secure_fw/services/tfm_partition_list.inc
+++ b/secure_fw/services/tfm_partition_list.inc
@@ -21,6 +21,10 @@
 PARTITION_ADD_PERIPHERAL(TFM_SP_AUDIT_LOG, TFM_PERIPHERAL_UART1);
 #endif /* AUDIT_UART_REDIRECTION */
 
+/******** TFM_SP_CRYPTO ********/
+PARTITION_DECLARE(TFM_SP_CRYPTO, SPM_PART_FLAG_SECURE | SPM_PART_FLAG_TRUSTED);
+PARTITION_ADD_INIT_FUNC(TFM_SP_CRYPTO, tfm_crypto_init);
+
 #ifdef TFM_PARTITION_TEST_CORE
 /******** TFM_SP_CORE_TEST ********/
 PARTITION_DECLARE(TFM_SP_CORE_TEST, SPM_PART_FLAG_SECURE);
diff --git a/secure_fw/services/tfm_sfid_list.inc b/secure_fw/services/tfm_sfid_list.inc
index 17de4b2..6934058 100644
--- a/secure_fw/services/tfm_sfid_list.inc
+++ b/secure_fw/services/tfm_sfid_list.inc
@@ -26,6 +26,21 @@
     {audit_core_get_record_info, TFM_AUDIT_GET_RECORD_INFO_SFID},
     {audit_core_delete_record, TFM_AUDIT_DELETE_RECORD_SFID},
 
+    /******** TFM_SP_CRYPTO ********/
+    {tfm_crypto_alloc_operation, TFM_CRYPTO_ALLOC_OPERATION_SFID},
+    {tfm_crypto_check_operation, TFM_CRYPTO_CHECK_OPERATION_SFID},
+    {tfm_crypto_release_operation, TFM_CRYPTO_RELEASE_OPERATION_SFID},
+    {tfm_crypto_import_key, TFM_CRYPTO_IMPORT_KEY_SFID},
+    {tfm_crypto_destroy_key, TFM_CRYPTO_DESTROY_KEY_SFID},
+    {tfm_crypto_get_key_information, TFM_CRYPTO_GET_KEY_INFORMATION_SFID},
+    {tfm_crypto_export_key, TFM_CRYPTO_EXPORT_KEY_SFID},
+    {tfm_crypto_encrypt_set_iv, TFM_CRYPTO_ENCRYPT_SET_IV_SFID},
+    {tfm_crypto_encrypt_setup, TFM_CRYPTO_ENCRYPT_SETUP_SFID},
+    {tfm_crypto_decrypt_setup, TFM_CRYPTO_DECRYPT_SETUP_SFID},
+    {tfm_crypto_cipher_update_wrapper, TFM_CRYPTO_CIPHER_UPDATE_SFID},
+    {tfm_crypto_cipher_abort, TFM_CRYPTO_CIPHER_ABORT_SFID},
+    {tfm_crypto_cipher_finish, TFM_CRYPTO_CIPHER_FINISH_SFID},
+
 #ifdef TFM_PARTITION_TEST_CORE
     /******** TFM_SP_CORE_TEST ********/
     {spm_core_test_sfn, TFM_CORE_TEST_SFN_SFID},
diff --git a/tools/tfm_manifest_list.yaml b/tools/tfm_manifest_list.yaml
index 3586c67..e4eb5fc 100644
--- a/tools/tfm_manifest_list.yaml
+++ b/tools/tfm_manifest_list.yaml
@@ -28,6 +28,14 @@
       "version_minor": 1

     },

     {

+      "name": "TFM Crypto Service",

+      "short_name": "TFM_Crypto",

+      "manifest": "secure_fw/services/crypto/manifest.yaml",

+      "tfm_extensions": true,

+      "version_major": 0,

+      "version_minor": 1

+    },

+    {

       "name": "TFM Core Test Service",

       "short_name": "TFM_Core_Test",

       "manifest": "test/test_services/tfm_core_test/manifest.yaml",