Merge pull request #113 from jainvikas8/linux-target-support

Linux target support
diff --git a/api-tests/platform/targets/tgt_dev_apis_stdc/README.md b/api-tests/platform/targets/tgt_dev_apis_stdc/README.md
new file mode 100644
index 0000000..df272d8
--- /dev/null
+++ b/api-tests/platform/targets/tgt_dev_apis_stdc/README.md
@@ -0,0 +1,15 @@
+# Linux Host Target
+
+There are a couple of limitations to this target when it comes to a test which involves system reset or test process due to Watch Dog Timer (WDT) and NVMEM implementation.
+
+- **WDT**:  Lacks functionality to recover after a hang as they just return failure or success.
+
+- **NVMEM**: Stores data in an array in memory, which means NVMEM would be lost as it isn't a non-volatile implementation.
+
+## License
+
+Arm PSA test suite is distributed under Apache v2.0 License.
+
+--------------
+
+*Copyright (c) 2018-2019, Arm Limited and Contributors. All rights reserved.*
diff --git a/api-tests/platform/targets/tgt_dev_apis_stdc/nspe/common/pal_client_api_empty_intf.c b/api-tests/platform/targets/tgt_dev_apis_stdc/nspe/common/pal_client_api_empty_intf.c
new file mode 100644
index 0000000..578b4ce
--- /dev/null
+++ b/api-tests/platform/targets/tgt_dev_apis_stdc/nspe/common/pal_client_api_empty_intf.c
@@ -0,0 +1,93 @@
+/** @file
+ * Copyright (c) 2019, Arm Limited or its affiliates. All rights reserved.
+ * SPDX-License-Identifier : Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+**/
+
+#include "pal_common.h"
+#include "pal_client_api_intf.h"
+
+/**
+ * @brief - Retrieve the version of the PSA Framework API that is implemented.
+ * This is a wrapper API for psa_framework_version API.
+ * @param    - void
+ * @return   - The PSA Framework API version.
+ */
+
+uint32_t pal_ipc_framework_version(void)
+{
+    return 0;
+}
+
+/**
+ * @brief - Retrieve the minor version of a Root of Trust Service by its SID.
+ * This is a wrapper API for the psa_version API.
+ * @param - sid The Root of Trust Service ID
+ * @return - Minor version of Root of Trust Service or PSA_VERSION_NONE if Root of Trust
+ *           Service not present on the system.
+ */
+
+uint32_t pal_ipc_version(uint32_t sid)
+{
+    return PSA_VERSION_NONE;
+}
+
+/**
+ * @brief   - Connect to given sid.
+ *            This is a wrapper API for the psa_connect API.
+ * @param   - sid : RoT service id
+ * @param   - minor_version : minor_version of RoT service
+ * @return  - psa_handle_t : return connection handle
+ */
+
+psa_handle_t pal_ipc_connect(uint32_t sid, uint32_t minor_version)
+{
+    return PSA_NULL_HANDLE;
+}
+
+/**
+ * @brief Call a connected Root of Trust Service.
+ * This is a wrapper API for the psa_call API.
+ * The caller must provide an array of ::psa_invec_t structures as the input payload.
+ *
+ * @param  -handle   Handle for the connection.
+ * @param  -in_vec   Array of psa_invec structures.
+ * @param  -in_len   Number of psa_invec structures in in_vec.
+ * @param  -out_vec  Array of psa_outvec structures for optional Root of Trust Service response.
+ * @param  -out_len  Number of psa_outvec structures in out_vec.
+ * @return -psa_status_t
+ */
+
+psa_status_t pal_ipc_call(psa_handle_t handle,
+                         const psa_invec *in_vec,
+                         size_t in_len,
+                         psa_outvec *out_vec,
+                         size_t out_len)
+{
+    return (PSA_SUCCESS - 1);
+}
+
+/**
+ * @brief Close a connection to a Root of Trust Service.
+ * This is a wrapper API for the psa_close API.
+ * Sends the PSA_IPC_DISCONNECT message to the Root of Trust Service so it can clean up resources.
+ *
+ * @param handle Handle for the connection.
+ * @return void
+ */
+
+void pal_ipc_close(psa_handle_t handle)
+{
+    return;
+}
diff --git a/api-tests/platform/targets/tgt_dev_apis_stdc/nspe/common/pal_client_api_intf.h b/api-tests/platform/targets/tgt_dev_apis_stdc/nspe/common/pal_client_api_intf.h
new file mode 100644
index 0000000..3f5741e
--- /dev/null
+++ b/api-tests/platform/targets/tgt_dev_apis_stdc/nspe/common/pal_client_api_intf.h
@@ -0,0 +1,32 @@
+/** @file
+ * Copyright (c) 2019, Arm Limited or its affiliates. All rights reserved.
+ * SPDX-License-Identifier : Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+**/
+
+#ifndef _PAL_CLIENT_API_H_
+#define _PAL_CLIENT_API_H_
+
+#include "pal_common.h"
+
+uint32_t pal_ipc_framework_version(void);
+uint32_t pal_ipc_version(uint32_t sid);
+psa_handle_t pal_ipc_connect(uint32_t sid, uint32_t minor_version);
+psa_status_t pal_ipc_call(psa_handle_t handle,
+                      const psa_invec *in_vec,
+                      size_t in_len,
+                      psa_outvec *out_vec,
+                      size_t out_len);
+void pal_ipc_close(psa_handle_t handle);
+#endif /* _PAL_CLIENT_API_H_ */
diff --git a/api-tests/platform/targets/tgt_dev_apis_stdc/nspe/common/pal_common.h b/api-tests/platform/targets/tgt_dev_apis_stdc/nspe/common/pal_common.h
new file mode 100644
index 0000000..0076891
--- /dev/null
+++ b/api-tests/platform/targets/tgt_dev_apis_stdc/nspe/common/pal_common.h
@@ -0,0 +1,116 @@
+/** @file
+ * Copyright (c) 2019, Arm Limited or its affiliates. All rights reserved.
+ * SPDX-License-Identifier : Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+**/
+
+#ifndef _PAL_COMMON_H_
+#define _PAL_COMMON_H_
+
+#include <string.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <limits.h>
+#include <stdarg.h>
+
+#include "pal_config.h"
+#include "pal_crypto_config.h"
+
+/* typedef's */
+typedef uint8_t             bool_t;
+typedef uintptr_t           addr_t;
+typedef uint32_t            test_id_t;
+typedef uint32_t            block_id_t;
+typedef char                char8_t;
+typedef uint32_t            cfg_id_t;
+
+#define PAL_STATUS_UNSUPPORTED_FUNC      0xFF
+
+typedef enum
+{
+    PAL_STATUS_SUCCESS = 0x0,
+    PAL_STATUS_ERROR   = 0x80
+} pal_status_t;
+
+typedef enum {
+    NVMEM_READ             = 0x1,
+    NVMEM_WRITE            = 0x2,
+} nvmem_fn_type_t;
+
+typedef struct {
+    nvmem_fn_type_t nvmem_fn_type;
+    addr_t base;
+    uint32_t offset;
+    int size;
+} nvmem_param_t;
+
+typedef enum {
+    WD_INIT_SEQ         = 0x1,
+    WD_ENABLE_SEQ       = 0x2,
+    WD_DISABLE_SEQ      = 0x3,
+    WD_STATUS_SEQ       = 0x4,
+} wd_fn_type_t;
+
+typedef enum {
+    WD_LOW_TIMEOUT      = 0x1,
+    WD_MEDIUM_TIMEOUT   = 0x2,
+    WD_HIGH_TIMEOUT     = 0x3,
+    WD_CRYPTO_TIMEOUT   = 0x4,
+} wd_timeout_type_t;
+
+typedef struct {
+    wd_fn_type_t wd_fn_type;
+    addr_t       wd_base_addr;
+    uint32_t     wd_time_us;
+    uint32_t     wd_timer_tick_us;
+} wd_param_t;
+
+typedef enum {
+    UART_INIT             = 0x1,
+    UART_PRINT            = 0x2,
+} uart_fn_type_t;
+
+/*
+ * Redefining some of the client.h elements for compilation to go through
+ * when PSA IPC APIs are not implemented.
+ */
+#ifndef IPC
+
+#ifndef PSA_VERSION_NONE
+#define PSA_VERSION_NONE            (0)
+#endif
+
+#ifndef PSA_SUCCESS
+#define PSA_SUCCESS                 (0)
+typedef int32_t psa_status_t;
+#endif
+typedef int32_t psa_handle_t;
+
+#ifndef PSA_NULL_HANDLE
+#define PSA_NULL_HANDLE             ((psa_handle_t)0)
+#endif
+
+typedef struct psa_invec {
+    const void *base;
+    size_t len;
+} psa_invec;
+
+typedef struct psa_outvec {
+    void *base;
+    size_t len;
+} psa_outvec;
+
+#endif /* IPC */
+
+#endif /* _PAL_COMMON_H_ */
diff --git a/api-tests/platform/targets/tgt_dev_apis_stdc/nspe/common/pal_config.h b/api-tests/platform/targets/tgt_dev_apis_stdc/nspe/common/pal_config.h
new file mode 100644
index 0000000..2871339
--- /dev/null
+++ b/api-tests/platform/targets/tgt_dev_apis_stdc/nspe/common/pal_config.h
@@ -0,0 +1,88 @@
+/** @file
+ * Copyright (c) 2019, Arm Limited or its affiliates. All rights reserved.
+ * SPDX-License-Identifier : Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+**/
+
+#ifndef _PAL_CONFIG_H_
+#define _PAL_CONFIG_H_
+
+/* Define PSA test suite dependent macros for non-cmake build */
+#if !defined(PSA_CMAKE_BUILD)
+
+/* Print verbosity = TEST */
+#define VERBOSE 3
+
+/* NSPE or SPE VAL build? */
+#define VAL_NSPE_BUILD
+
+/* NSPE or SPE TEST build? */
+#define NONSECURE_TEST_BUILD
+
+/* Combine test archive or binary? */
+#define TEST_COMBINE_ARCHIVE
+
+/* If not defined, skip watchdog programming */
+#define WATCHDOG_AVAILABLE
+
+/* Are Dynamic memory APIs available to secure partition? */
+#define SP_HEAP_MEM_SUPP
+#endif /* PSA_CMAKE_BUILD */
+
+/* Version of crypto spec used in attestation */
+#define CRYPTO_VERSION_BETA2
+
+/*
+ * Include of PSA defined Header files
+ */
+#ifdef IPC
+/* psa/client.h: Contains the PSA Client API elements */
+#include "psa/client.h"
+
+/*
+ * psa_manifest/sid.h:  Macro definitions derived from manifest files that map from RoT Service
+ * names to Service IDs (SIDs). Partition manifest parse build tool must provide the implementation
+ * of this file.
+*/
+#include "psa_manifest/sid.h"
+
+/*
+ * psa_manifest/pid.h: Secure Partition IDs
+ * Macro definitions that map from Secure Partition names to Secure Partition IDs.
+ * Partition manifest parse build tool must provide the implementation of this file.
+*/
+#include "psa_manifest/pid.h"
+#endif
+
+#ifdef CRYPTO
+/* psa/crypto.h: Contains the PSA Crypto API elements */
+#include "psa/crypto.h"
+#endif
+
+#ifdef INTERNAL_TRUSTED_STORAGE
+/* psa/internal_trusted_storage.h: Contains the PSA ITS API elements */
+#include "psa/internal_trusted_storage.h"
+#endif
+
+#ifdef PROTECTED_STORAGE
+/* psa/protected_storage.h: Contains the PSA PS API elements */
+#include "psa/protected_storage.h"
+#endif
+
+#ifdef INITIAL_ATTESTATION
+/* psa/initial_attestation.h: Contains the PSA Initial Attestation API elements */
+#include "psa/initial_attestation.h"
+#endif
+
+#endif /* _PAL_CONFIG_H_ */
diff --git a/api-tests/platform/targets/tgt_dev_apis_stdc/nspe/common/pal_driver_ns_intf.c b/api-tests/platform/targets/tgt_dev_apis_stdc/nspe/common/pal_driver_ns_intf.c
new file mode 100644
index 0000000..204adfb
--- /dev/null
+++ b/api-tests/platform/targets/tgt_dev_apis_stdc/nspe/common/pal_driver_ns_intf.c
@@ -0,0 +1,209 @@
+/** @file
+ * Copyright (c) 2019, Arm Limited or its affiliates. All rights reserved.
+ * SPDX-License-Identifier : Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+**/
+
+#include <inttypes.h>
+#include <limits.h>
+#include <stddef.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "pal_common.h"
+
+/* This stdc implementation doesn't support tests that involve resets of the
+ * test process or the system, so we don't actually need non-volatile memory.
+ * Just implement the "nvmem" as an array in memory.
+ */
+
+/* Using zero as NVMEM_BASE is a bit arbitrary - we don't actually need callers
+ * to specify a base address but the nvmem function signatures have "base" params.
+ * Zero is the value used in our target.cfg file so that's what we should recieve.
+ */
+#define NVMEM_BASE 0
+
+#define NVMEM_SIZE (1024)
+static uint8_t g_nvmem[NVMEM_SIZE];
+
+/**
+    @brief    - Check that an nvmem access is within the bounds of the nvmem
+    @param    - base    : Base address of nvmem (must be zero)
+                offset  : Offset into nvmem
+                size    : Number of bytes
+    @return   - SUCCESS/FAILURE
+**/
+static int nvmem_check_bounds(addr_t base, uint32_t offset, int size)
+{
+    if (base != NVMEM_BASE)
+    {
+        return PAL_STATUS_ERROR;
+    }
+    if (offset > NVMEM_SIZE)
+    {
+        return PAL_STATUS_ERROR;
+    }
+    if (size < 0)
+    {
+        return PAL_STATUS_ERROR;
+    }
+    if (offset > INT_MAX - size)
+    {
+        return PAL_STATUS_ERROR;
+    }
+    if (offset + size > NVMEM_SIZE)
+    {
+        return PAL_STATUS_ERROR;
+    }
+    return PAL_STATUS_SUCCESS;
+}
+
+/**
+    @brief    - Reads from given non-volatile address.
+    @param    - base    : Base address of nvmem (must be zero)
+                offset  : Offset
+                buffer  : Pointer to dest address
+                size    : Number of bytes
+    @return   - SUCCESS/FAILURE
+**/
+int pal_nvmem_read_ns(addr_t base, uint32_t offset, void *buffer, int size)
+{
+    if (nvmem_check_bounds(base, offset, size) != PAL_STATUS_SUCCESS)
+    {
+        return PAL_STATUS_ERROR;
+    }
+    memcpy(buffer, g_nvmem + offset, size);
+    return PAL_STATUS_SUCCESS;
+}
+
+/**
+    @brief    - Writes into given non-volatile address.
+    @param    - base    : Base address of nvmem (must be zero)
+                offset  : Offset
+                buffer  : Pointer to source address
+                size    : Number of bytes
+    @return   - SUCCESS/FAILURE
+**/
+int pal_nvmem_write_ns(addr_t base, uint32_t offset, void *buffer, int size)
+{
+    if (nvmem_check_bounds(base, offset, size) != PAL_STATUS_SUCCESS)
+    {
+        return PAL_STATUS_ERROR;
+    }
+    memcpy(g_nvmem + offset, buffer, size);
+    return PAL_STATUS_SUCCESS;
+}
+
+/**
+    @brief    - This function initializes the UART
+
+    This implementation doesn't actually use a UART to print test output, we
+    just send it to stdout. No init necessary.
+
+    @param    - uart base addr (ignored)
+    @return   - SUCCESS/FAILURE
+**/
+int pal_uart_init_ns(uint32_t uart_base_addr)
+{
+    return PAL_STATUS_SUCCESS;
+}
+
+/**
+    @brief    - This function parses the input string and writes bytes into UART TX FIFO
+
+    This implementation doesn't actually use a UART to print test output, we
+    just send it to stdout.
+
+    @param    - str      : Input String
+              - data     : Value for format specifier
+    @return   - SUCCESS/FAILURE
+**/
+int pal_print_ns(char *str, int32_t data)
+{
+    if (printf(str, data) < 0)
+    {
+        return PAL_STATUS_ERROR;
+    }
+    return PAL_STATUS_SUCCESS;
+}
+
+/**
+    @brief           - Initializes an hardware watchdog timer
+
+    This implementation doesn't support watchdogs so this is a noop.
+
+    @param           - base_addr       : Base address of the watchdog module
+                     - time_us         : Time in micro seconds
+                     - timer_tick_us   : Number of ticks per micro second
+    @return          - SUCCESS/FAILURE
+**/
+int pal_wd_timer_init_ns(addr_t base_addr, uint32_t time_us, uint32_t timer_tick_us)
+{
+    return PAL_STATUS_SUCCESS;
+}
+
+/**
+    @brief           - Enables a hardware watchdog timer
+
+    This implementation doesn't support watchdogs so this is a noop.
+
+    @param           - base_addr       : Base address of the watchdog module
+    @return          - SUCCESS/FAILURE
+**/
+int pal_wd_timer_enable_ns(addr_t base_addr)
+{
+    return PAL_STATUS_SUCCESS;
+}
+
+/**
+    @brief           - Disables a hardware watchdog timer
+
+    This implementation doesn't support watchdogs so this is a noop.
+
+    @param           - base_addr  : Base address of the watchdog module
+    @return          - SUCCESS/FAILURE
+**/
+int pal_wd_timer_disable_ns(addr_t base_addr)
+{
+    return PAL_STATUS_SUCCESS;
+}
+
+/**
+     @brief    - This function will read peripherals using SPI commands
+
+    This implementation doesn't support SPI so this is a noop.
+
+     @param    - addr : address of the peripheral
+                 data : read buffer
+                 len  : length of the read buffer in bytes
+     @return   - error status
+**/
+int pal_spi_read(addr_t addr, uint8_t *data, uint32_t len)
+{
+    return PAL_STATUS_ERROR;
+}
+
+/**
+     @brief    - Terminates the simulation at the end of all tests completion.
+
+     This implementation just calls exit.
+
+     @param    - void
+     @return   - void
+**/
+void pal_terminate_simulation(void)
+{
+    ;
+}
diff --git a/api-tests/platform/targets/tgt_dev_apis_stdc/nspe/crypto/pal_crypto_config.h b/api-tests/platform/targets/tgt_dev_apis_stdc/nspe/crypto/pal_crypto_config.h
new file mode 100644
index 0000000..47bb881
--- /dev/null
+++ b/api-tests/platform/targets/tgt_dev_apis_stdc/nspe/crypto/pal_crypto_config.h
@@ -0,0 +1,322 @@
+/** @file
+ * Copyright (c) 2019, Arm Limited or its affiliates. All rights reserved.
+ * SPDX-License-Identifier : Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+**/
+
+/*
+ * \file pal_crypto_config.h
+ *
+ * \brief Configuration options for crypto tests (set of defines)
+ *
+ *  This set of compile-time options may be used to enable
+ *  or disable features selectively for crypto test suite
+ */
+
+#ifndef _PAL_CRYPTO_CONFIG_H_
+#define _PAL_CRYPTO_CONFIG_H_
+/**
+ * \def ARCH_TEST_RSA
+ *
+ * Enable the RSA public-key cryptosystem.
+ * By default all supported keys are enabled.
+ *
+ * Comment macros to disable the types
+ */
+#define ARCH_TEST_RSA
+#define ARCH_TEST_RSA_1024
+#define ARCH_TEST_RSA_2048
+#define ARCH_TEST_RSA_3072
+
+/**
+ * \def  ARCH_TEST_ECC
+ * \def  ARCH_TEST_ECC_CURVE_SECPXXXR1
+ *
+ * Enable the elliptic curve
+ * Enable specific curves within the Elliptic Curve
+ * module.  By default all supported curves are enabled.
+ *
+ * Requires: ARCH_TEST_ECC
+ * Comment macros to disable the curve
+ */
+#define ARCH_TEST_ECC
+#define ARCH_TEST_ECC_CURVE_SECP192R1
+#define ARCH_TEST_ECC_CURVE_SECP224R1
+#define ARCH_TEST_ECC_CURVE_SECP256R1
+#define ARCH_TEST_ECC_CURVE_SECP384R1
+
+/**
+ * \def ARCH_TEST_AES
+ *
+ * Enable the AES block cipher.
+ * By default all supported keys are enabled.
+ *
+ * Comment macros to disable the types
+ */
+#define ARCH_TEST_AES
+#define ARCH_TEST_AES_128
+#define ARCH_TEST_AES_192
+#define ARCH_TEST_AES_256
+#define ARCH_TEST_AES_512
+
+/**
+ * \def  ARCH_TEST_DES
+ *
+ * Enable the DES block cipher.
+ * By default all supported keys are enabled.
+ *
+ * Comment macros to disable the types
+ */
+#define ARCH_TEST_DES
+#define ARCH_TEST_DES_1KEY
+#define ARCH_TEST_DES_2KEY
+#define ARCH_TEST_DES_3KEY
+
+/**
+ * \def  ARCH_TEST_RAW
+ *
+ * A "key" of this type cannot be used for any cryptographic operation.
+ * Applications may use this type to store arbitrary data in the keystore.
+ */
+#define ARCH_TEST_RAW
+
+/**
+ * \def ARCH_TEST_CIPER
+ *
+ * Enable the generic cipher layer.
+ */
+
+#define ARCH_TEST_CIPER
+
+/**
+ * \def ARCH_TEST_ARC4
+ *
+ * Enable the ARC4 key type.
+ */
+#define ARCH_TEST_ARC4
+
+/**
+ * \def ARCH_TEST_CIPER_MODE_CTR
+ *
+ * Enable Counter Block Cipher mode (CTR) for symmetric ciphers.
+ *
+ * Requires: ARCH_TEST_CIPER
+ */
+#define ARCH_TEST_CIPER_MODE_CTR
+
+/**
+ * \def ARCH_TEST_CIPER_MODE_CFB
+ *
+ * Enable Cipher Feedback mode (CFB) for symmetric ciphers.
+ *
+ * Requires: ARCH_TEST_CIPER
+ */
+#define ARCH_TEST_CIPER_MODE_CFB
+
+/**
+ * \def ARCH_TEST_CIPER_MODE_CBC
+ *
+ * Enable Cipher Block Chaining mode (CBC) for symmetric ciphers.
+ *
+ * Requires: ARCH_TEST_CIPER
+ */
+#define ARCH_TEST_CIPER_MODE_CBC
+
+/**
+ * \def ARCH_TEST_CTR_AES
+ *
+ * Requires: ARCH_TEST_CIPER, ARCH_TEST_AES, ARCH_TEST_CIPER_MODE_CTR
+ */
+#define ARCH_TEST_CTR_AES
+
+/**
+ * \def ARCH_TEST_CBC_AES
+ *
+ * Requires: ARCH_TEST_CIPER, ARCH_TEST_AES, ARCH_TEST_CIPER_MODE_CBC
+ *
+ * Comment macros to disable the types
+ */
+#define ARCH_TEST_CBC_AES
+#define ARCH_TEST_CBC_AES_NO_PADDING
+
+/**
+ * \def ARCH_TEST_CBC_NO_PADDING
+ *
+ * Requires: ARCH_TEST_CIPER, ARCH_TEST_CIPER_MODE_CBC
+ *
+ * Comment macros to disable the types
+ */
+#define ARCH_TEST_CBC_NO_PADDING
+
+/**
+ * \def ARCH_TEST_CFB_AES
+ *
+ * Requires: ARCH_TEST_CIPER, ARCH_TEST_AES, ARCH_TEST_CIPER_MODE_CFB
+ */
+#define ARCH_TEST_CFB_AES
+
+/**
+ * \def ARCH_TEST_PKCS1V15_*
+ *
+ * Enable support for PKCS#1 v1.5 encoding.
+ * Enable support for PKCS#1 v1.5 operations.
+ * Enable support for RSA-OAEP
+ *
+ * Requires: ARCH_TEST_RSA, ARCH_TEST_PKCS1V15
+ *
+ * Comment macros to disable the types
+ */
+#define ARCH_TEST_PKCS1V15
+#define ARCH_TEST_RSA_PKCS1V15_SIGN
+#define ARCH_TEST_RSA_PKCS1V15_SIGN_RAW
+#define ARCH_TEST_RSA_PKCS1V15_CRYPT
+#define ARCH_TEST_RSA_OAEP
+
+/**
+ * \def ARCH_TEST_CBC_PKCS7
+ *
+ * Requires: ARCH_TEST_CIPER_MODE_CBC
+ *
+ * Comment macros to disable the types
+ */
+#define ARCH_TEST_CBC_PKCS7
+
+/**
+ * \def ARCH_TEST_ASYMMETRIC_ENCRYPTION
+ *
+ * Enable support for Asymmetric encryption algorithms
+ */
+#define ARCH_TEST_ASYMMETRIC_ENCRYPTION
+
+/**
+ * \def ARCH_TEST_HASH
+ *
+ * Enable the hash algorithm.
+ */
+#define ARCH_TEST_HASH
+
+/**
+ * \def  ARCH_TEST_HMAC
+ *
+ * The key policy determines which underlying hash algorithm the key can be
+ * used for.
+ *
+ * Requires: ARCH_TEST_HASH
+ */
+#define ARCH_TEST_HMAC
+
+/**
+ * \def ARCH_TEST_MDX
+ * \def ARCH_TEST_SHAXXX
+ *
+ * Enable the MDX algorithm.
+ * Enable the SHAXXX algorithm.
+ *
+ * Requires: ARCH_TEST_HASH
+ *
+ * Comment macros to disable the types
+ */
+// #define ARCH_TEST_MD2
+// #define ARCH_TEST_MD4
+#define ARCH_TEST_MD5
+#define ARCH_TEST_RIPEMD160
+#define ARCH_TEST_SHA1
+#define ARCH_TEST_SHA224
+#define ARCH_TEST_SHA256
+#define ARCH_TEST_SHA384
+#define ARCH_TEST_SHA512
+// #define ARCH_TEST_SHA512_224
+// #define ARCH_TEST_SHA512_256
+// #define ARCH_TEST_SHA3_224
+// #define ARCH_TEST_SHA3_256
+// #define ARCH_TEST_SHA3_384
+// #define ARCH_TEST_SHA3_512
+
+/**
+ * \def ARCH_TEST_HKDF
+ *
+ * Enable the HKDF algorithm (RFC 5869).
+ *
+ * Requires: ARCH_TEST_HASH
+*/
+#define ARCH_TEST_HKDF
+
+/**
+ * \def ARCH_TEST_xMAC
+ *
+ * Enable the xMAC (Cipher/Hash/G-based Message Authentication Code) mode for block
+ * ciphers.
+ * Requires: ARCH_TEST_AES or ARCH_TEST_DES
+ *
+ * Comment macros to disable the types
+ */
+#define ARCH_TEST_CMAC
+#define ARCH_TEST_HMAC
+
+/**
+ * \def ARCH_TEST_CCM
+ *
+ * Enable the Counter with CBC-MAC (CCM) mode for 128-bit block cipher.
+ *
+ * Requires: ARCH_TEST_AES
+ */
+#define ARCH_TEST_CCM
+
+/**
+ * \def ARCH_TEST_GCM
+ *
+ * Enable the Galois/Counter Mode (GCM) for AES.
+ *
+ * Requires: ARCH_TEST_AES
+ *
+ */
+#define ARCH_TEST_GCM
+
+/**
+ * \def ARCH_TEST_TRUNCATED_MAC
+ *
+ * Enable support for RFC 6066 truncated HMAC in SSL.
+ *
+ * Comment this macro to disable support for truncated HMAC in SSL
+ */
+#define ARCH_TEST_TRUNCATED_MAC
+
+
+/**
+ * \def ARCH_TEST_ECDH
+ *
+ * Enable the elliptic curve Diffie-Hellman library.
+ *
+ * Requires: ARCH_TEST_ECC
+ */
+#define ARCH_TEST_ECDH
+
+/**
+ * \def ARCH_TEST_ECDSA
+ *
+ * Enable the elliptic curve DSA library.
+ * Requires: ARCH_TEST_ECC
+ */
+#define ARCH_TEST_ECDSA
+
+/**
+ * \def ARCH_TEST_DETERMINISTIC_ECDSA
+ *
+ * Enable deterministic ECDSA (RFC 6979).
+*/
+#define ARCH_TEST_DETERMINISTIC_ECDSA
+
+#include "pal_crypto_config_check.h"
+
+#endif /* _PAL_CRYPTO_CONFIG_H_ */
diff --git a/api-tests/platform/targets/tgt_dev_apis_stdc/nspe/crypto/pal_crypto_config_check.h b/api-tests/platform/targets/tgt_dev_apis_stdc/nspe/crypto/pal_crypto_config_check.h
new file mode 100644
index 0000000..443e0bc
--- /dev/null
+++ b/api-tests/platform/targets/tgt_dev_apis_stdc/nspe/crypto/pal_crypto_config_check.h
@@ -0,0 +1,223 @@
+/** @file
+ * Copyright (c) 2019, Arm Limited or its affiliates. All rights reserved.
+ * SPDX-License-Identifier : Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+**/
+
+/**
+ * \file pal_crypto_config_check.h
+ *
+ * \brief Consistency checks for configuration options
+ *
+ */
+
+#ifndef _PAL_CRYPTO_CONFIG_CHECK_H_
+#define _PAL_CRYPTO_CONFIG_CHECK_H_
+
+#if defined(ARCH_TEST_RSA_1024) && !defined(ARCH_TEST_RSA)
+#error "ARCH_TEST_RSA_1024 defined, but not all prerequisites"
+#endif
+
+#if defined(ARCH_TEST_RSA_2048) && !defined(ARCH_TEST_RSA)
+#error "ARCH_TEST_RSA_2048 defined, but not all prerequisites"
+#endif
+
+#if defined(ARCH_TEST_RSA_3072) && !defined(ARCH_TEST_RSA)
+#error "ARCH_TEST_RSA_3072 defined, but not all prerequisites"
+#endif
+
+#if defined(ARCH_TEST_ECC_CURVE_SECP192R1) && !defined(ARCH_TEST_ECC)
+#error "ARCH_TEST_ECC_CURVE_SECP192R1 defined, but not all prerequisites"
+#endif
+
+#if defined(ARCH_TEST_ECC_CURVE_SECP224R1) && !defined(ARCH_TEST_ECC)
+#error "ARCH_TEST_ECC_CURVE_SECP224R1 defined, but not all prerequisites"
+#endif
+
+#if defined(ARCH_TEST_ECC_CURVE_SECP256R1) && !defined(ARCH_TEST_ECC)
+#error "ARCH_TEST_ECC_CURVE_SECP256R1 defined, but not all prerequisites"
+#endif
+
+#if defined(ARCH_TEST_ECC_CURVE_SECP384R1) && !defined(ARCH_TEST_ECC)
+#error "ARCH_TEST_ECC_CURVE_SECP384R1 defined, but not all prerequisites"
+#endif
+
+#if defined(ARCH_TEST_AES_128) && !defined(ARCH_TEST_AES)
+#error "ARCH_TEST_AES_128 defined, but not all prerequisites"
+#endif
+
+#if defined(ARCH_TEST_AES_256) && !defined(ARCH_TEST_AES)
+#error "ARCH_TEST_AES_256 defined, but not all prerequisites"
+#endif
+
+#if defined(ARCH_TEST_AES_512) && !defined(ARCH_TEST_AES)
+#error "ARCH_TEST_AES_512 defined, but not all prerequisites"
+#endif
+
+#if defined(ARCH_TEST_DES_1KEY) && !defined(ARCH_TEST_DES)
+#error "ARCH_TEST_DES_1KEY defined, but not all prerequisites"
+#endif
+
+#if defined(ARCH_TEST_DES_2KEY) && !defined(ARCH_TEST_DES)
+#error "ARCH_TEST_DES_2KEY defined, but not all prerequisites"
+#endif
+
+#if defined(ARCH_TEST_DES_3KEY) && !defined(ARCH_TEST_DES)
+#error "ARCH_TEST_DES_3KEY defined, but not all prerequisites"
+#endif
+
+#if defined(ARCH_TEST_CIPER_MODE_CTR) && !defined(ARCH_TEST_CIPER)
+#error "ARCH_TEST_CIPER_MODE_CTR defined, but not all prerequisites"
+#endif
+
+#if defined(ARCH_TEST_CIPER_MODE_CFB) && !defined(ARCH_TEST_CIPER)
+#error "ARCH_TEST_CIPER_MODE_CFB defined, but not all prerequisites"
+#endif
+
+#if defined(ARCH_TEST_CIPER_MODE_CBC) && !defined(ARCH_TEST_CIPER)
+#error "ARCH_TEST_CIPER_MODE_CBC defined, but not all prerequisites"
+#endif
+
+#if defined(ARCH_TEST_CTR_AES) &&\
+    (!defined(ARCH_TEST_CIPER) || !defined(ARCH_TEST_AES) || !defined(ARCH_TEST_CIPER_MODE_CTR))
+#error "ARCH_TEST_CTR_AES defined, but not all prerequisites"
+#endif
+
+#if (defined(ARCH_TEST_CBC_AES) || defined(ARCH_TEST_CBC_AES_NO_PADDING)) &&\
+    (!defined(ARCH_TEST_CIPER) || !defined(ARCH_TEST_AES) || !defined(ARCH_TEST_CIPER_MODE_CBC))
+#error "ARCH_TEST_CBC_AES defined, but not all prerequisites"
+#endif
+
+#if (defined(ARCH_TEST_CBC_NO_PADDING)) &&\
+    (!defined(ARCH_TEST_CIPER) || !defined(ARCH_TEST_CIPER_MODE_CBC))
+#error "ARCH_TEST_CBC_NO_PADDING defined, but not all prerequisites"
+#endif
+
+#if defined(ARCH_TEST_CFB_AES) &&\
+    (!defined(ARCH_TEST_CIPER) || !defined(ARCH_TEST_AES) || !defined(ARCH_TEST_CIPER_MODE_CFB))
+#error "ARCH_TEST_CFB_AES defined, but not all prerequisites"
+#endif
+
+#if defined(ARCH_TEST_RSA_PKCS1V15_SIGN) &&\
+    (!defined(ARCH_TEST_RSA) || !defined(ARCH_TEST_PKCS1V15))
+#error "ARCH_TEST_RSA_PKCS1V15_SIGN defined, but not all prerequisites"
+#endif
+
+#if defined(ARCH_TEST_RSA_PKCS1V15_SIGN_RAW) &&\
+    (!defined(ARCH_TEST_RSA) || !defined(ARCH_TEST_PKCS1V15))
+#error "ARCH_TEST_RSA_PKCS1V15_SIGN_RAW defined, but not all prerequisites"
+#endif
+
+#if defined(ARCH_TEST_RSA_PKCS1V15_CRYPT) &&\
+    (!defined(ARCH_TEST_RSA) || !defined(ARCH_TEST_PKCS1V15))
+#error "ARCH_TEST_RSA_PKCS1V15_CRYPT defined, but not all prerequisites"
+#endif
+
+#if defined(ARCH_TEST_CBC_PKCS7) && !defined(ARCH_TEST_CIPER_MODE_CBC)
+#error "ARCH_TEST_CBC_PKCS7 defined, but not all prerequisites"
+#endif
+
+#if defined(ARCH_TEST_HMAC) && !defined(ARCH_TEST_HASH)
+#error "ARCH_TEST_HMAC defined, but not all prerequisites"
+#endif
+
+#if defined(ARCH_TEST_MD2) && !defined(ARCH_TEST_HASH)
+#error "ARCH_TEST_MD2 defined, but not all prerequisites"
+#endif
+
+#if defined(ARCH_TEST_MD4) && !defined(ARCH_TEST_HASH)
+#error "ARCH_TEST_MD4 defined, but not all prerequisites"
+#endif
+
+#if defined(ARCH_TEST_MD5) && !defined(ARCH_TEST_HASH)
+#error "ARCH_TEST_MD5 defined, but not all prerequisites"
+#endif
+
+#if defined(ARCH_TEST_RIPEMD160) && !defined(ARCH_TEST_HASH)
+#error "ARCH_TEST_RIPEMD160 defined, but not all prerequisites"
+#endif
+
+#if defined(ARCH_TEST_SHA1) && !defined(ARCH_TEST_HASH)
+#error "ARCH_TEST_SHA1 defined, but not all prerequisites"
+#endif
+
+#if defined(ARCH_TEST_SHA224) && !defined(ARCH_TEST_HASH)
+#error "ARCH_TEST_SHA224 defined, but not all prerequisites"
+#endif
+
+#if defined(ARCH_TEST_SHA256) && !defined(ARCH_TEST_HASH)
+#error "ARCH_TEST_SHA256 defined, but not all prerequisites"
+#endif
+
+#if defined(ARCH_TEST_SHA512) && !defined(ARCH_TEST_HASH)
+#error "ARCH_TEST_SHA512 defined, but not all prerequisites"
+#endif
+
+#if defined(ARCH_TEST_SHA512_224) && !defined(ARCH_TEST_HASH)
+#error "ARCH_TEST_SHA512_224 defined, but not all prerequisites"
+#endif
+
+#if defined(ARCH_TEST_SHA512_256) && !defined(ARCH_TEST_HASH)
+#error "ARCH_TEST_SHA512_256 defined, but not all prerequisites"
+#endif
+
+#if defined(ARCH_TEST_SHA3_224) && !defined(ARCH_TEST_HASH)
+#error "ARCH_TEST_SHA3_224 defined, but not all prerequisites"
+#endif
+
+#if defined(ARCH_TEST_SHA3_256) && !defined(ARCH_TEST_HASH)
+#error "ARCH_TEST_SHA3_256 defined, but not all prerequisites"
+#endif
+
+#if defined(ARCH_TEST_SHA3_384) && !defined(ARCH_TEST_HASH)
+#error "ARCH_TEST_SHA3_256 defined, but not all prerequisites"
+#endif
+
+#if defined(ARCH_TEST_SHA3_512) && !defined(ARCH_TEST_HASH)
+#error "ARCH_TEST_SHA3_256 defined, but not all prerequisites"
+#endif
+
+#if defined(ARCH_TEST_HKDF) && !defined(ARCH_TEST_HASH)
+#error "ARCH_TEST_HKDF defined, but not all prerequisites"
+#endif
+
+#if defined(ARCH_TEST_CMAC) && !defined(ARCH_TEST_AES)
+#error "ARCH_TEST_CMAC defined, but not all prerequisites"
+#endif
+
+#if defined(ARCH_TEST_GMAC) && !defined(ARCH_TEST_AES)
+#error "ARCH_TEST_GMAC defined, but not all prerequisites"
+#endif
+
+#if defined(ARCH_TEST_HMAC) && !defined(ARCH_TEST_AES)
+#error "ARCH_TEST_HMAC defined, but not all prerequisites"
+#endif
+
+#if defined(ARCH_TEST_CCM) && !defined(ARCH_TEST_AES)
+#error "ARCH_TEST_CCM defined, but not all prerequisites"
+#endif
+
+#if defined(ARCH_TEST_GCM) && !defined(ARCH_TEST_AES)
+#error "ARCH_TEST_GCM defined, but not all prerequisites"
+#endif
+
+#if defined(ARCH_TEST_ECDH) && !defined(ARCH_TEST_ECC)
+#error "ARCH_TEST_ECDH defined, but not all prerequisites"
+#endif
+
+#if defined(ARCH_TEST_ECDSA) && !defined(ARCH_TEST_ECC)
+#error "ARCH_TEST_ECDSA defined, but not all prerequisites"
+#endif
+
+#endif /* _PAL_CRYPTO_CONFIG_CHECK_H_ */
diff --git a/api-tests/platform/targets/tgt_dev_apis_stdc/nspe/crypto/pal_crypto_empty_intf.c b/api-tests/platform/targets/tgt_dev_apis_stdc/nspe/crypto/pal_crypto_empty_intf.c
new file mode 100644
index 0000000..2a28f39
--- /dev/null
+++ b/api-tests/platform/targets/tgt_dev_apis_stdc/nspe/crypto/pal_crypto_empty_intf.c
@@ -0,0 +1,30 @@
+/** @file
+ * Copyright (c) 2019, Arm Limited or its affiliates. All rights reserved.
+ * SPDX-License-Identifier : Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+**/
+
+#include <stdarg.h>
+#include "pal_common.h"
+
+/**
+    @brief    - This API will call the requested crypto function
+    @param    - type    : function code
+                valist  : variable argument list
+    @return   - error status
+**/
+int32_t pal_crypto_function(int type, va_list valist)
+{
+    return PAL_STATUS_ERROR;
+}
diff --git a/api-tests/platform/targets/tgt_dev_apis_stdc/nspe/crypto/pal_crypto_intf.c b/api-tests/platform/targets/tgt_dev_apis_stdc/nspe/crypto/pal_crypto_intf.c
new file mode 100644
index 0000000..fd2e055
--- /dev/null
+++ b/api-tests/platform/targets/tgt_dev_apis_stdc/nspe/crypto/pal_crypto_intf.c
@@ -0,0 +1,506 @@
+/** @file
+ * Copyright (c) 2019, Arm Limited or its affiliates. All rights reserved.
+ * SPDX-License-Identifier : Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+**/
+
+
+#include "pal_crypto_intf.h"
+
+#define  PAL_KEY_SLOT_COUNT  32
+
+/**
+    @brief    - This API will call the requested crypto function
+    @param    - type    : function code
+                valist  : variable argument list
+    @return   - error status
+**/
+int32_t pal_crypto_function(int type, va_list valist)
+{
+    int                              i;
+    psa_status_t                     status;
+    uint8_t                         *buffer, *ciphertext, *plaintext;
+    const uint8_t                   *nonce, *additional_data, *salt, *peer;
+    size_t                          *length, size, ciphertext_size, nonce_length;
+    size_t                           salt_length, peer_length, additional_data_length;
+    size_t                          *tag_length, plaintext_size;
+    psa_aead_operation_t            *aead_operation;
+    psa_key_attributes_t            *attributes;
+    psa_key_handle_t                *handle, key_handle;
+    psa_key_type_t                  *key_type_out, key_type;
+    psa_key_usage_t                 *usage_out, usage;
+    psa_key_id_t                    *key_id_out, key_id;
+    psa_key_lifetime_t              *key_lifetime_out, key_lifetime;
+    psa_algorithm_t                 *key_alg_out, key_alg, alg;
+    psa_hash_operation_t            *hash_operation, *target_operation;
+    psa_mac_operation_t             *mac_operation;
+    psa_cipher_operation_t          *cipher_operation;
+    psa_key_derivation_operation_t  *derive_operation;
+    psa_key_derivation_step_t        step;
+    switch (type)
+    {
+        case PAL_CRYPTO_INIT:
+            return psa_crypto_init();
+        case PAL_CRYPTO_GENERATE_RANDOM:
+            buffer = va_arg(valist, uint8_t *);
+            size = va_arg(valist, int);
+            return psa_generate_random(buffer, size);
+        case PAL_CRYPTO_IMPORT_KEY:
+            attributes = va_arg(valist, psa_key_attributes_t *);
+            buffer = va_arg(valist, uint8_t *);
+            size = va_arg(valist, size_t);
+            handle = (psa_key_handle_t *)va_arg(valist, int *);
+            status = psa_import_key(attributes, buffer, size, handle);
+            return status;
+        case PAL_CRYPTO_SET_KEY_TYPE:
+            attributes = va_arg(valist, psa_key_attributes_t *);
+            key_type = va_arg(valist, psa_key_type_t);
+            psa_set_key_type(attributes, key_type);
+            return 0;
+        case PAL_CRYPTO_SET_KEY_BITS:
+            attributes = va_arg(valist, psa_key_attributes_t *);
+            size = va_arg(valist, size_t);
+            psa_set_key_bits(attributes, size);
+            return 0;
+        case PAL_CRYPTO_GET_KEY_ATTRIBUTES:
+            key_handle = (psa_key_handle_t)va_arg(valist, int);
+            attributes = va_arg(valist, psa_key_attributes_t *);
+            return psa_get_key_attributes(key_handle, attributes);
+        case PAL_CRYPTO_GET_KEY_TYPE:
+            attributes = va_arg(valist, psa_key_attributes_t *);
+            key_type_out = va_arg(valist, psa_key_type_t *);
+            *key_type_out = psa_get_key_type(attributes);
+            return 0;
+        case PAL_CRYPTO_EXPORT_KEY:
+            key_handle = (psa_key_handle_t)va_arg(valist, int);
+            buffer = (uint8_t *)(va_arg(valist, uint8_t *));
+            size = va_arg(valist, size_t);
+            length = (size_t *)va_arg(valist, size_t *);
+            return psa_export_key(key_handle, buffer, size, length);
+        case PAL_CRYPTO_SET_KEY_USAGE_FLAGS:
+            attributes = va_arg(valist, psa_key_attributes_t *);
+            usage = va_arg(valist, psa_key_usage_t);
+            psa_set_key_usage_flags(attributes, usage);
+            return 0;
+        case PAL_CRYPTO_RESET_KEY_ATTRIBUTES:
+            attributes = va_arg(valist, psa_key_attributes_t *);
+            psa_reset_key_attributes(attributes);
+            return 0;
+        case PAL_CRYPTO_EXPORT_PUBLIC_KEY:
+            key_handle = (psa_key_handle_t)va_arg(valist, int);
+            buffer = (uint8_t *)(va_arg(valist, uint8_t *));
+            size = va_arg(valist, size_t);
+            length = (size_t *)va_arg(valist, size_t *);
+            return psa_export_public_key(key_handle, buffer, size, length);
+        case PAL_CRYPTO_SET_KEY_ID:
+            attributes = va_arg(valist, psa_key_attributes_t *);
+            key_id = va_arg(valist, psa_key_id_t);
+            psa_set_key_id(attributes, key_id);
+            return 0;
+        case PAL_CRYPTO_SET_KEY_LIFETIME:
+            attributes = va_arg(valist, psa_key_attributes_t *);
+            key_lifetime = va_arg(valist, psa_key_lifetime_t);
+            psa_set_key_lifetime(attributes, key_lifetime);
+            return 0;
+        case PAL_CRYPTO_SET_KEY_ALGORITHM:
+            attributes = va_arg(valist, psa_key_attributes_t *);
+            key_alg = va_arg(valist, psa_algorithm_t);
+            psa_set_key_algorithm(attributes, key_alg);
+            return 0;
+        case PAL_CRYPTO_GET_KEY_ID:
+            attributes = va_arg(valist, psa_key_attributes_t *);
+            key_id_out = va_arg(valist, psa_key_id_t *);
+            *key_id_out = psa_get_key_id(attributes);
+            return 0;
+        case PAL_CRYPTO_GET_KEY_LIFETIME:
+            attributes = va_arg(valist, psa_key_attributes_t *);
+            key_lifetime_out = va_arg(valist, psa_key_lifetime_t *);
+            *key_lifetime_out = psa_get_key_lifetime(attributes);
+            return 0;
+        case PAL_CRYPTO_GET_KEY_USAGE_FLAGS:
+            attributes = va_arg(valist, psa_key_attributes_t *);
+            usage_out = va_arg(valist, psa_key_usage_t *);
+            *usage_out = psa_get_key_usage_flags(attributes);
+            return 0;
+        case PAL_CRYPTO_GET_KEY_ALGORITHM:
+            attributes = va_arg(valist, psa_key_attributes_t *);
+            key_alg_out = va_arg(valist, psa_algorithm_t *);
+            *key_alg_out = psa_get_key_algorithm(attributes);
+            return 0;
+        case PAL_CRYPTO_GET_KEY_BITS:
+            attributes = va_arg(valist, psa_key_attributes_t *);
+            length = va_arg(valist, size_t *);
+            *length = psa_get_key_bits(attributes);
+            return 0;
+        case PAL_CRYPTO_DESTROY_KEY:
+            key_handle = (psa_key_handle_t)va_arg(valist, int);
+            return psa_destroy_key(key_handle);
+        case PAL_CRYPTO_HASH_SETUP:
+            hash_operation = va_arg(valist, psa_hash_operation_t*);
+            alg = va_arg(valist, psa_algorithm_t);
+            return psa_hash_setup(hash_operation, alg);
+        case PAL_CRYPTO_HASH_UPDATE:
+            hash_operation = va_arg(valist, psa_hash_operation_t*);
+            buffer = va_arg(valist, uint8_t*);
+            size = va_arg(valist, size_t);
+            return psa_hash_update(hash_operation, buffer, size);
+        case PAL_CRYPTO_HASH_VERIFY:
+            hash_operation = va_arg(valist, psa_hash_operation_t*);
+            buffer = va_arg(valist, uint8_t*);
+            size = va_arg(valist, size_t);
+            return psa_hash_verify(hash_operation, buffer, size);
+        case PAL_CRYPTO_HASH_FINISH:
+            hash_operation = va_arg(valist, psa_hash_operation_t*);
+            buffer = va_arg(valist, uint8_t*);
+            size = va_arg(valist, size_t);
+            length = va_arg(valist, size_t*);
+            return psa_hash_finish(hash_operation, buffer, size, length);
+        case PAL_CRYPTO_HASH_ABORT:
+            hash_operation = va_arg(valist, psa_hash_operation_t*);
+            return psa_hash_abort(hash_operation);
+        case PAL_CRYPTO_HASH_COMPUTE:
+            alg = va_arg(valist, psa_algorithm_t);
+            plaintext = va_arg(valist, uint8_t*);
+            plaintext_size = va_arg(valist, size_t);
+            buffer = va_arg(valist, uint8_t*);
+            size = va_arg(valist, size_t);
+            length = va_arg(valist, size_t*);
+            return psa_hash_compute(alg, plaintext, plaintext_size, buffer, size, length);
+        case PAL_CRYPTO_HASH_COMPARE:
+            alg = va_arg(valist, psa_algorithm_t);
+            plaintext = va_arg(valist, uint8_t*);
+            plaintext_size = va_arg(valist, size_t);
+            buffer = va_arg(valist, uint8_t*);
+            size = va_arg(valist, size_t);
+            return psa_hash_compare(alg, plaintext, plaintext_size, buffer, size);
+        case PAL_CRYPTO_HASH_CLONE:
+            hash_operation = va_arg(valist, psa_hash_operation_t*);
+            target_operation = va_arg(valist, psa_hash_operation_t*);
+            return psa_hash_clone(hash_operation, target_operation);
+        case PAL_CRYPTO_GENERATE_KEY:
+            attributes = va_arg(valist, psa_key_attributes_t *);
+            handle = (psa_key_handle_t *)va_arg(valist, int *);
+            return psa_generate_key(attributes, handle);
+        case PAL_CRYPTO_AEAD_ENCRYPT:
+            key_handle = (psa_key_handle_t)va_arg(valist, int);
+            alg = va_arg(valist, psa_algorithm_t);
+            nonce = va_arg(valist, const uint8_t *);
+            nonce_length = va_arg(valist, size_t);
+            additional_data = va_arg(valist, const uint8_t *);
+            additional_data_length = va_arg(valist, size_t);
+            plaintext = va_arg(valist, uint8_t *);
+            size = va_arg(valist, size_t);
+            ciphertext = va_arg(valist, uint8_t *);
+            ciphertext_size = va_arg(valist, size_t);
+            length = va_arg(valist, size_t*);
+            return psa_aead_encrypt(key_handle, alg, nonce, nonce_length, additional_data,
+            additional_data_length, plaintext, size, ciphertext, ciphertext_size, length);
+        case PAL_CRYPTO_AEAD_DECRYPT:
+            key_handle = (psa_key_handle_t)va_arg(valist, int);
+            alg = va_arg(valist, psa_algorithm_t);
+            nonce = va_arg(valist, const uint8_t *);
+            nonce_length = va_arg(valist, size_t);
+            additional_data = va_arg(valist, const uint8_t *);
+            additional_data_length = va_arg(valist, size_t);
+            ciphertext = va_arg(valist, uint8_t *);
+            ciphertext_size = va_arg(valist, size_t);
+            plaintext = va_arg(valist, uint8_t *);
+            size = va_arg(valist, size_t);
+            length = va_arg(valist, size_t*);
+            return psa_aead_decrypt(key_handle, alg, nonce, nonce_length, additional_data,
+            additional_data_length, ciphertext, ciphertext_size, plaintext, size, length);
+        case PAL_CRYPTO_AEAD_ENCRYPT_SETUP:
+            aead_operation = va_arg(valist, psa_aead_operation_t *);
+            key_handle = (psa_key_handle_t)va_arg(valist, int);
+            alg = va_arg(valist, psa_algorithm_t);
+            return psa_aead_encrypt_setup(aead_operation, key_handle, alg);
+        case PAL_CRYPTO_AEAD_DECRYPT_SETUP:
+            aead_operation = va_arg(valist, psa_aead_operation_t *);
+            key_handle = (psa_key_handle_t)va_arg(valist, int);
+            alg = va_arg(valist, psa_algorithm_t);
+            return psa_aead_decrypt_setup(aead_operation, key_handle, alg);
+        case PAL_CRYPTO_AEAD_GENERATE_NONCE:
+            aead_operation = va_arg(valist, psa_aead_operation_t *);
+            buffer = va_arg(valist, uint8_t*);
+            size = va_arg(valist, size_t);
+            length = (size_t *)va_arg(valist, size_t*);
+            return psa_aead_generate_nonce(aead_operation, buffer, size, length);
+        case PAL_CRYPTO_AEAD_SET_NONCE:
+            aead_operation = va_arg(valist, psa_aead_operation_t *);
+            buffer = va_arg(valist, uint8_t*);
+            size = va_arg(valist, size_t);
+            return psa_aead_set_nonce(aead_operation, buffer, size);
+        case PAL_CRYPTO_AEAD_SET_LENGTHS:
+            aead_operation = va_arg(valist, psa_aead_operation_t *);
+            size = va_arg(valist, size_t);
+            plaintext_size = va_arg(valist, size_t);
+            return psa_aead_set_lengths(aead_operation, size, plaintext_size);
+        case PAL_CRYPTO_AEAD_UPDATE_AD:
+            aead_operation = va_arg(valist, psa_aead_operation_t *);
+            buffer = va_arg(valist, uint8_t*);
+            size = va_arg(valist, size_t);
+            return psa_aead_update_ad(aead_operation, buffer, size);
+        case PAL_CRYPTO_AEAD_UPDATE:
+            aead_operation = va_arg(valist, psa_aead_operation_t *);
+            plaintext = va_arg(valist, uint8_t*);
+            plaintext_size = va_arg(valist, size_t);
+            ciphertext = va_arg(valist, uint8_t*);
+            ciphertext_size = va_arg(valist, size_t);
+            length = va_arg(valist, size_t*);
+            return psa_aead_update(aead_operation, plaintext, plaintext_size, ciphertext,
+            ciphertext_size, length);
+        case PAL_CRYPTO_AEAD_FINISH:
+            aead_operation = va_arg(valist, psa_aead_operation_t *);
+            ciphertext = va_arg(valist, uint8_t*);
+            ciphertext_size = va_arg(valist, size_t);
+            length = va_arg(valist, size_t*);
+            buffer = va_arg(valist, uint8_t*);
+            size = va_arg(valist, size_t);
+            tag_length = (size_t *)va_arg(valist, size_t*);
+            return psa_aead_finish(aead_operation, ciphertext, ciphertext_size, length, buffer,
+            size, tag_length);
+        case PAL_CRYPTO_AEAD_VERIFY:
+            aead_operation = va_arg(valist, psa_aead_operation_t *);
+            plaintext = va_arg(valist, uint8_t*);
+            plaintext_size = va_arg(valist, size_t);
+            length = (size_t *)va_arg(valist, size_t*);
+            buffer = va_arg(valist, uint8_t*);
+            size = va_arg(valist, size_t);
+            return psa_aead_verify(aead_operation, plaintext, plaintext_size, length, buffer, size);
+        case PAL_CRYPTO_AEAD_ABORT:
+            aead_operation = va_arg(valist, psa_aead_operation_t *);
+            return psa_aead_abort(aead_operation);
+        case PAL_CRYPTO_MAC_SIGN_SETUP:
+            mac_operation = va_arg(valist, psa_mac_operation_t*);
+            key_handle = (psa_key_handle_t)va_arg(valist, int);
+            alg = va_arg(valist, psa_algorithm_t);
+            return psa_mac_sign_setup(mac_operation, key_handle, alg);
+        case PAL_CRYPTO_MAC_UPDATE:
+            mac_operation = va_arg(valist, psa_mac_operation_t*);
+            buffer = va_arg(valist, uint8_t*);
+            size = va_arg(valist, size_t);
+            return psa_mac_update(mac_operation, buffer, size);
+        case PAL_CRYPTO_MAC_SIGN_FINISH:
+            mac_operation = va_arg(valist, psa_mac_operation_t*);
+            buffer = va_arg(valist, uint8_t*);
+            size = va_arg(valist, size_t);
+            length = (size_t *)va_arg(valist, size_t*);
+            return psa_mac_sign_finish(mac_operation, buffer, size, length);
+        case PAL_CRYPTO_MAC_VERIFY_SETUP:
+            mac_operation = va_arg(valist, psa_mac_operation_t*);
+            key_handle = (psa_key_handle_t)va_arg(valist, int);
+            alg = va_arg(valist, psa_algorithm_t);
+            return psa_mac_verify_setup(mac_operation, key_handle, alg);
+        case PAL_CRYPTO_MAC_VERIFY_FINISH:
+            mac_operation = va_arg(valist, psa_mac_operation_t*);
+            buffer = va_arg(valist, uint8_t*);
+            size = va_arg(valist, size_t);
+            return psa_mac_verify_finish(mac_operation, buffer, size);
+        case PAL_CRYPTO_MAC_ABORT:
+            mac_operation = va_arg(valist, psa_mac_operation_t*);
+            return psa_mac_abort(mac_operation);
+        case PAL_CRYPTO_MAC_COMPUTE:
+            key_handle = (psa_key_handle_t)va_arg(valist, int);
+            alg = va_arg(valist, psa_algorithm_t);
+            plaintext = va_arg(valist, uint8_t*);
+            plaintext_size = va_arg(valist, size_t);
+            ciphertext = va_arg(valist, uint8_t*);
+            ciphertext_size = va_arg(valist, size_t);
+            length = va_arg(valist, size_t*);
+            return psa_mac_compute(key_handle, alg, plaintext, plaintext_size, ciphertext,
+            ciphertext_size, length);
+        case PAL_CRYPTO_MAC_VERIFY:
+            key_handle = (psa_key_handle_t)va_arg(valist, int);
+            alg = va_arg(valist, psa_algorithm_t);
+            plaintext = va_arg(valist, uint8_t*);
+            plaintext_size = va_arg(valist, size_t);
+            ciphertext = va_arg(valist, uint8_t*);
+            ciphertext_size = va_arg(valist, size_t);
+            return psa_mac_verify(key_handle, alg, plaintext, plaintext_size, ciphertext,
+            ciphertext_size);
+        case PAL_CRYPTO_ASYMMTERIC_ENCRYPT:
+            key_handle = (psa_key_handle_t)va_arg(valist, int);
+            alg = va_arg(valist, psa_algorithm_t);
+            plaintext = va_arg(valist, uint8_t *);
+            size = va_arg(valist, size_t);
+            salt = va_arg(valist, const uint8_t *);
+            salt_length = va_arg(valist, size_t);
+            ciphertext = va_arg(valist, uint8_t *);
+            ciphertext_size = va_arg(valist, size_t);
+            length = va_arg(valist, size_t*);
+            return psa_asymmetric_encrypt(key_handle, alg, plaintext, size, salt, salt_length,
+            ciphertext, ciphertext_size, length);
+        case PAL_CRYPTO_ASYMMTERIC_DECRYPT:
+            key_handle = (psa_key_handle_t)va_arg(valist, int);
+            alg = va_arg(valist, psa_algorithm_t);
+            plaintext = va_arg(valist, uint8_t *);
+            size = va_arg(valist, size_t);
+            salt = va_arg(valist, const uint8_t *);
+            salt_length = va_arg(valist, size_t);
+            ciphertext = va_arg(valist, uint8_t *);
+            ciphertext_size = va_arg(valist, size_t);
+            length = va_arg(valist, size_t*);
+            return psa_asymmetric_decrypt(key_handle, alg, plaintext, size, salt, salt_length,
+            ciphertext, ciphertext_size, length);
+        case PAL_CRYPTO_CIPHER_ENCRYPT_SETUP:
+            cipher_operation =  va_arg(valist, psa_cipher_operation_t *);
+            key_handle = (psa_key_handle_t)va_arg(valist, int);
+            alg = va_arg(valist, psa_algorithm_t);
+            return psa_cipher_encrypt_setup(cipher_operation, key_handle, alg);
+        case PAL_CRYPTO_CIPHER_DECRYPT_SETUP:
+            cipher_operation =  va_arg(valist, psa_cipher_operation_t *);
+            key_handle = (psa_key_handle_t)va_arg(valist, int);
+            alg = va_arg(valist, psa_algorithm_t);
+            return psa_cipher_decrypt_setup(cipher_operation, key_handle, alg);
+        case PAL_CRYPTO_CIPHER_GENERATE_IV:
+            cipher_operation =  va_arg(valist, psa_cipher_operation_t *);
+            buffer = va_arg(valist, uint8_t*);
+            size = va_arg(valist, size_t);
+            length = va_arg(valist, size_t*);
+            return psa_cipher_generate_iv(cipher_operation, buffer, size, length);
+        case PAL_CRYPTO_CIPHER_SET_IV:
+            cipher_operation =  va_arg(valist, psa_cipher_operation_t *);
+            buffer = va_arg(valist, uint8_t*);
+            size = va_arg(valist, size_t);
+            return psa_cipher_set_iv(cipher_operation, buffer, size);
+        case PAL_CRYPTO_CIPHER_UPDATE:
+            cipher_operation =  va_arg(valist, psa_cipher_operation_t *);
+            plaintext = va_arg(valist, uint8_t *);
+            size = va_arg(valist, size_t);
+            ciphertext = va_arg(valist, uint8_t *);
+            ciphertext_size = va_arg(valist, size_t);
+            length = va_arg(valist, size_t*);
+            return psa_cipher_update(cipher_operation, plaintext, size, ciphertext, ciphertext_size,
+            length);
+        case PAL_CRYPTO_CIPHER_FINISH:
+            cipher_operation =  va_arg(valist, psa_cipher_operation_t *);
+            ciphertext = va_arg(valist, uint8_t *);
+            ciphertext_size = va_arg(valist, size_t);
+            length = va_arg(valist, size_t*);
+            return psa_cipher_finish(cipher_operation, ciphertext, ciphertext_size, length);
+        case PAL_CRYPTO_CIPHER_ABORT:
+            cipher_operation =  va_arg(valist, psa_cipher_operation_t *);
+            return psa_cipher_abort(cipher_operation);
+        case PAL_CRYPTO_CIPHER_ENCRYPT:
+            key_handle = (psa_key_handle_t)va_arg(valist, int);
+            alg = va_arg(valist, psa_algorithm_t);
+            plaintext = va_arg(valist, uint8_t *);
+            size = va_arg(valist, size_t);
+            ciphertext = va_arg(valist, uint8_t *);
+            ciphertext_size = va_arg(valist, size_t);
+            length = va_arg(valist, size_t*);
+            return psa_cipher_encrypt(key_handle, alg, plaintext, size, ciphertext, ciphertext_size,
+            length);
+        case PAL_CRYPTO_CIPHER_DECRYPT:
+            key_handle = (psa_key_handle_t)va_arg(valist, int);
+            alg = va_arg(valist, psa_algorithm_t);
+            plaintext = va_arg(valist, uint8_t *);
+            size = va_arg(valist, size_t);
+            ciphertext = va_arg(valist, uint8_t *);
+            ciphertext_size = va_arg(valist, size_t);
+            length = va_arg(valist, size_t*);
+            return psa_cipher_decrypt(key_handle, alg, plaintext, size, ciphertext, ciphertext_size,
+            length);
+        case PAL_CRYPTO_ASYMMTERIC_SIGN:
+            key_handle = (psa_key_handle_t)va_arg(valist, int);
+            alg = va_arg(valist, psa_algorithm_t);
+            buffer = va_arg(valist, uint8_t*);
+            size = va_arg(valist, size_t);
+            ciphertext = va_arg(valist, uint8_t *);
+            ciphertext_size = va_arg(valist, size_t);
+            length = va_arg(valist, size_t*);
+            return psa_asymmetric_sign(key_handle, alg, buffer, size, ciphertext, ciphertext_size,
+            length);
+        case PAL_CRYPTO_ASYMMTERIC_VERIFY:
+            key_handle = (psa_key_handle_t)va_arg(valist, int);
+            alg = va_arg(valist, psa_algorithm_t);
+            buffer = va_arg(valist, uint8_t*);
+            size = va_arg(valist, size_t);
+            ciphertext = va_arg(valist, uint8_t *);
+            ciphertext_size = va_arg(valist, size_t);
+            return psa_asymmetric_verify(key_handle, alg, buffer, size, ciphertext,
+            ciphertext_size);
+        case PAL_CRYPTO_RAW_KEY_AGREEMENT:
+            alg = va_arg(valist, psa_algorithm_t);
+            key_handle = (psa_key_handle_t)va_arg(valist, int);
+            peer = va_arg(valist, uint8_t*);
+            peer_length = va_arg(valist, size_t);
+            buffer = va_arg(valist, uint8_t*);
+            size = va_arg(valist, size_t);
+            length = va_arg(valist, size_t*);
+            return psa_raw_key_agreement(alg, key_handle, peer, peer_length, buffer, size, length);
+        case PAL_CRYPTO_COPY_KEY:
+            key_handle = (psa_key_handle_t)va_arg(valist, int);
+            attributes = va_arg(valist, psa_key_attributes_t *);
+            handle = (psa_key_handle_t *)va_arg(valist, int *);
+            return psa_copy_key(key_handle, attributes, handle);
+        case PAL_CRYPTO_KEY_DERIVATION_SETUP:
+            derive_operation = va_arg(valist, psa_key_derivation_operation_t *);
+            alg = va_arg(valist, psa_algorithm_t);
+            return psa_key_derivation_setup(derive_operation, alg);
+        case PAL_CRYPTO_KEY_DERIVATION_INPUT_BYTES:
+            derive_operation = va_arg(valist, psa_key_derivation_operation_t *);
+            step = (psa_key_derivation_step_t)va_arg(valist, int);
+            buffer = va_arg(valist, uint8_t*);
+            size = va_arg(valist, size_t);
+            return psa_key_derivation_input_bytes(derive_operation, step, buffer, size);
+        case PAL_CRYPTO_KEY_DERIVATION_INPUT_KEY:
+            derive_operation = va_arg(valist, psa_key_derivation_operation_t *);
+            step = (psa_key_derivation_step_t)va_arg(valist, int);
+            key_handle = (psa_key_handle_t)va_arg(valist, int);
+            return psa_key_derivation_input_key(derive_operation, step, key_handle);
+        case PAL_CRYPTO_KEY_DERIVATION_KEY_AGREEMENT:
+            derive_operation = va_arg(valist, psa_key_derivation_operation_t *);
+            step = (psa_key_derivation_step_t)va_arg(valist, int);
+            key_handle = (psa_key_handle_t)va_arg(valist, int);
+            peer = va_arg(valist, uint8_t*);
+            peer_length = va_arg(valist, size_t);
+            return psa_key_derivation_key_agreement(derive_operation, step, key_handle, peer,
+            peer_length);
+        case PAL_CRYPTO_KEY_DERIVATION_OUTPUT_BYTES:
+            derive_operation = va_arg(valist, psa_key_derivation_operation_t *);
+            buffer = va_arg(valist, uint8_t*);
+            size = va_arg(valist, size_t);
+            return psa_key_derivation_output_bytes(derive_operation, buffer, size);
+        case PAL_CRYPTO_KEY_DERIVATION_OUTPUT_KEY:
+            attributes = va_arg(valist, psa_key_attributes_t *);
+            derive_operation = va_arg(valist, psa_key_derivation_operation_t *);
+            handle = (psa_key_handle_t *)va_arg(valist, int *);
+            return psa_key_derivation_output_key(attributes, derive_operation, handle);
+        case PAL_CRYPTO_KEY_DERIVATION_SET_CAPACITY:
+            derive_operation = va_arg(valist, psa_key_derivation_operation_t *);
+            size = va_arg(valist, size_t);
+            return psa_key_derivation_set_capacity(derive_operation, size);
+        case PAL_CRYPTO_KEY_DERIVATION_GET_CAPACITY:
+            derive_operation = va_arg(valist, psa_key_derivation_operation_t *);
+            length = va_arg(valist, size_t *);
+            return psa_key_derivation_get_capacity(derive_operation, length);
+        case PAL_CRYPTO_KEY_DERIVATION_ABORT:
+            derive_operation = va_arg(valist, psa_key_derivation_operation_t *);
+            return psa_key_derivation_abort(derive_operation);
+        case PAL_CRYPTO_OPEN_KEY:
+            key_id = va_arg(valist, psa_key_id_t);
+            handle = (psa_key_handle_t *)va_arg(valist, int *);
+            return psa_open_key(key_id, handle);
+        case PAL_CRYPTO_CLOSE_KEY:
+            key_handle = (psa_key_handle_t)va_arg(valist, int);
+            return psa_close_key(key_handle);
+        case PAL_CRYPTO_FREE:
+            for (i = 0; i < PAL_KEY_SLOT_COUNT; i++)
+                psa_destroy_key(i);
+            return 0;
+        default:
+            return PAL_STATUS_UNSUPPORTED_FUNC;
+    }
+}
diff --git a/api-tests/platform/targets/tgt_dev_apis_stdc/nspe/crypto/pal_crypto_intf.h b/api-tests/platform/targets/tgt_dev_apis_stdc/nspe/crypto/pal_crypto_intf.h
new file mode 100644
index 0000000..486f793
--- /dev/null
+++ b/api-tests/platform/targets/tgt_dev_apis_stdc/nspe/crypto/pal_crypto_intf.h
@@ -0,0 +1,103 @@
+/** @file
+ * Copyright (c) 2019, Arm Limited or its affiliates. All rights reserved.
+ * SPDX-License-Identifier : Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+**/
+
+#ifndef _PAL_CRYPTO_H_
+#define _PAL_CRYPTO_H_
+
+#include "pal_common.h"
+
+enum crypto_function_code {
+    PAL_CRYPTO_INIT                             = 0x1,
+    PAL_CRYPTO_GENERATE_RANDOM                  = 0x2,
+    PAL_CRYPTO_IMPORT_KEY                       = 0x3,
+    PAL_CRYPTO_EXPORT_KEY                       = 0x4,
+    PAL_CRYPTO_EXPORT_PUBLIC_KEY                = 0x5,
+    PAL_CRYPTO_DESTROY_KEY                      = 0x6,
+    PAL_CRYPTO_HASH_SETUP                       = 0x7,
+    PAL_CRYPTO_HASH_UPDATE                      = 0x8,
+    PAL_CRYPTO_HASH_VERIFY                      = 0x9,
+    PAL_CRYPTO_HASH_FINISH                      = 0xA,
+    PAL_CRYPTO_HASH_ABORT                       = 0xB,
+    PAL_CRYPTO_GENERATE_KEY                     = 0xC,
+    PAL_CRYPTO_AEAD_ENCRYPT                     = 0xD,
+    PAL_CRYPTO_AEAD_DECRYPT                     = 0xE,
+    PAL_CRYPTO_MAC_SIGN_SETUP                   = 0xF,
+    PAL_CRYPTO_MAC_UPDATE                       = 0x10,
+    PAL_CRYPTO_MAC_SIGN_FINISH                  = 0x11,
+    PAL_CRYPTO_MAC_VERIFY_SETUP                 = 0x12,
+    PAL_CRYPTO_MAC_VERIFY_FINISH                = 0x13,
+    PAL_CRYPTO_MAC_ABORT                        = 0x14,
+    PAL_CRYPTO_ASYMMTERIC_ENCRYPT               = 0x15,
+    PAL_CRYPTO_ASYMMTERIC_DECRYPT               = 0x16,
+    PAL_CRYPTO_CIPHER_ENCRYPT_SETUP             = 0x17,
+    PAL_CRYPTO_CIPHER_DECRYPT_SETUP             = 0x18,
+    PAL_CRYPTO_CIPHER_GENERATE_IV               = 0x19,
+    PAL_CRYPTO_CIPHER_SET_IV                    = 0x1A,
+    PAL_CRYPTO_CIPHER_UPDATE                    = 0x1B,
+    PAL_CRYPTO_CIPHER_FINISH                    = 0x1C,
+    PAL_CRYPTO_CIPHER_ABORT                     = 0x1D,
+    PAL_CRYPTO_ASYMMTERIC_SIGN                  = 0x1E,
+    PAL_CRYPTO_ASYMMTERIC_VERIFY                = 0x1F,
+    PAL_CRYPTO_COPY_KEY                         = 0x20,
+    PAL_CRYPTO_SET_KEY_TYPE                     = 0x21,
+    PAL_CRYPTO_SET_KEY_BITS                     = 0x22,
+    PAL_CRYPTO_GET_KEY_ATTRIBUTES               = 0x23,
+    PAL_CRYPTO_GET_KEY_TYPE                     = 0x24,
+    PAL_CRYPTO_SET_KEY_USAGE_FLAGS              = 0x25,
+    PAL_CRYPTO_RESET_KEY_ATTRIBUTES             = 0x26,
+    PAL_CRYPTO_SET_KEY_ID                       = 0x27,
+    PAL_CRYPTO_SET_KEY_LIFETIME                 = 0x28,
+    PAL_CRYPTO_SET_KEY_ALGORITHM                = 0x29,
+    PAL_CRYPTO_GET_KEY_ID                       = 0x2A,
+    PAL_CRYPTO_GET_KEY_LIFETIME                 = 0x2B,
+    PAL_CRYPTO_GET_KEY_USAGE_FLAGS              = 0x2C,
+    PAL_CRYPTO_GET_KEY_ALGORITHM                = 0x2D,
+    PAL_CRYPTO_GET_KEY_BITS                     = 0x2E,
+    PAL_CRYPTO_HASH_COMPUTE                     = 0x2F,
+    PAL_CRYPTO_HASH_COMPARE                     = 0x30,
+    PAL_CRYPTO_KEY_DERIVATION_SETUP             = 0x31,
+    PAL_CRYPTO_KEY_DERIVATION_ABORT             = 0x32,
+    PAL_CRYPTO_RAW_KEY_AGREEMENT                = 0x33,
+    PAL_CRYPTO_KEY_DERIVATION_INPUT_BYTES       = 0x34,
+    PAL_CRYPTO_KEY_DERIVATION_INPUT_KEY         = 0x35,
+    PAL_CRYPTO_KEY_DERIVATION_KEY_AGREEMENT     = 0x36,
+    PAL_CRYPTO_KEY_DERIVATION_OUTPUT_BYTES      = 0x37,
+    PAL_CRYPTO_KEY_DERIVATION_OUTPUT_KEY        = 0x38,
+    PAL_CRYPTO_KEY_DERIVATION_SET_CAPACITY      = 0x39,
+    PAL_CRYPTO_KEY_DERIVATION_GET_CAPACITY      = 0x3A,
+    PAL_CRYPTO_HASH_CLONE                       = 0x3B,
+    PAL_CRYPTO_MAC_COMPUTE                      = 0x3C,
+    PAL_CRYPTO_MAC_VERIFY                       = 0x3D,
+    PAL_CRYPTO_CIPHER_ENCRYPT                   = 0x3F,
+    PAL_CRYPTO_CIPHER_DECRYPT                   = 0x40,
+    PAL_CRYPTO_OPEN_KEY                         = 0x41,
+    PAL_CRYPTO_CLOSE_KEY                        = 0x42,
+    PAL_CRYPTO_AEAD_ENCRYPT_SETUP               = 0x43,
+    PAL_CRYPTO_AEAD_DECRYPT_SETUP               = 0x44,
+    PAL_CRYPTO_AEAD_GENERATE_NONCE              = 0x45,
+    PAL_CRYPTO_AEAD_SET_NONCE                   = 0x46,
+    PAL_CRYPTO_AEAD_SET_LENGTHS                 = 0X47,
+    PAL_CRYPTO_AEAD_UPDATE_AD                   = 0x48,
+    PAL_CRYPTO_AEAD_UPDATE                      = 0x49,
+    PAL_CRYPTO_AEAD_FINISH                      = 0x4A,
+    PAL_CRYPTO_AEAD_VERIFY                      = 0x4B,
+    PAL_CRYPTO_AEAD_ABORT                       = 0x4C,
+    PAL_CRYPTO_FREE                             = 0xFE,
+};
+
+int32_t pal_crypto_function(int type, va_list valist);
+#endif /* _PAL_CRYPTO_H_ */
diff --git a/api-tests/platform/targets/tgt_dev_apis_stdc/target.cfg b/api-tests/platform/targets/tgt_dev_apis_stdc/target.cfg
new file mode 100644
index 0000000..daef0db
--- /dev/null
+++ b/api-tests/platform/targets/tgt_dev_apis_stdc/target.cfg
@@ -0,0 +1,63 @@
+///** @file
+// * Copyright (c) 2019, Arm Limited or its affiliates. All rights reserved.
+// * SPDX-License-Identifier : Apache-2.0
+// *
+// * Licensed under the Apache License, Version 2.0 (the "License");
+// * you may not use this file except in compliance with the License.
+// * You may obtain a copy of the License at
+// *
+// *  http://www.apache.org/licenses/LICENSE-2.0
+// *
+// * Unless required by applicable law or agreed to in writing, software
+// * distributed under the License is distributed on an "AS IS" BASIS,
+// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// * See the License for the specific language governing permissions and
+// * limitations under the License.
+//**/
+
+// UART device info
+// In this implementation we don't assume there's a UART device, we just print
+// to stdout, so the values below don't mean much.
+uart.num=1;
+uart.0.base = 0x00000000;
+uart.0.size = 0x0;
+uart.0.intr_id = 0x0;
+uart.0.permission = TYPE_READ_WRITE;
+
+// Watchdog device info
+// In this implementation we don't assume there's a watchdog. Watchdog PAL
+// functions all just return SUCCESS, so the values below don't mean much.
+watchdog.num = 1;
+watchdog.0.base = 0x0;
+watchdog.0.size = 0x0;
+watchdog.0.intr_id = 0x0;
+watchdog.0.permission = TYPE_READ_WRITE;
+watchdog.0.num_of_tick_per_micro_sec = 0x0;
+watchdog.0.timeout_in_micro_sec_low = 0x0;
+watchdog.0.timeout_in_micro_sec_medium = 0x0;
+watchdog.0.timeout_in_micro_sec_high = 0x0;
+watchdog.0.timeout_in_micro_sec_crypto = 0x0;
+
+// In this implementation we don't actually use NV memory - we don't support
+// tests that require process or system restarts so NV memory isn't required.
+// The implementation just uses an array in memory.
+nvmem.num =1;
+nvmem.0.start = 0x0;
+nvmem.0.end = 0x400; // 1KiB
+nvmem.0.permission = TYPE_READ_WRITE;
+
+// Miscellaneous - Test scatter info
+dut.num = 1;
+
+// Start address of 12KB NS memory for test ELF
+dut.0.ns_test_addr = 0x2007F000;
+
+// Start address of combine_test_binary in memory. Memory can be main memory or secondary memory.
+// Size of combine_test_binary = Summation of size of each test ELF file.
+dut.0.ns_start_addr_of_combine_test_binary = 0x2003F000;
+
+// Is combine_test_binary available in RAM?
+dut.0.combine_test_binary_in_ram = AVAILABLE;
+
+// Level of Isolation
+dut.0.implemented_psa_firmware_isolation_level = LEVEL1;
diff --git a/api-tests/platform/targets/tgt_dev_apis_stdc/target.cmake b/api-tests/platform/targets/tgt_dev_apis_stdc/target.cmake
new file mode 100644
index 0000000..38e4db2
--- /dev/null
+++ b/api-tests/platform/targets/tgt_dev_apis_stdc/target.cmake
@@ -0,0 +1,76 @@
+#/** @file
+# * Copyright (c) 2019, Arm Limited or its affiliates. All rights reserved.
+# * SPDX-License-Identifier : Apache-2.0
+# *
+# * Licensed under the Apache License, Version 2.0 (the "License");
+# * you may not use this file except in compliance with the License.
+# * You may obtain a copy of the License at
+# *
+# *  http://www.apache.org/licenses/LICENSE-2.0
+# *
+# * Unless required by applicable law or agreed to in writing, software
+# * distributed under the License is distributed on an "AS IS" BASIS,
+# * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# * See the License for the specific language governing permissions and
+# * limitations under the License.
+#**/
+
+# PAL C source files part of NSPE library
+list(APPEND PAL_SRC_C_NSPE )
+
+# PAL ASM source files part of NSPE library
+list(APPEND PAL_SRC_ASM_NSPE )
+
+# PAL C source files part of SPE library - driver partition
+list(APPEND PAL_SRC_C_DRIVER_SP )
+
+# PAL ASM source files part of SPE library - driver partition
+list(APPEND PAL_SRC_ASM_DRIVER_SP )
+
+
+# Listing all the sources required for given target
+if(${SUITE} STREQUAL "IPC")
+	message(FATAL_ERROR "IPC not supported")
+else()
+	list(APPEND PAL_SRC_C_NSPE
+		# driver files will be compiled as part of NSPE
+		${PSA_ROOT_DIR}/platform/targets/${TARGET}/nspe/common/pal_client_api_empty_intf.c
+		${PSA_ROOT_DIR}/platform/targets/${TARGET}/nspe/common/pal_driver_ns_intf.c
+	)
+endif()
+if(${SUITE} STREQUAL "CRYPTO")
+	list(APPEND PAL_SRC_C_NSPE
+		${PSA_ROOT_DIR}/platform/targets/${TARGET}/nspe/crypto/pal_crypto_intf.c
+	)
+endif()
+if(${SUITE} STREQUAL "PROTECTED_STORAGE")
+	message(FATAL_ERROR "Protected Storage not supported")
+endif()
+if(${SUITE} STREQUAL "INTERNAL_TRUSTED_STORAGE")
+	message(FATAL_ERROR "Internal Trusted Storage not support")
+endif()
+if(${SUITE} STREQUAL "INITIAL_ATTESTATION")
+	message(FATAL_ERROR "Initial attestation not supported")
+endif()
+
+# Create NSPE library
+add_library(${PSA_TARGET_PAL_NSPE_LIB} STATIC ${PAL_SRC_C_NSPE} ${PAL_SRC_ASM_NSPE})
+
+# PSA Include directories
+foreach(psa_inc_path ${PSA_INCLUDE_PATHS})
+	target_include_directories(${PSA_TARGET_PAL_NSPE_LIB} PRIVATE ${psa_inc_path})
+endforeach()
+
+target_include_directories(${PSA_TARGET_PAL_NSPE_LIB} PRIVATE
+	${PSA_ROOT_DIR}/platform/targets/${TARGET}/nspe/common
+	${PSA_ROOT_DIR}/platform/targets/${TARGET}/nspe/crypto
+	${PSA_ROOT_DIR}/platform/targets/${TARGET}/nspe/protected_storage
+	${PSA_ROOT_DIR}/platform/targets/${TARGET}/nspe/internal_trusted_storage
+	${PSA_ROOT_DIR}/platform/targets/${TARGET}/nspe/initial_attestation
+)
+
+if(${SUITE} STREQUAL "INITIAL_ATTESTATION")
+target_include_directories(${PSA_TARGET_PAL_NSPE_LIB} PRIVATE
+	${PSA_QCBOR_INCLUDE_PATH}
+)
+endif()