SMC: Initial release of smc_pa_strl, tf_daemon

These userspace components are used to load secure services in the normal
(non-secure) world. The SMC kernel driver is required to use these binaries.

Secure services enable certain security features such as
hardware-accelerated crypto, secure storage, drm, and much more.

Author: "Trusted Logic <smc_support@trusted-logic.com>." Gerrit refuses to
accept.

Change-Id: Ie81604d3fee31abc319643401c3cc66888f9f848
Signed-off-by: Bryan Buckley <bryan.buckley@ti.com>
Signed-off-by: Trusted Logic <smc_support@trusted-logic.com>
diff --git a/security/NOTICE b/security/NOTICE
new file mode 100755
index 0000000..2cf17f5
--- /dev/null
+++ b/security/NOTICE
@@ -0,0 +1,31 @@
+Submitted on behalf of a third-party: Trusted Logic
+
+/**
+ * Copyright(c) 2011 Trusted Logic.   All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *  * Neither the name Trusted Logic nor the names of its
+ *    contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
diff --git a/security/smc_pa_ctrl/Android.mk b/security/smc_pa_ctrl/Android.mk
new file mode 100644
index 0000000..fe0bdf4
--- /dev/null
+++ b/security/smc_pa_ctrl/Android.mk
@@ -0,0 +1,25 @@
+ifeq ($(TARGET_BOARD_PLATFORM),omap4)
+
+LOCAL_PATH := $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_PRELINK_MODULE := false
+LOCAL_ARM_MODE := arm
+
+LOCAL_SRC_FILES:= \
+	smc_pa_ctrl.c smc_pa_ctrl_linux.c
+
+LOCAL_CFLAGS += -DLINUX
+LOCAL_CFLAGS += -D__ANDROID32__
+
+ifdef S_VERSION_BUILD
+LOCAL_CFLAGS += -DS_VERSION_BUILD=$(S_VERSION_BUILD)
+endif
+
+LOCAL_CFLAGS += -I $(LOCAL_PATH)/../tf_sdk/include/
+
+LOCAL_MODULE:= smc_pa_ctrl
+LOCAL_MODULE_TAGS := optional
+
+include $(BUILD_EXECUTABLE)
+endif
diff --git a/security/smc_pa_ctrl/s_version.h b/security/smc_pa_ctrl/s_version.h
new file mode 100644
index 0000000..139c11f
--- /dev/null
+++ b/security/smc_pa_ctrl/s_version.h
@@ -0,0 +1,114 @@
+/**
+ * Copyright(c) 2011 Trusted Logic.   All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *  * Neither the name Trusted Logic nor the names of its
+ *    contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __S_VERSION_H__
+#define __S_VERSION_H__
+
+/*
+ * Usage: define S_VERSION_BUILD on the compiler's command line.
+ *
+ * Then set:
+ * - S_VERSION_OS
+ * - S_VERSION_PLATFORM
+ * - S_VERSION_MAIN
+ * - S_VERSION_ENG is optional
+ * - S_VERSION_PATCH is optional
+ * - S_VERSION_BUILD = 0 if S_VERSION_BUILD not defined or empty
+ */
+#if defined(WIN32)
+#define S_VERSION_OS "W"          /* "W" for Windows PC (XP, Vista…) */
+#define S_VERSION_PLATFORM "X"    /* "X" for ix86 PC simulators */
+#elif defined(__ANDROID32__)
+#define S_VERSION_OS "A"          /* "A" for Android */
+#define S_VERSION_PLATFORM "G"    /* "G" for 4430 */
+#elif defined(LINUX)
+#define S_VERSION_OS "L"          /* "L" for Linux */
+#define S_VERSION_PLATFORM "X"    /* "X" for ix86 PC simulators */
+#else
+#define S_VERSION_OS "X"          /* "X" for Secure-World */
+#define S_VERSION_PLATFORM "G"    /* "G" for 4430 */
+#endif
+
+/*
+ * This version number must be updated for each new release
+ */
+#define S_VERSION_MAIN  "01.04"
+#define S_VERSION_RESOURCE 1,4,0,S_VERSION_BUILD
+
+/*
+* If this is a patch or engineering version use the following
+* defines to set the version number. Else set these values to 0.
+*/
+#define S_VERSION_PATCH 11
+#define S_VERSION_ENG 0
+
+#ifdef S_VERSION_BUILD
+/* TRICK: detect if S_VERSION is defined but empty */
+#if 0 == S_VERSION_BUILD-0
+#undef  S_VERSION_BUILD
+#define S_VERSION_BUILD 0
+#endif
+#else
+/* S_VERSION_BUILD is not defined */
+#define S_VERSION_BUILD 0
+#endif
+
+#define __STRINGIFY(X) #X
+#define __STRINGIFY2(X) __STRINGIFY(X)
+
+#if S_VERSION_ENG != 0
+#define _S_VERSION_ENG "e" __STRINGIFY2(S_VERSION_ENG)
+#else
+#define _S_VERSION_ENG ""
+#endif
+
+#if S_VERSION_PATCH != 0
+#define _S_VERSION_PATCH "p" __STRINGIFY2(S_VERSION_PATCH)
+#else
+#define _S_VERSION_PATCH ""
+#endif
+
+#if !defined(NDEBUG) || defined(_DEBUG)
+#define S_VERSION_VARIANT "D   "
+#else
+#define S_VERSION_VARIANT "    "
+#endif
+
+#define S_VERSION_STRING \
+	"SMC" \
+	S_VERSION_OS \
+	S_VERSION_PLATFORM \
+	S_VERSION_MAIN \
+	_S_VERSION_PATCH \
+	_S_VERSION_ENG \
+	"."  __STRINGIFY2(S_VERSION_BUILD) " " \
+	S_VERSION_VARIANT
+
+#endif /* __S_VERSION_H__ */
diff --git a/security/smc_pa_ctrl/smc_pa_ctrl.c b/security/smc_pa_ctrl/smc_pa_ctrl.c
new file mode 100644
index 0000000..93db1a5
--- /dev/null
+++ b/security/smc_pa_ctrl/smc_pa_ctrl.c
@@ -0,0 +1,219 @@
+/**
+ * Copyright(c) 2011 Trusted Logic.   All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *  * Neither the name Trusted Logic nor the names of its
+ *    contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "s_type.h"
+#include "s_version.h"
+#include "smc_pa_ctrl_os.h"
+
+
+/*---------------------------------------------------------------------------
+ * Utility Functions
+ *---------------------------------------------------------------------------*/
+
+static void printUsage(bool bSuccess)
+{
+#ifdef BOOT_TIME_PA
+   printf("usage : smc_boot_pa_ctrl <options> [command]\n");
+   printf("   Options:\n");
+   printf("      -h, --help: Print this help\n");
+   printf("   Commands:\n");
+   printf("      -c <conf> : Configuration file path\n");
+   printf("      start <pa_file_path>: load and start the SMC PA\n");
+   printf("\n");
+#else
+   printf("usage : smc_pa_ctrl <options> [command]\n");
+   printf("   Options:\n");
+   printf("      -h, --help: Print this help\n");
+   printf("   Commands:\n");
+   printf("      -c <conf> : Configuration file path\n");
+   printf("      start <pa_file_path>: load and start the SMC PA\n");
+   printf("      stop: stop the SMC PA\n");
+   printf("\n");
+#endif
+
+   exit(bSuccess ? 0 : 1);
+}
+
+
+
+/*---------------------------------------------------------------------------
+ * Application Entry-Point
+ *---------------------------------------------------------------------------*/
+
+int main(int argc, char *argv[])
+{
+   char* pPAFileName = NULL;
+   char* pConfFileName = NULL;
+   int   nCommand = SCX_SMC_PA_CTRL_NONE;
+   int   nStatus = 0;
+
+#ifdef BOOT_TIME_PA
+   printf("SMC BOOT PA Control\n");
+   printf(S_VERSION_STRING "\n");
+#else
+   printf("SMC PA Control\n");
+   printf(S_VERSION_STRING "\n");
+#endif
+
+   /* Skip program name */
+   argv ++;
+   argc --;
+
+   while (argc != 0)
+   {
+      if (argv[0][0] == '-')
+      {
+         /*
+          * This is an option
+          */
+
+         if ((strcmp(argv[0], "--help") == 0) || (strcmp(argv[0], "-h") == 0))
+         {
+            printUsage(true);
+         }
+         else if (strcmp(argv[0], "-c") == 0)
+         {
+            /* Next argument */
+            argc --;
+            argv ++;
+
+            if (argc <= 0)
+            {
+               printf("Missing argument for the option '-c'\n\n");
+               printUsage(false);
+            }
+
+            pConfFileName = malloc(strlen(argv[0]) + 1);
+            if (pConfFileName == NULL)
+            {
+               printf("Out of memory\n");
+               exit(2);
+            }
+
+            strcpy(pConfFileName, argv[0]);
+         }
+         else
+         {
+            printf("Invalid option [%s]\n\n", argv[0]);
+            printUsage(false);
+         }
+      }
+      else
+      {
+         /*
+          * This is a command
+          */
+         if (strcmp(argv[0], "start") == 0)
+         {
+            /* Next argument */
+            argc --;
+            argv ++;
+
+            if (argc <= 0)
+            {
+               printf("Missing argument for the command 'start'\n\n");
+               printUsage(false);
+            }
+
+            pPAFileName = malloc(strlen(argv[0]) + 1);
+            if (pPAFileName == NULL)
+            {
+               printf("Out of memory\n");
+               exit(2);
+            }
+
+            strcpy(pPAFileName, argv[0]);
+
+            nCommand = SCX_SMC_PA_CTRL_START;
+         }
+#ifndef BOOT_TIME_PA
+         else if (strcmp(argv[0], "stop") == 0)
+         {
+            nCommand = SCX_SMC_PA_CTRL_STOP;
+         }
+#endif
+         else
+         {
+            printf("Invalid command [%s]\n\n", argv[0]);
+            printUsage(false);
+         }
+      }
+
+      argc --;
+      argv ++;
+   }
+
+   switch (nCommand)
+   {
+      case SCX_SMC_PA_CTRL_START:
+         /*
+          * Load and execute the SMC PA
+          */
+
+         if (pConfFileName == NULL)
+         {
+            printf("Configuration file path is missing !\n");
+            printUsage(false);
+         }
+
+         nStatus = smcPAStart(pPAFileName, pConfFileName);
+         break;
+
+#ifndef BOOT_TIME_PA
+      case SCX_SMC_PA_CTRL_STOP:
+         /*
+          * Stop the SMC PA
+          */
+
+         if (pConfFileName != NULL)
+         {
+            printf("Configuration file cannot be used with the 'stop' command\n\n");
+            printUsage(false);
+         }
+
+         nStatus = smcPAStop();
+         break;
+#endif
+
+      default:
+         printf("No command specified\n\n");
+         printUsage(false);
+         break;
+   }
+
+   free(pPAFileName);
+   free(pConfFileName);
+
+   return nStatus;
+}
diff --git a/security/smc_pa_ctrl/smc_pa_ctrl_linux.c b/security/smc_pa_ctrl/smc_pa_ctrl_linux.c
new file mode 100644
index 0000000..a0eab92
--- /dev/null
+++ b/security/smc_pa_ctrl/smc_pa_ctrl_linux.c
@@ -0,0 +1,284 @@
+/**
+ * Copyright(c) 2011 Trusted Logic.   All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *  * Neither the name Trusted Logic nor the names of its
+ *    contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#ifndef WIN32
+#include <sys/ioctl.h>
+#include <unistd.h>
+#endif
+#include <fcntl.h>
+#include <errno.h>
+
+#include "smc_pa_ctrl_os.h"
+#include "s_type.h"
+
+#ifndef BOOT_TIME_PA
+#define SMC_DRIVER_NAME    "/dev/tf_ctrl"
+#else
+#define SMC_DRIVER_NAME    "/dev/supervisor"
+#endif
+
+#define IOCTL_SCX_SMC_PA_CTRL \
+         _IOWR('z', 0xFF, SCX_SMC_PA_CTRL)
+
+
+typedef struct
+{
+   uint32_t nPACommand;       /* SCX_PA_CTRL_xxx */
+
+   /* For the SCX_SMC_PA_CTRL_START command only                           */
+   uint32_t nPASize;          /* PA buffer size                            */
+   uint8_t* pPABuffer;        /* PA buffer                                 */
+   uint32_t nConfSize;        /* Configuration buffer size, including the  */
+                              /* zero-terminating character (may be zero)  */
+   uint8_t* pConfBuffer;      /* Configuration buffer, zero-terminated     */
+                              /* string (may be NULL)                      */
+} SCX_SMC_PA_CTRL;
+
+static uint8_t* readLocalFile(const char* pFileName, uint32_t* pnBufferSize, bool bIsString)
+{
+   uint8_t* pBuffer = NULL;
+   FILE*    pFile = NULL;
+   uint32_t nBytesToAllocate;
+   int      nBytesRead;
+   int      nResult;
+
+   struct stat statFile;
+
+   *pnBufferSize = 0;
+
+   if (stat(pFileName, &statFile) != 0)
+   {
+      printf("Cannot read '%s' !\n", pFileName);
+      goto error;
+   }
+
+   nBytesToAllocate = statFile.st_size;
+
+   if (bIsString)
+   {
+      /* Allocate enough room for the zero-terminated string */
+      nBytesToAllocate ++;
+   }
+
+   pBuffer = (uint8_t*)malloc(nBytesToAllocate);
+   if (pBuffer == NULL)
+   {
+      printf("Out of memory for the buffer [%u bytes] !\n", nBytesToAllocate);
+      goto error;
+   }
+
+   pFile = fopen(pFileName, "rb");
+   if (pFile == NULL)
+   {
+      printf("Cannot open '%s' !\n", pFileName);
+      goto error;
+   }
+
+   nBytesRead = fread(pBuffer, 1, statFile.st_size, pFile);
+
+   if (nBytesRead != statFile.st_size)
+   {
+      printf("Cannot read bytes from '%s' [%i] !\n", pFileName, nBytesRead);
+      goto error;
+   }
+
+   nResult = fclose(pFile);
+
+   pFile = NULL;
+
+   if (nResult != 0)
+   {
+      printf("Cannot close '%s' !\n", pFileName);
+      goto error;
+   }
+
+   if (bIsString)
+   {
+      /* Set the zero-terminated string */
+      pBuffer[nBytesRead] = 0;
+   }
+
+   *pnBufferSize = nBytesToAllocate;
+
+   return pBuffer;
+
+   /*
+    * Error handling.
+    */
+
+error:
+   free(pBuffer);
+   if (pFile != NULL)
+   {
+      fclose(pFile);
+   }
+
+   return NULL;
+}
+
+
+
+
+int smcPAStart(const char* pPAFileName, const char* pConfFileName)
+{
+   int fd = 0;
+   int nStatus = 0;
+   SCX_SMC_PA_CTRL paCtrl;
+
+   memset(&paCtrl, 0, sizeof(SCX_SMC_PA_CTRL));
+   paCtrl.nPACommand = SCX_SMC_PA_CTRL_START;
+
+#ifdef BOOT_TIME_PA
+   printf("Starting the SMC BOOT PA '%s'. Driver name : %s", pPAFileName, SMC_DRIVER_NAME);
+#else
+   printf("Starting the SMC PA '%s'", pPAFileName);
+#endif
+   if (pConfFileName != NULL)
+   {
+      printf(" with the Configuration file '%s'", pConfFileName);
+   }
+   else
+   {
+      printf("Configuration file is mandatory\n");
+      nStatus  = -1;
+      goto end;
+   }
+   printf("...\n");
+
+   paCtrl.pPABuffer = readLocalFile(pPAFileName, &paCtrl.nPASize, false);
+   if (paCtrl.pPABuffer == NULL)
+   {
+      nStatus  = -2;
+      goto end;
+   }
+
+   paCtrl.pConfBuffer = readLocalFile(pConfFileName, &paCtrl.nConfSize, false);
+   if (paCtrl.pConfBuffer == NULL)
+   {
+      nStatus  = -4;
+      goto end;
+   }
+
+   #ifndef WIN32
+   fd = open(SMC_DRIVER_NAME, O_RDWR, 0);
+   #endif
+   if (fd == -1)
+   {
+      nStatus = errno;
+#ifdef BOOT_TIME_PA
+      printf("Boot time driver open failed [%d] !\n", nStatus);
+#else
+      printf("SMC driver open failed [%d] !\n", nStatus);
+#endif
+      goto end;
+   }
+
+   #ifndef WIN32
+   nStatus = ioctl(fd, IOCTL_SCX_SMC_PA_CTRL, &paCtrl);
+   #endif
+   if (nStatus != 0)
+   {
+      nStatus = errno;
+#ifdef BOOT_TIME_PA
+      printf("Starting the BOOT TIME PA failed [%d] !\n", nStatus);
+#else
+      printf("Starting the SMC PA failed [%d] !\n", nStatus);
+#endif
+      goto end;
+   }
+
+#ifdef BOOT_TIME_PA
+   printf("Boot time PA '%s' has been launched successfully.\n", pPAFileName);
+#else
+   printf("Starting the SMC PA '%s': Done\n", pPAFileName);
+#endif
+
+end:
+   if (fd != 0)
+   {
+      #ifndef WIN32
+      close(fd);
+      #endif
+   }
+
+   free(paCtrl.pPABuffer);
+   free(paCtrl.pConfBuffer);
+
+   return nStatus;
+}
+
+int smcPAStop(void)
+{
+   int fd = 0;
+   int nStatus = 0;
+   SCX_SMC_PA_CTRL paCtrl;
+
+   memset(&paCtrl, 0, sizeof(SCX_SMC_PA_CTRL));
+   paCtrl.nPACommand = SCX_SMC_PA_CTRL_STOP;
+
+   printf("Stopping the SMC PA...\n");
+
+   #ifndef WIN32
+   fd = open(SMC_DRIVER_NAME, O_RDWR, 0);
+   #endif
+   if (fd == 0)
+   {
+      nStatus = errno;
+      printf("SMC driver open failed [%d] !\n", nStatus);
+      goto end;
+   }
+
+   #ifndef WIN32
+   nStatus = ioctl(fd, IOCTL_SCX_SMC_PA_CTRL, &paCtrl);
+   #endif
+   if (nStatus != 0)
+   {
+      printf("Stopping the SMC PA failed [%d] !\n", nStatus);
+      goto end;
+   }
+
+   printf("Stopping the SMC PA: Done\n");
+
+end:
+
+   if (fd != 0)
+   {
+      #ifndef WIN32
+      close(fd);
+      #endif
+   }
+
+   return nStatus;
+}
diff --git a/security/smc_pa_ctrl/smc_pa_ctrl_os.h b/security/smc_pa_ctrl/smc_pa_ctrl_os.h
new file mode 100644
index 0000000..4e087e5
--- /dev/null
+++ b/security/smc_pa_ctrl/smc_pa_ctrl_os.h
@@ -0,0 +1,61 @@
+/**
+ * Copyright(c) 2011 Trusted Logic.   All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *  * Neither the name Trusted Logic nor the names of its
+ *    contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _SMC_PA_CTRL_OH_H__
+#define _SMC_PA_CTRL_OH_H__
+
+#ifdef __SYMBIAN32__
+#define EXOS_TRACE_ACTIVE
+#define printf RDebugPrintf
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/*
+ * The SCX PA Control types.
+ */
+#define SCX_SMC_PA_CTRL_NONE     0
+#define SCX_SMC_PA_CTRL_START    1
+#define SCX_SMC_PA_CTRL_STOP     2
+
+
+
+int smcPAStart(const char* pPAFileName, const char* pConfFileName);
+int smcPAStop(void);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /*  _SMC_PA_CTRL_OH_H__  */
diff --git a/security/tee_client_api/Android.mk b/security/tee_client_api/Android.mk
new file mode 100644
index 0000000..bfd92f4
--- /dev/null
+++ b/security/tee_client_api/Android.mk
@@ -0,0 +1,25 @@
+ifeq ($(TARGET_BOARD_PLATFORM),omap4)
+
+LOCAL_PATH := $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_PRELINK_MODULE := false
+LOCAL_ARM_MODE := arm
+
+LOCAL_SRC_FILES:= \
+	tee_client_api_linux_driver.c
+
+LOCAL_CFLAGS += -DLINUX
+LOCAL_CFLAGS += -D__ANDROID32__
+
+ifdef S_VERSION_BUILD
+LOCAL_CFLAGS += -DS_VERSION_BUILD=$(S_VERSION_BUILD)
+endif
+
+LOCAL_CFLAGS += -I $(LOCAL_PATH)/../tf_sdk/include/
+
+LOCAL_MODULE:= libtee_client_api_driver
+LOCAL_MODULE_TAGS := optional
+
+include $(BUILD_STATIC_LIBRARY)
+endif
diff --git a/security/tee_client_api/s_version.h b/security/tee_client_api/s_version.h
new file mode 100644
index 0000000..d112ea0
--- /dev/null
+++ b/security/tee_client_api/s_version.h
@@ -0,0 +1,113 @@
+/**
+ * Copyright(c) 2011 Trusted Logic.   All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *  * Neither the name Trusted Logic nor the names of its
+ *    contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#ifndef __S_VERSION_H__
+#define __S_VERSION_H__
+
+/*
+ * Usage: define S_VERSION_BUILD on the compiler's command line.
+ *
+ * Then set:
+ * - S_VERSION_OS
+ * - S_VERSION_PLATFORM
+ * - S_VERSION_MAIN
+ * - S_VERSION_ENG is optional
+ * - S_VERSION_PATCH is optional
+ * - S_VERSION_BUILD = 0 if S_VERSION_BUILD not defined or empty
+ */
+#if defined(WIN32)
+#define S_VERSION_OS "W"          /* "W" for Windows PC (XP, Vista…) */
+#define S_VERSION_PLATFORM "X"    /* "X" for ix86 PC simulators */
+#elif defined(__ANDROID32__)
+#define S_VERSION_OS "A"          /* "A" for Android */
+#define S_VERSION_PLATFORM "G"    /* "G" for 4430 */
+#elif defined(LINUX)
+#define S_VERSION_OS "L"          /* "L" for Linux */
+#define S_VERSION_PLATFORM "X"    /* "X" for ix86 PC simulators */
+#else
+#define S_VERSION_OS "X"          /* "X" for Secure-World */
+#define S_VERSION_PLATFORM "G"    /* "G" for 4430 */
+#endif
+
+/*
+ * This version number must be updated for each new release
+ */
+#define S_VERSION_MAIN  "01.04"
+#define S_VERSION_RESOURCE 1,4,0,S_VERSION_BUILD
+
+/*
+* If this is a patch or engineering version use the following
+* defines to set the version number. Else set these values to 0.
+*/
+#define S_VERSION_PATCH 11
+#define S_VERSION_ENG 0
+
+#ifdef S_VERSION_BUILD
+/* TRICK: detect if S_VERSION is defined but empty */
+#if 0 == S_VERSION_BUILD-0
+#undef  S_VERSION_BUILD
+#define S_VERSION_BUILD 0
+#endif
+#else
+/* S_VERSION_BUILD is not defined */
+#define S_VERSION_BUILD 0
+#endif
+
+#define __STRINGIFY(X) #X
+#define __STRINGIFY2(X) __STRINGIFY(X)
+
+#if S_VERSION_ENG != 0
+#define _S_VERSION_ENG "e" __STRINGIFY2(S_VERSION_ENG)
+#else
+#define _S_VERSION_ENG ""
+#endif
+
+#if S_VERSION_PATCH != 0
+#define _S_VERSION_PATCH "p" __STRINGIFY2(S_VERSION_PATCH)
+#else
+#define _S_VERSION_PATCH ""
+#endif
+
+#if !defined(NDEBUG) || defined(_DEBUG)
+#define S_VERSION_VARIANT "D   "
+#else
+#define S_VERSION_VARIANT "    "
+#endif
+
+#define S_VERSION_STRING \
+	"SMC" \
+	S_VERSION_OS \
+	S_VERSION_PLATFORM \
+	S_VERSION_MAIN \
+	_S_VERSION_PATCH \
+	_S_VERSION_ENG \
+	"."  __STRINGIFY2(S_VERSION_BUILD) " " \
+	S_VERSION_VARIANT
+
+#endif /* __S_VERSION_H__ */
diff --git a/security/tee_client_api/schannel6_logins.h b/security/tee_client_api/schannel6_logins.h
new file mode 100644
index 0000000..ca0cddd
--- /dev/null
+++ b/security/tee_client_api/schannel6_logins.h
@@ -0,0 +1,97 @@
+/**
+ * Copyright(c) 2011 Trusted Logic.   All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *  * Neither the name Trusted Logic nor the names of its
+ *    contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __SCHANNEL6_LOGINS_H__
+#define __SCHANNEL6_LOGINS_H__
+
+#define SCX_LOGIN_PUBLIC              0x00000000
+#define SCX_LOGIN_USER                0x00000001
+#define SCX_LOGIN_GROUP               0x00000002
+#define SCX_LOGIN_APPLICATION         0x00000004
+#define SCX_LOGIN_APPLICATION_USER    0x00000005
+#define SCX_LOGIN_APPLICATION_GROUP   0x00000006
+#define SCX_LOGIN_AUTHENTICATION      0x80000000
+#define SCX_LOGIN_PRIVILEGED          0x80000002
+
+/* Login variants */
+
+#define SCX_LOGIN_VARIANT(mainType, os, variant) \
+   ((mainType) | (1 << 27) | ((os) << 16) | ((variant) << 8))
+
+#define SCX_LOGIN_GET_MAIN_TYPE(type) ((type) & ~SCX_LOGIN_VARIANT(0, 0xFF, 0xFF))
+
+#define SCX_LOGIN_OS_ANY       0x00
+#define SCX_LOGIN_OS_LINUX     0x01
+#define SCX_LOGIN_OS_WINMOBILE 0x02
+#define SCX_LOGIN_OS_SYMBIAN   0x03
+#define SCX_LOGIN_OS_ANDROID   0x04
+
+/* OS-independent variants */
+#define SCX_LOGIN_USER_NONE        SCX_LOGIN_VARIANT(SCX_LOGIN_USER, SCX_LOGIN_OS_ANY, 0xFF)
+#define SCX_LOGIN_GROUP_NONE       SCX_LOGIN_VARIANT(SCX_LOGIN_GROUP, SCX_LOGIN_OS_ANY, 0xFF)
+#define SCX_LOGIN_APPLICATION_USER_NONE \
+               SCX_LOGIN_VARIANT(SCX_LOGIN_APPLICATION_USER, SCX_LOGIN_OS_ANY, 0xFF)
+#define SCX_LOGIN_AUTHENTICATION_BINARY_SHA1_HASH \
+               SCX_LOGIN_VARIANT(SCX_LOGIN_AUTHENTICATION, SCX_LOGIN_OS_ANY, 0x01)
+#define SCX_LOGIN_PRIVILEGED_KERNEL \
+               SCX_LOGIN_VARIANT(SCX_LOGIN_PRIVILEGED, SCX_LOGIN_OS_ANY, 0x01)
+
+/* Linux variants */
+#define SCX_LOGIN_USER_LINUX_EUID     SCX_LOGIN_VARIANT(SCX_LOGIN_USER, SCX_LOGIN_OS_LINUX, 0x01)
+#define SCX_LOGIN_GROUP_LINUX_GID     SCX_LOGIN_VARIANT(SCX_LOGIN_GROUP, SCX_LOGIN_OS_LINUX, 0x01)
+#define SCX_LOGIN_APPLICATION_LINUX_PATH_SHA1_HASH \
+               SCX_LOGIN_VARIANT(SCX_LOGIN_APPLICATION, SCX_LOGIN_OS_LINUX, 0x01)
+#define SCX_LOGIN_APPLICATION_USER_LINUX_PATH_EUID_SHA1_HASH \
+               SCX_LOGIN_VARIANT(SCX_LOGIN_APPLICATION_USER, SCX_LOGIN_OS_LINUX, 0x01)
+#define SCX_LOGIN_APPLICATION_GROUP_LINUX_PATH_GID_SHA1_HASH \
+               SCX_LOGIN_VARIANT(SCX_LOGIN_APPLICATION_GROUP, SCX_LOGIN_OS_LINUX, 0x01)
+
+/* Android variants */
+#define SCX_LOGIN_USER_ANDROID_EUID   SCX_LOGIN_VARIANT(SCX_LOGIN_USER, SCX_LOGIN_OS_ANDROID, 0x01)
+#define SCX_LOGIN_GROUP_ANDROID_GID   SCX_LOGIN_VARIANT(SCX_LOGIN_GROUP, SCX_LOGIN_OS_ANDROID, 0x01)
+#define SCX_LOGIN_APPLICATION_ANDROID_UID \
+               SCX_LOGIN_VARIANT(SCX_LOGIN_APPLICATION, SCX_LOGIN_OS_ANDROID, 0x01)
+#define SCX_LOGIN_APPLICATION_USER_ANDROID_UID_EUID \
+               SCX_LOGIN_VARIANT(SCX_LOGIN_APPLICATION_USER, SCX_LOGIN_OS_ANDROID, 0x01)
+#define SCX_LOGIN_APPLICATION_GROUP_ANDROID_UID_GID \
+               SCX_LOGIN_VARIANT(SCX_LOGIN_APPLICATION_GROUP, SCX_LOGIN_OS_ANDROID, 0x01)
+
+/* Symbian variants */
+#define SCX_LOGIN_APPLICATION_SYMBIAN_UIDS \
+               SCX_LOGIN_VARIANT(SCX_LOGIN_APPLICATION, SCX_LOGIN_OS_SYMBIAN, 0x01)
+#define SCX_LOGIN_APPLICATION_USER_SYMBIAN_UIDS \
+               SCX_LOGIN_VARIANT(SCX_LOGIN_APPLICATION_USER, SCX_LOGIN_OS_SYMBIAN, 0x01)
+#define SCX_LOGIN_APPLICATION_GROUP_SYMBIAN_UIDS \
+               SCX_LOGIN_VARIANT(SCX_LOGIN_APPLICATION_GROUP, SCX_LOGIN_OS_SYMBIAN, 0x01)
+#define SCX_LOGIN_AUTHENTICATION_SYMBIAN_UIDS \
+               SCX_LOGIN_VARIANT(SCX_LOGIN_AUTHENTICATION, SCX_LOGIN_OS_SYMBIAN, 0x01)
+
+
+#endif /* __SCHANNEL6_LOGINS_H__ */
diff --git a/security/tee_client_api/schannel6_protocol.h b/security/tee_client_api/schannel6_protocol.h
new file mode 100644
index 0000000..66ed12c
--- /dev/null
+++ b/security/tee_client_api/schannel6_protocol.h
@@ -0,0 +1,425 @@
+/**
+ * Copyright(c) 2011 Trusted Logic.   All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *  * Neither the name Trusted Logic nor the names of its
+ *    contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __SCHANNEL6_PROTOCOL_H__
+#define __SCHANNEL6_PROTOCOL_H__
+
+#include "s_type.h"
+
+/**
+ * This header file defines some structures needed for the secure channel
+ * protocol. See your Product Reference Manual for a specification of the
+ * SChannel protocol.
+ */
+// jroux to do : remove
+#undef SMC_PROTOCOL_VERSION
+#define SMC_PROTOCOL_VERSION 0x06000000
+
+/**
+ * Time representation.
+ */
+typedef uint64_t SCTIME;
+
+#define SCTIME_IMMEDIATE ((uint64_t) 0x0000000000000000ULL)
+#define SCTIME_INFINITE  ((uint64_t) 0xFFFFFFFFFFFFFFFFULL)
+
+/*
+ * Message types
+ */
+#define SCX_CREATE_DEVICE_CONTEXT   0x02
+#define SCX_DESTROY_DEVICE_CONTEXT  0xFD
+#define SCX_REGISTER_SHARED_MEMORY  0xF7
+#define SCX_RELEASE_SHARED_MEMORY   0xF9
+#define SCX_OPEN_CLIENT_SESSION     0xF0
+#define SCX_CLOSE_CLIENT_SESSION    0xF2
+#define SCX_INVOKE_CLIENT_COMMAND   0xF5
+#define SCX_CANCEL_CLIENT_OPERATION 0xF4
+#define SCX_MANAGEMENT              0xFE
+
+/*
+ * Shared mem flags
+ */
+#define SCX_SHARED_MEM_FLAG_INPUT   1
+#define SCX_SHARED_MEM_FLAG_OUTPUT  2
+#define SCX_SHARED_MEM_FLAG_INOUT   3
+
+/*
+ * Parameter types
+ */
+#define SCX_PARAM_TYPE_NONE                     0x0
+#define SCX_PARAM_TYPE_VALUE_INPUT              0x1
+#define SCX_PARAM_TYPE_VALUE_OUTPUT             0x2
+#define SCX_PARAM_TYPE_VALUE_INOUT              0x3
+#define SCX_PARAM_TYPE_MEMREF_TEMP_INPUT        0x5
+#define SCX_PARAM_TYPE_MEMREF_TEMP_OUTPUT       0x6
+#define SCX_PARAM_TYPE_MEMREF_TEMP_INOUT        0x7
+#define SCX_PARAM_TYPE_MEMREF_INPUT             0xD
+#define SCX_PARAM_TYPE_MEMREF_OUTPUT            0xE
+#define SCX_PARAM_TYPE_MEMREF_INOUT             0xF
+
+#define SCX_PARAM_TYPE_INPUT_FLAG                0x1
+#define SCX_PARAM_TYPE_OUTPUT_FLAG               0x2
+#define SCX_PARAM_TYPE_MEMREF_FLAG               0x4
+#define SCX_PARAM_TYPE_REGISTERED_MEMREF_FLAG    0x8
+
+#define SCX_PARAM_TYPE_IS_TMPREF(nParamType) (((nParamType) & (SCX_PARAM_TYPE_MEMREF_FLAG | SCX_PARAM_TYPE_REGISTERED_MEMREF_FLAG)) == SCX_PARAM_TYPE_MEMREF_FLAG)
+
+#define SCX_MAKE_PARAM_TYPES(t0, t1, t2, t3) ((t0) | ((t1) << 4) | ((t2) << 8) | ((t3) << 12))
+#define SCX_GET_PARAM_TYPE(t, i) (((t) >> (4*i)) & 0xF)
+
+/*
+ * return origins
+ */
+#define SCX_ORIGIN_COMMS       2
+#define SCX_ORIGIN_TEE         3
+#define SCX_ORIGIN_TRUSTED_APP 4
+
+/*
+ * Login types
+ */
+#include "schannel6_logins.h"
+
+/**
+ * Command parameters.
+ */
+typedef struct
+{
+   uint32_t    a;
+   uint32_t    b;
+}SCHANNEL6_COMMAND_PARAM_VALUE;
+
+typedef struct
+{
+   uint32_t    nDescriptor;
+   uint32_t    nSize;
+   uint32_t    nOffset;     /* Socket: 4 weak bits of the address (for alignement checks) */
+
+}SCHANNEL6_COMMAND_PARAM_TEMP_MEMREF;
+
+typedef struct
+{
+   S_HANDLE    hBlock;
+   uint32_t    nSize;
+   uint32_t    nOffset;
+
+}SCHANNEL6_COMMAND_PARAM_MEMREF;
+
+typedef union
+{
+   SCHANNEL6_COMMAND_PARAM_VALUE        sValue;
+   SCHANNEL6_COMMAND_PARAM_TEMP_MEMREF  sTempMemref;
+   SCHANNEL6_COMMAND_PARAM_MEMREF       sMemref;
+
+} SCHANNEL6_COMMAND_PARAM;
+
+typedef struct
+{
+   uint32_t a;
+   uint32_t b;
+} SCHANNEL6_ANSWER_PARAM_VALUE;
+
+typedef struct
+{
+   uint32_t _ignored;
+   uint32_t nSize;
+} SCHANNEL6_ANSWER_PARAM_SIZE;
+
+typedef union
+{
+   SCHANNEL6_ANSWER_PARAM_SIZE  sSize;
+   SCHANNEL6_ANSWER_PARAM_VALUE sValue;
+} SCHANNEL6_ANSWER_PARAM;
+
+/**
+ * Command messages.
+ */
+ typedef struct
+{
+   uint8_t                       nMessageSize;
+   uint8_t                       nMessageType;
+   uint16_t                      nMessageInfo;
+   uint32_t                      nOperationID; /* an opaque Normal World identifier for the operation */
+}SCHANNEL6_COMMAND_HEADER;
+
+typedef struct
+{
+   uint8_t                       nMessageSize;
+   uint8_t                       nMessageType;
+   uint16_t                      nMessageInfo_RFU;
+   uint32_t                      nOperationID; /* an opaque Normal World identifier for the operation */
+   uint32_t                      nDeviceContextID; /* an opaque Normal World identifier for the device context */
+}SCHANNEL6_CREATE_DEVICE_CONTEXT_COMMAND;
+
+typedef struct
+{
+   uint8_t                       nMessageSize;
+   uint8_t                       nMessageType;
+   uint16_t                      nParamTypes;
+   uint32_t                      nOperationID; /* an opaque Normal World identifier for the operation */
+   S_HANDLE                      hDeviceContext;
+   S_HANDLE                      hClientSession;
+   uint64_t                      sTimeout;
+   uint32_t                      nCancellationID;
+   uint32_t                      nClientCommandIdentifier;
+   SCHANNEL6_COMMAND_PARAM       sParams[4];
+}SCHANNEL6_INVOKE_CLIENT_COMMAND_COMMAND;
+
+typedef struct
+{
+   uint8_t                       nMessageSize;
+   uint8_t                       nMessageType;
+   uint16_t                      nParamTypes;
+   uint32_t                      nOperationID; /* an opaque Normal World identifier for the operation */
+   S_HANDLE                      hDeviceContext;
+   uint32_t                      nCancellationID;
+   SCTIME                        sTimeout;
+   S_UUID                        sDestinationUUID;
+   SCHANNEL6_COMMAND_PARAM       sParams[4];
+   uint32_t                      nLoginType;
+   uint8_t                       sLoginData[20]; /* Size depends on the login type. */
+
+}SCHANNEL6_OPEN_CLIENT_SESSION_COMMAND;
+
+typedef struct
+{
+   uint8_t                       nMessageSize;
+   uint8_t                       nMessageType;
+   uint16_t                      nMemoryFlags;
+   uint32_t                      nOperationID; /* an opaque Normal World identifier for the operation */
+   S_HANDLE                      hDeviceContext;
+   uint32_t                      nBlockID;
+   uint32_t                      nSharedMemSize;
+   uint32_t                      nSharedMemStartOffset;
+   uint32_t                      nSharedMemDescriptors[8];
+
+}SCHANNEL6_REGISTER_SHARED_MEMORY_COMMAND;
+
+typedef struct
+{
+   uint8_t                       nMessageSize;
+   uint8_t                       nMessageType;
+   uint16_t                      nMessageInfo_RFU;
+   uint32_t                      nOperationID; /* an opaque Normal World identifier for the operation */
+   S_HANDLE                      hDeviceContext;
+   S_HANDLE                      hBlock;
+
+}SCHANNEL6_RELEASE_SHARED_MEMORY_COMMAND;
+
+typedef struct
+{
+   uint8_t                       nMessageSize;
+   uint8_t                       nMessageType;
+   uint16_t                      nMessageInfo_RFU;
+   uint32_t                      nOperationID; /* an opaque Normal World identifier for the operation */
+   S_HANDLE                      hDeviceContext;
+   S_HANDLE                      hClientSession;
+   uint32_t                      nCancellationID;
+
+}SCHANNEL6_CANCEL_CLIENT_OPERATION_COMMAND;
+
+typedef struct
+{
+   uint8_t                       nMessageSize;
+   uint8_t                       nMessageType;
+   uint16_t                      nMessageInfo_RFU;
+   uint32_t                      nOperationID; /* an opaque Normal World identifier for the operation */
+   S_HANDLE                      hDeviceContext;
+   S_HANDLE                      hClientSession;
+
+}SCHANNEL6_CLOSE_CLIENT_SESSION_COMMAND;
+
+typedef struct
+{
+   uint8_t                       nMessageSize;
+   uint8_t                       nMessageType;
+   uint16_t                      nMessageInfo_RFU;
+   uint32_t                      nOperationID; /* an opaque Normal World identifier for the operation */
+   S_HANDLE                      hDeviceContext;
+
+}SCHANNEL6_DESTROY_DEVICE_CONTEXT_COMMAND;
+
+#define SCHANNEL6_MANAGEMENT_COMMAND_HIBERNATE            1
+#define SCHANNEL6_MANAGEMENT_COMMAND_SHUTDOWN             2
+#define SCHANNEL6_MANAGEMENT_COMMAND_PREPARE_FOR_CORE_OFF 3
+#define SCHANNEL6_MANAGEMENT_COMMAND_RESUME_FROM_CORE_OFF 4
+
+typedef struct
+{
+   uint8_t                       nMessageSize;
+   uint8_t                       nMessageType;
+   uint16_t                      nCommand;
+   uint32_t                      nOperationID; /* an opaque Normal World identifier for the operation */
+   uint32_t                      nW3BSize;
+   uint32_t                      nW3BStartOffset;
+#ifdef SCHANNEL_TRUSTZONE
+   uint32_t                      nSharedMemDescriptors[128];
+#endif
+}SCHANNEL6_MANAGEMENT_COMMAND;
+
+typedef union
+{
+   SCHANNEL6_COMMAND_HEADER                            sHeader;
+   SCHANNEL6_CREATE_DEVICE_CONTEXT_COMMAND             sCreateDeviceContext;
+   SCHANNEL6_DESTROY_DEVICE_CONTEXT_COMMAND            sDestroyDeviceContext;
+   SCHANNEL6_OPEN_CLIENT_SESSION_COMMAND               sOpenClientSession;
+   SCHANNEL6_CLOSE_CLIENT_SESSION_COMMAND              sCloseClientSession;
+   SCHANNEL6_REGISTER_SHARED_MEMORY_COMMAND            sRegisterSharedMemory;
+   SCHANNEL6_RELEASE_SHARED_MEMORY_COMMAND             sReleaseSharedMemory;
+   SCHANNEL6_INVOKE_CLIENT_COMMAND_COMMAND             sInvokeClientCommand;
+   SCHANNEL6_CANCEL_CLIENT_OPERATION_COMMAND           sCancelClientOperation;
+   SCHANNEL6_MANAGEMENT_COMMAND                        sManagement;
+
+}SCHANNEL6_COMMAND;
+
+/**
+ * Answer messages.
+ */
+typedef struct
+{
+   uint8_t                   nMessageSize;
+   uint8_t                   nMessageType;
+   uint16_t                  nMessageInfo;
+   uint32_t                  nOperationID;
+   uint32_t                  nErrorCode;
+}SCHANNEL6_ANSWER_HEADER;
+
+typedef struct
+{
+   uint8_t                   nMessageSize;
+   uint8_t                   nMessageType;
+   uint16_t                  nMessageInfo_RFU;
+   uint32_t                  nOperationID;
+   uint32_t                  nErrorCode;
+   S_HANDLE                  hDeviceContext;
+}SCHANNEL6_CREATE_DEVICE_CONTEXT_ANSWER;
+
+typedef struct
+{
+   uint8_t                   nMessageSize;
+   uint8_t                   nMessageType;
+   uint8_t                   nReturnOrigin;
+   uint8_t                   __nReserved;
+   uint32_t                  nOperationID;
+   uint32_t                  nErrorCode;
+   SCHANNEL6_ANSWER_PARAM    sAnswers[4];
+
+}SCHANNEL6_INVOKE_CLIENT_COMMAND_ANSWER;
+
+typedef struct
+{
+   uint8_t                   nMessageSize;
+   uint8_t                   nMessageType;
+   uint8_t                   nReturnOrigin;
+   uint8_t                   __nReserved;
+   uint32_t                  nOperationID;
+   uint32_t                  nErrorCode;
+   S_HANDLE                  hClientSession;
+   SCHANNEL6_ANSWER_PARAM    sAnswers[4];
+}SCHANNEL6_OPEN_CLIENT_SESSION_ANSWER;
+
+typedef struct
+{
+   uint8_t                   nMessageSize;
+   uint8_t                   nMessageType;
+   uint16_t                  nMessageInfo_RFU;
+   uint32_t                  nOperationID;
+   uint32_t                  nErrorCode;
+}SCHANNEL6_CLOSE_CLIENT_SESSION_ANSWER;
+
+typedef struct
+{
+   uint8_t                   nMessageSize;
+   uint8_t                   nMessageType;
+   uint16_t                  nMessageInfo_RFU;
+   uint32_t                  nOperationID;
+   uint32_t                  nErrorCode;
+   S_HANDLE                  hBlock;
+
+}SCHANNEL6_REGISTER_SHARED_MEMORY_ANSWER;
+
+typedef struct
+{
+   uint8_t                   nMessageSize;
+   uint8_t                   nMessageType;
+   uint16_t                  nMessageInfo_RFU;
+   uint32_t                  nOperationID;
+   uint32_t                  nErrorCode;
+   uint32_t                  nBlockID;
+
+}SCHANNEL6_RELEASE_SHARED_MEMORY_ANSWER;
+
+typedef struct
+{
+   uint8_t                   nMessageSize;
+   uint8_t                   nMessageType;
+   uint16_t                  nMessageInfo_RFU;
+   uint32_t                  nOperationID;
+   uint32_t                  nErrorCode;
+   uint32_t                  nDeviceContextID;
+
+}SCHANNEL6_DESTROY_DEVICE_CONTEXT_ANSWER;
+
+typedef struct
+{
+   uint8_t                   nMessageSize;
+   uint8_t                   nMessageType;
+   uint16_t                  nMessageInfo_RFU;
+   uint32_t                  nOperationID;
+   uint32_t                  nErrorCode;
+
+}SCHANNEL6_CANCEL_CLIENT_OPERATION_ANSWER;
+
+typedef struct
+{
+   uint8_t                   nMessageSize;
+   uint8_t                   nMessageType;
+   uint16_t                  nMessageInfo_RFU;
+   uint32_t                  nOperationID;
+   uint32_t                  nErrorCode;
+
+}SCHANNEL6_MANAGEMENT_ANSWER;
+
+typedef union
+{
+   SCHANNEL6_ANSWER_HEADER                    sHeader;
+   SCHANNEL6_CREATE_DEVICE_CONTEXT_ANSWER     sCreateDeviceContext;
+   SCHANNEL6_OPEN_CLIENT_SESSION_ANSWER       sOpenClientSession;
+   SCHANNEL6_REGISTER_SHARED_MEMORY_ANSWER    sRegisterSharedMemory;
+   SCHANNEL6_RELEASE_SHARED_MEMORY_ANSWER     sReleaseSharedMemory;
+   SCHANNEL6_INVOKE_CLIENT_COMMAND_ANSWER     sInvokeClientCommand;
+   SCHANNEL6_DESTROY_DEVICE_CONTEXT_ANSWER    sDestroyDeviceContext;
+   SCHANNEL6_CANCEL_CLIENT_OPERATION_ANSWER   sCancelClientOperation;
+   SCHANNEL6_CLOSE_CLIENT_SESSION_ANSWER      sCloseClientSession;
+   SCHANNEL6_MANAGEMENT_ANSWER                sManagement;
+
+}SCHANNEL6_ANSWER;
+
+
+#endif /* __SCHANNEL6_PROTOCOL_H__ */
diff --git a/security/tee_client_api/tee_client_api_linux_driver.c b/security/tee_client_api/tee_client_api_linux_driver.c
new file mode 100644
index 0000000..08a8210
--- /dev/null
+++ b/security/tee_client_api/tee_client_api_linux_driver.c
@@ -0,0 +1,929 @@
+/**
+ * Copyright(c) 2011 Trusted Logic.   All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *  * Neither the name Trusted Logic nor the names of its
+ *    contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "tee_client_api.h"
+#include "schannel6_protocol.h"
+#include "s_error.h"
+#include "s_version.h"
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <ctype.h>
+#include <string.h>
+#include <stdarg.h>
+#include <assert.h>
+
+#include <sys/ioctl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/mman.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <unistd.h>
+#include <linux/limits.h>
+#include <time.h>
+#include <sys/time.h>
+
+/*
+ * SCX_VERSION_INFORMATION_BUFFER structure description
+ * Description of the sVersionBuffer handed over from user space to kernel space
+ * This field is filled after an IOCTL call and handed back to user space
+ */
+typedef struct
+{
+   uint8_t sDriverDescription[65];
+   uint8_t sSecureWorldDescription[65];
+} SCX_VERSION_INFORMATION_BUFFER;
+
+
+/* The IOCTLs to the driver */
+#define IOCTL_SCX_GET_VERSION \
+         _IO('z', 0)
+
+#define IOCTL_SCX_EXCHANGE \
+         _IOWR('z', 1, SCHANNEL6_COMMAND)
+
+#define IOCTL_SCX_GET_DESCRIPTION \
+         _IOR('z', 2, SCX_VERSION_INFORMATION_BUFFER)
+
+
+/* Expected driver interface version. */
+#define SM_DRIVER_VERSION 0x04000000
+
+#define SCX_DEFAULT_DEVICE_NAME "tf_driver"
+
+#define SCX_PARAM_TYPE_GET(nParamTypes, i) (((nParamTypes) >> (4*i)) & 0xF)
+
+#define VAR_NOT_USED(variable)  do{(void)(variable);}while(0);
+
+#define SIZE_4KB  0x1000
+#define SIZE_1MB  0x100000
+
+/* ------------------------------------------------------------------------ */
+/*    UTILS                                                                 */
+/* ------------------------------------------------------------------------ */
+#ifdef NDEBUG
+/* Compile-out the traces */
+#define TRACE_ERROR(...)
+#define TRACE_WARNING(...)
+#define TRACE_INFO(...)
+#else
+static void TRACE_ERROR(const char* format, ...)
+{
+   va_list ap;
+   va_start(ap, format);
+   fprintf(stderr, "TRACE: ERROR: ");
+   vfprintf(stderr, format, ap);
+   fprintf(stderr, "\n");
+   va_end(ap);
+}
+
+static void TRACE_WARNING(const char* format, ...)
+{
+   va_list ap;
+   va_start(ap, format);
+   fprintf(stderr, "TRACE: WARNING: ");
+   vfprintf(stderr, format, ap);
+   fprintf(stderr, "\n");
+   va_end(ap);
+}
+
+static void TRACE_INFO(const char* format, ...)
+{
+   va_list ap;
+   va_start(ap, format);
+   fprintf(stderr, "TRACE: ");
+   vfprintf(stderr, format, ap);
+   fprintf(stderr, "\n");
+   va_end(ap);
+}
+#endif /* NDEBUG */
+
+
+/*
+ * ====================================================
+ *                 Internal functions
+ * =====================================================
+*/
+
+static void scxYield(void)
+{
+   sleep(0);
+}
+
+/* ------------------------------------------------------------------------ */
+
+
+/*
+ * Exchange a message with the Secure World
+ * by calling the ioctl command of the linux driver
+ *
+ * @param pContext
+ * @param pCommand a SChannel command message that must have been filled except for the operation parameters
+ * @param pAnswer  a placeholder for the SChannel answer
+ * @param pOperation a TEEC_Operation structure that contains the operation parameters (and types)
+ *                   and is updated with the SChannel answer data as appropriate. This parameter is
+ *                   used only for the open and invoke operations
+ */
+static TEEC_Result scxExchangeMessage(
+   IN  TEEC_Context*     pContext,
+   IN  SCHANNEL6_COMMAND* pCommand,
+   OUT SCHANNEL6_ANSWER*  pAnswer,
+   IN TEEC_Operation* pOperation)
+{
+   TEEC_Result nResult = TEEC_SUCCESS;
+
+   TRACE_INFO("scxExchangeMessage[0x%X]\n",pContext);
+
+   if (pOperation != NULL)
+   {
+      /* Determine message parameters from operation parameters */
+      uint32_t i;
+      SCHANNEL6_COMMAND_PARAM* pSCXParams;
+
+      /* Note that nParamType is at the same position in an open and an invoke message */
+      pCommand->sHeader.nMessageInfo = pOperation->paramTypes;
+
+      if (pCommand->sHeader.nMessageType == SCX_OPEN_CLIENT_SESSION)
+      {
+         pSCXParams = pCommand->sOpenClientSession.sParams;
+      }
+      else
+      {
+         /* An invoke-command */
+         pSCXParams = pCommand->sInvokeClientCommand.sParams;
+      }
+
+      for (i = 0; i < 4; i++)
+      {
+         uint32_t nTEECParamType = SCX_PARAM_TYPE_GET(pOperation->paramTypes, i);
+         TEEC_Parameter*  pTEECParam = &pOperation->params[i];
+         SCHANNEL6_COMMAND_PARAM* pSCXParam = &pSCXParams[i];
+
+         if (nTEECParamType & SCX_PARAM_TYPE_MEMREF_FLAG)
+         {
+            if (nTEECParamType & SCX_PARAM_TYPE_REGISTERED_MEMREF_FLAG)
+            {
+               /* A registered memref */
+               pSCXParam->sMemref.hBlock  = pTEECParam->memref.parent->imp._hBlock;
+               if (nTEECParamType == TEEC_MEMREF_WHOLE)
+               {
+                  /* A memref on the whole shared memory */
+                  /* Set the direction from the shared memory flags */
+                  pCommand->sInvokeClientCommand.nParamTypes |=
+                     (pTEECParam->memref.parent->flags & (SCX_PARAM_TYPE_INPUT_FLAG | SCX_PARAM_TYPE_OUTPUT_FLAG))
+                     << (4*i);
+                  pSCXParam->sMemref.nSize   = pTEECParam->memref.parent->size;
+                  pSCXParam->sMemref.nOffset = 0;
+               }
+               else
+               {
+                  /* A partial memref */
+                  pSCXParam->sMemref.nSize   = pTEECParam->memref.size;
+                  pSCXParam->sMemref.nOffset = pTEECParam->memref.offset;
+               }
+            }
+            else
+            {
+               /* A temporary memref */
+               /* Set nOffset to the address in the client. This allows the server
+                 to allocate a block with the same alignment and also to
+                 detect a NULL tmpref.
+               */
+               pSCXParam->sTempMemref.nOffset = (uint32_t)pTEECParam->tmpref.buffer;
+               pSCXParam->sTempMemref.nDescriptor = (uint32_t)pTEECParam->tmpref.buffer;
+               pSCXParam->sTempMemref.nSize = pTEECParam->tmpref.size;
+            }
+         }
+         else if (nTEECParamType & SCX_PARAM_TYPE_INPUT_FLAG)
+         {
+            /* An input value */
+            pSCXParam->sValue.a = pTEECParam->value.a;
+            pSCXParam->sValue.b = pTEECParam->value.b;
+         }
+      }
+   }
+
+   pCommand->sHeader.nOperationID = (uint32_t)pAnswer;
+
+   nResult = ioctl((S_HANDLE)pContext->imp._hConnection, IOCTL_SCX_EXCHANGE, pCommand);
+   if (nResult != S_SUCCESS)
+   {
+      TRACE_INFO("scxExchangeMessage[0x%X]: Ioctl returned error: 0x%x (0x%x - %d)\n",pContext,nResult,errno,errno);
+      switch(errno)
+      {
+         case ENOMEM:
+            nResult=TEEC_ERROR_OUT_OF_MEMORY;
+            break;
+         case EACCES:
+            nResult=TEEC_ERROR_ACCESS_DENIED;
+            break;
+         default:
+            nResult=TEEC_ERROR_COMMUNICATION;
+            break;
+      }
+   }
+
+   if (pOperation != NULL)
+   {
+      /* Update the operation parameters from the answer message */
+      uint32_t   i;
+      SCHANNEL6_ANSWER_PARAM *  pSCXAnswers;
+      if (pAnswer->sHeader.nMessageType == SCX_OPEN_CLIENT_SESSION)
+      {
+         /* Open session */
+         pSCXAnswers = pAnswer->sOpenClientSession.sAnswers;
+      }
+      else
+      {
+         /* Invoke case */
+         pSCXAnswers = pAnswer->sInvokeClientCommand.sAnswers;
+      }
+
+      for (i = 0; i < 4; i++)
+      {
+         uint32_t   nSCXParamType;
+         nSCXParamType = SCX_GET_PARAM_TYPE(pCommand->sHeader.nMessageInfo, i);
+         if (nSCXParamType & SCX_PARAM_TYPE_OUTPUT_FLAG)
+         {
+            if (nSCXParamType & SCX_PARAM_TYPE_MEMREF_FLAG)
+            {
+               /* Trick: the size field is at the same position in a memref or a tmpref */
+               pOperation->params[i].memref.size = pSCXAnswers[i].sSize.nSize;
+            }
+            else
+            {
+               /* An output value */
+               pOperation->params[i].value.a = pSCXAnswers[i].sValue.a;
+               pOperation->params[i].value.b = pSCXAnswers[i].sValue.b;
+            }
+         }
+      }
+   }
+
+   return nResult;
+}
+
+/* ------------------------------------------------------------------------ */
+
+static void* scxAllocateSharedMemory(
+   IN uint32_t nLength)
+{
+   if (nLength == 0)
+   {
+      /* This is valid, although we don't want to call mmap.
+         Just return a dummy non-NULL pointer */
+      return (void*)0x10;
+   }
+   else
+   {
+      return mmap(
+         0,nLength,
+         PROT_READ | PROT_WRITE,
+         MAP_SHARED | MAP_ANONYMOUS,
+         0,0);
+   }
+}
+
+/* ------------------------------------------------------------------------ */
+
+static void scxReleaseSharedMemory(IN void* pBuffer,
+                                   IN uint32_t nLength)
+{
+   if (nLength == 0)
+   {
+      return;
+   }
+   if (munmap(pBuffer, nLength)!= 0)
+   {
+       TRACE_WARNING("scxReleaseSharedMemory returned 0x%x \n",errno);
+   }
+}
+/* ------------------------------------------------------------------------ */
+
+uint64_t scxGetCurrentTime(void)
+{
+   uint64_t currentTime = 0;
+   struct timeval now;
+
+   gettimeofday(&now,NULL);
+   currentTime = now.tv_sec;
+   currentTime = (currentTime * 1000) + (now.tv_usec / 1000);
+
+   return currentTime;
+}
+/* ------------------------------------------------------------------------ */
+
+/*
+ * ====================================================
+ *                TEE Client API
+ * =====================================================
+*/
+
+/**
+ * Get a time-limit equal to now + relative timeout expressed in milliseconds.
+ **/
+void TEEC_GetTimeLimit(
+    TEEC_Context*    sContext,
+    uint32_t         nTimeout,
+    TEEC_TimeLimit*  sTimeLimit)
+{
+   uint64_t nTimeLimit = 0;
+   VAR_NOT_USED(sContext);
+
+   TRACE_INFO("TEEC_GetTimeLimit(0x%X, %u ms)", sContext, nTimeout);
+
+   if (nTimeout == 0xFFFFFFFF )
+   {
+      /* Infinite timeout */
+      nTimeLimit = SCTIME_INFINITE;
+   }
+   else
+   {
+       nTimeLimit = scxGetCurrentTime() + nTimeout;
+   }
+   TRACE_INFO("GetTimeLimit %ld\n",nTimeLimit);
+   memcpy(sTimeLimit, &nTimeLimit, sizeof(TEEC_TimeLimit));
+}
+
+//-----------------------------------------------------------------------------------------------------
+TEEC_Result TEEC_InitializeContext(
+    const char*   pDeviceName,
+    TEEC_Context* pContext)
+{
+
+  TEEC_Result nError = TEEC_SUCCESS;
+   S_HANDLE hDriver   = S_HANDLE_NULL;
+   char sFullDeviceName[PATH_MAX];
+   uint32_t nVersion;
+
+   if(pDeviceName == NULL)
+   {
+      pDeviceName = SCX_DEFAULT_DEVICE_NAME;
+   }
+   strcpy(sFullDeviceName, "/dev/");
+   strcat(sFullDeviceName, pDeviceName);
+
+   hDriver = open(sFullDeviceName, O_RDWR, 0);
+
+   if (hDriver == (uint32_t)-1)
+   {
+      TRACE_ERROR("scxOpen: open() failed 0x%x\n", errno);
+      switch(errno)
+      {
+         case ENOMEM:
+            nError = TEEC_ERROR_OUT_OF_MEMORY;
+            goto error;
+         case EINTR:
+             break;
+         default:
+            nError = TEEC_ERROR_COMMUNICATION;
+            goto error;
+      }
+   }
+   fcntl(hDriver, F_SETFD, FD_CLOEXEC);
+   nVersion = ioctl(hDriver, IOCTL_SCX_GET_VERSION);
+   if (nVersion != SM_DRIVER_VERSION)
+   {
+      TRACE_ERROR("scxOpen: Not expected driver version: 0x%x instead of 0x%x\n", nVersion,SM_DRIVER_VERSION);
+      switch(errno)
+      {
+         case ENOMEM:
+            nError=TEEC_ERROR_OUT_OF_MEMORY;
+            break;
+         default:
+            nError=TEEC_ERROR_COMMUNICATION;
+            break;
+      }
+      close(hDriver);
+   }
+error:
+   if(nError == TEEC_SUCCESS)
+   {
+       pContext->imp._hConnection = hDriver;
+   }
+   else
+   {
+      TRACE_ERROR("scxOpen failed 0x%x\n", nError);
+      pContext->imp._hConnection = 0;
+   }
+
+   return nError;
+}
+
+//-----------------------------------------------------------------------------------------------------
+void TEEC_FinalizeContext(TEEC_Context* pContext)
+{
+   TRACE_INFO("TEEC_FinalizeContext[0x%X]", pContext);
+
+   if (pContext == NULL) return;
+
+   close(pContext->imp._hConnection);
+   pContext->imp._hConnection = 0;
+}
+
+//-----------------------------------------------------------------------------------------------------
+TEEC_Result TEEC_OpenSession (
+    TEEC_Context*    context,
+    TEEC_Session*    session,      /* OUT */
+    const TEEC_UUID* destination,  /* The trusted application UUID we want to open the session with */
+    uint32_t         connectionMethod, /* LoginType*/
+    void*            connectionData,  /* LoginData */
+    TEEC_Operation*  operation,    /* payload. If operation is NULL then no data buffers are exchanged with the Trusted Application, and the operation cannot be cancelled by the Client Application */
+    uint32_t*        errorOrigin)
+{
+  return TEEC_OpenSessionEx(context,
+                            session,
+                            NULL,
+                            destination,
+                            connectionMethod,
+                            connectionData,
+                            operation,
+                            errorOrigin);
+}
+
+//-----------------------------------------------------------------------------------------------------
+void TEEC_CloseSession (TEEC_Session* session)
+{
+   TEEC_Context*     context;
+   SCHANNEL6_ANSWER  sAnswer;
+   SCHANNEL6_COMMAND sCommand;
+   if (session == NULL) return;
+   context = session->imp._pContext;
+   memset(&sCommand,0,sizeof(sCommand));
+   sCommand.sHeader.nMessageType = SCX_CLOSE_CLIENT_SESSION;
+   sCommand.sHeader.nMessageSize = (sizeof(SCHANNEL6_CLOSE_CLIENT_SESSION_COMMAND)
+                                         - sizeof(SCHANNEL6_COMMAND_HEADER))/sizeof(uint32_t);
+   sCommand.sCloseClientSession.hClientSession = session->imp._hClientSession;
+   scxExchangeMessage(context, &sCommand, &sAnswer, NULL);
+   /* we ignore the error code of scxExchangeMessage */
+   session->imp._hClientSession = S_HANDLE_NULL;
+   session->imp._pContext = NULL;
+}
+
+//-----------------------------------------------------------------------------------------------------
+TEEC_Result TEEC_InvokeCommand(
+    TEEC_Session*     session,
+    uint32_t          commandID,
+    TEEC_Operation*   operation,
+    uint32_t*         errorOrigin)
+{
+    return TEEC_InvokeCommandEx(session,
+                            NULL,
+                            commandID,
+                            operation,
+                            errorOrigin);
+}
+
+
+//-----------------------------------------------------------------------------------------------------
+/* Used to implement both register and allocate */
+static TEEC_Result TEEC_RegisterSharedMemory0(
+    TEEC_Context*      context,
+    TEEC_SharedMemory* sharedMem)
+{
+   TEEC_Result nResult;
+   SCHANNEL6_COMMAND sCommand;
+   SCHANNEL6_ANSWER  sAnswer;
+
+   TRACE_INFO("TEEC_RegisterSharedMemory0 (%p, %p)",context, sharedMem);
+   memset(&sCommand, 0, sizeof(sCommand));
+
+   sCommand.sRegisterSharedMemory.nMessageSize = (sizeof(SCHANNEL6_REGISTER_SHARED_MEMORY_COMMAND) - sizeof(SCHANNEL6_COMMAND_HEADER))/4;
+   sCommand.sRegisterSharedMemory.nMessageType             = SCX_REGISTER_SHARED_MEMORY;
+   sCommand.sRegisterSharedMemory.nMemoryFlags             = sharedMem->flags;
+   sCommand.sRegisterSharedMemory.nSharedMemSize           = sharedMem->size;
+   sCommand.sRegisterSharedMemory.nSharedMemStartOffset    = 0;
+   sCommand.sRegisterSharedMemory.nSharedMemDescriptors[0] = (uint32_t)sharedMem->buffer;
+   nResult = scxExchangeMessage(context,
+                &sCommand,
+                &sAnswer,
+                NULL);
+   if (nResult == TEEC_SUCCESS)
+   {
+       nResult = sAnswer.sRegisterSharedMemory.nErrorCode;
+   }
+   if (nResult == TEEC_SUCCESS)
+   {
+      sharedMem->imp._pContext = context;
+      sharedMem->imp._hBlock = sAnswer.sRegisterSharedMemory.hBlock;
+   }
+   return nResult;
+}
+
+
+//-----------------------------------------------------------------------------------------------------
+TEEC_Result TEEC_RegisterSharedMemory(
+    TEEC_Context*      context,
+    TEEC_SharedMemory* sharedMem)
+{
+   TRACE_INFO("TEEC_RegisterSharedMemory (%p)",context);
+   sharedMem->imp._pContext = NULL;
+   sharedMem->imp._hBlock = S_HANDLE_NULL;
+   sharedMem->imp._bAllocated = false;
+   return TEEC_RegisterSharedMemory0(context, sharedMem);
+}
+
+//-----------------------------------------------------------------------------------------------------
+TEEC_Result TEEC_AllocateSharedMemory(
+    TEEC_Context*      context,
+    TEEC_SharedMemory* sharedMem)
+{
+   TEEC_Result nResult;
+   TRACE_INFO("TEEC_AllocateSharedMemory (%p)",context);
+
+   sharedMem->imp._pContext = NULL;
+   sharedMem->imp._hBlock = S_HANDLE_NULL;
+   sharedMem->buffer = scxAllocateSharedMemory(sharedMem->size);
+   if (sharedMem->buffer == NULL)
+   {
+      return TEEC_ERROR_OUT_OF_MEMORY;
+   }
+   sharedMem->imp._bAllocated = true;
+   nResult = TEEC_RegisterSharedMemory0(context, sharedMem);
+   if (nResult != TEEC_SUCCESS)
+   {
+      scxReleaseSharedMemory(sharedMem->buffer,sharedMem->size);
+      sharedMem->buffer = NULL;
+   }
+   return nResult;
+}
+
+//-----------------------------------------------------------------------------------------------------
+void TEEC_ReleaseSharedMemory (
+    TEEC_SharedMemory* sharedMem)
+{
+   SCHANNEL6_ANSWER  sAnswer;
+   SCHANNEL6_COMMAND sMessage;
+   TEEC_Context* context;
+
+   context = (TEEC_Context *)sharedMem->imp._pContext;
+   memset(&sMessage, 0, sizeof(SCHANNEL6_COMMAND));
+   sMessage.sReleaseSharedMemory.nMessageType = SCX_RELEASE_SHARED_MEMORY;
+   sMessage.sReleaseSharedMemory.nMessageSize = (sizeof(SCHANNEL6_RELEASE_SHARED_MEMORY_COMMAND)
+                                    - sizeof(SCHANNEL6_COMMAND_HEADER))/sizeof(uint32_t);
+   sMessage.sReleaseSharedMemory.hBlock = sharedMem->imp._hBlock;
+   scxExchangeMessage(context,&sMessage, &sAnswer, NULL);
+   if (sharedMem->imp._bAllocated)
+   {
+       scxReleaseSharedMemory(sharedMem->buffer,sharedMem->size);
+       /* Update parameters:
+       * In this case the Implementation MUST set the buffer and size fields of the sharedMem structure
+       * to NULL and 0 respectively before returning.
+       */
+       sharedMem->buffer = NULL;
+       sharedMem->size = 0;
+   }
+   sharedMem->imp._pContext = NULL;
+   sharedMem->imp._hBlock = S_HANDLE_NULL;
+}
+
+//-----------------------------------------------------------------------------------------------------
+void TEEC_RequestCancellation(TEEC_Operation* operation)
+{
+   uint32_t nOperationState;
+   TEEC_Result       nResult;
+
+   if (operation == NULL) return;
+
+retry:
+   nOperationState = operation->started;
+   if (nOperationState == 2)
+    {
+      /* Operation already finished. Return immediately */
+      return;
+   }
+   else if (nOperationState == 1)
+   {
+       /* Operation is in progress */
+       TEEC_Context*     context;
+       SCHANNEL6_ANSWER  sAnswer;
+       SCHANNEL6_COMMAND sMessage;
+
+       context = operation->imp._pContext;
+
+       memset(&sMessage,0,sizeof(sMessage));
+       sMessage.sHeader.nMessageType = SCX_CANCEL_CLIENT_OPERATION;
+       sMessage.sHeader.nMessageSize = (sizeof(SCHANNEL6_CANCEL_CLIENT_OPERATION_COMMAND) - sizeof(SCHANNEL6_COMMAND_HEADER))/4;
+       sMessage.sCancelClientOperation.hClientSession = operation->imp._hSession;
+       sMessage.sCancelClientOperation.nCancellationID = (uint32_t)operation;
+       nResult = scxExchangeMessage(context,&sMessage, &sAnswer, NULL);
+
+       if (nResult != TEEC_SUCCESS)
+       {
+           /* Communication failure. Ignore the error: the operation is already cancelled anyway */
+           return;
+       }
+       if (sAnswer.sCancelClientOperation.nErrorCode == S_SUCCESS)
+       {
+           /* Command was successfully cancelled */
+           return;
+       }
+       /* Otherwise, the command has not yet reached the secure world or has already finished and we must retry */
+   }
+   /* This applies as well when nOperationState == 0. In this case, the operation has not yet
+      started yet and we don't even have a pointer to the context */
+   scxYield();
+   goto retry;
+}
+
+
+//-----------------------------------------------------------------------------------------------------
+TEEC_Result TEEC_ReadSignatureFile(
+                                   void**    ppSignatureFile,
+                                   uint32_t* pnSignatureFileLength)
+{
+   TEEC_Result nErrorCode = TEEC_SUCCESS;
+
+   uint32_t      nBytesRead;
+   uint32_t      nSignatureSize = 0;
+   uint8_t*     pSignature = NULL;
+   FILE*    pSignatureFile = NULL;
+   char     sFileName[PATH_MAX + 1 + 5];  /* Allocate room for the signature extension */
+   long     nFileSize;
+
+   *pnSignatureFileLength = 0;
+   *ppSignatureFile = NULL;
+
+   if (realpath("/proc/self/exe", sFileName) == NULL)
+   {
+      TRACE_ERROR("TEEC_ReadSignatureFile: realpath failed [%d]", errno);
+      return TEEC_ERROR_OS;
+   }
+
+   /* Work out the signature file name */
+   strcat(sFileName, ".ssig");
+
+   pSignatureFile = fopen(sFileName, "rb");
+   if (pSignatureFile == NULL)
+   {
+      /* Signature doesn't exist */
+       return TEEC_ERROR_ITEM_NOT_FOUND;
+   }
+
+   if (fseek(pSignatureFile, 0, SEEK_END) != 0)
+   {
+      TRACE_ERROR("TEEC_ReadSignatureFile: fseek(%s) failed [%d]",
+                     sFileName, errno);
+      nErrorCode = TEEC_ERROR_OS;
+      goto error;
+   }
+
+   nFileSize = ftell(pSignatureFile);
+   if (nFileSize < 0)
+   {
+      TRACE_ERROR("TEEC_ReadSignatureFile: ftell(%s) failed [%d]",
+                     sFileName, errno);
+      nErrorCode = TEEC_ERROR_OS;
+      goto error;
+   }
+
+   nSignatureSize = (uint32_t)nFileSize;
+
+   if (nSignatureSize != 0)
+   {
+      pSignature = malloc(nSignatureSize);
+      if (pSignature == NULL)
+      {
+         TRACE_ERROR("TEEC_ReadSignatureFile: Heap - Out of memory for %u bytes",
+                        nSignatureSize);
+         nErrorCode = TEEC_ERROR_OUT_OF_MEMORY;
+         goto error;
+      }
+
+      rewind(pSignatureFile);
+
+      nBytesRead = fread(pSignature, 1, nSignatureSize, pSignatureFile);
+      if (nBytesRead < nSignatureSize)
+      {
+         TRACE_ERROR("TEEC_ReadSignatureFile: fread failed [%d]", errno);
+         nErrorCode = TEEC_ERROR_OS;
+         goto error;
+      }
+   }
+
+   fclose(pSignatureFile);
+
+   *pnSignatureFileLength = nSignatureSize;
+   *ppSignatureFile = pSignature;
+
+   return S_SUCCESS;
+
+error:
+   fclose(pSignatureFile);
+   free(pSignature);
+
+   return nErrorCode;
+}
+
+//-----------------------------------------------------------------------------------------------------
+TEEC_Result TEEC_OpenSessionEx (
+    TEEC_Context*         context,
+    TEEC_Session*         session,      /* OUT */
+    const TEEC_TimeLimit* timeLimit,
+    const TEEC_UUID*      destination,  /* The trusted application UUID we want to open the session with */
+    uint32_t              connectionMethod, /* LoginType*/
+    void*                 connectionData,  /* LoginData */
+    TEEC_Operation*       operation,    /* payload. If operation is NULL then no data buffers are exchanged with the Trusted Application, and the operation cannot be cancelled by the Client Application */
+    uint32_t*             returnOrigin)
+{
+   TEEC_Result nError;
+   uint32_t nReturnOrigin;
+   SCHANNEL6_ANSWER  sAnswer;
+   SCHANNEL6_COMMAND sCommand;
+
+   memset(&sCommand, 0, sizeof(SCHANNEL6_COMMAND));
+
+   sCommand.sHeader.nMessageType = SCX_OPEN_CLIENT_SESSION;
+   sCommand.sHeader.nMessageSize = (sizeof(SCHANNEL6_OPEN_CLIENT_SESSION_COMMAND) - 20 -sizeof(SCHANNEL6_COMMAND_HEADER))/sizeof(uint32_t);
+   if (timeLimit == NULL)
+   {
+      sCommand.sOpenClientSession.sTimeout = SCTIME_INFINITE;
+   }
+   else
+   {
+      sCommand.sOpenClientSession.sTimeout = *(uint64_t*)timeLimit;
+   }
+   sCommand.sOpenClientSession.sDestinationUUID   = *((S_UUID*)destination);
+   sCommand.sOpenClientSession.nLoginType         = connectionMethod;
+   if ((connectionMethod == TEEC_LOGIN_GROUP)||(connectionMethod == TEEC_LOGIN_GROUP_APPLICATION))
+   {
+       /* connectionData MUST point to a uint32_t which contains the group
+       * which this Client Application wants to connect as. The Linux Driver
+       * is responsible for securely ensuring that the Client Application
+       * instance is actually a member of this group.
+       */
+       if (connectionData != NULL)
+       {
+           *(uint32_t*)sCommand.sOpenClientSession.sLoginData = *(uint32_t*)connectionData;
+           sCommand.sHeader.nMessageSize += sizeof(uint32_t);
+       }
+   }
+   sCommand.sOpenClientSession.nCancellationID    = (uint32_t)operation; // used for TEEC_RequestCancellation
+
+   if (operation != NULL)
+   {
+       operation->imp._pContext = context;
+       operation->imp._hSession = S_HANDLE_NULL;
+       operation->started = 1;
+   }
+
+   nError = scxExchangeMessage(context, &sCommand, &sAnswer, operation);
+
+   if (operation != NULL) operation->started = 2;
+
+   if (nError != TEEC_SUCCESS)
+   {
+       nReturnOrigin = TEEC_ORIGIN_COMMS;
+   }
+   else
+   {
+       nError = sAnswer.sOpenClientSession.nErrorCode;
+       nReturnOrigin = sAnswer.sOpenClientSession.nReturnOrigin;
+   }
+
+   if (returnOrigin != NULL) *returnOrigin = nReturnOrigin;
+
+   if (nError == S_SUCCESS)
+   {
+       session->imp._hClientSession = sAnswer.sOpenClientSession.hClientSession;
+       session->imp._pContext       = context;
+   }
+
+   return nError;
+}
+
+//-----------------------------------------------------------------------------------------------------
+TEEC_Result TEEC_InvokeCommandEx(
+    TEEC_Session*         session,
+    const TEEC_TimeLimit* timeLimit,
+    uint32_t              commandID,
+    TEEC_Operation*       operation,
+    uint32_t*             returnOrigin)
+{
+   TEEC_Result nError;
+   SCHANNEL6_ANSWER  sAnswer;
+   SCHANNEL6_COMMAND sCommand;
+   uint32_t    nReturnOrigin;
+   TEEC_Context * context;
+
+   context = (TEEC_Context *)session->imp._pContext;
+   memset(&sCommand, 0, sizeof(SCHANNEL6_COMMAND));
+
+   sCommand.sHeader.nMessageType = SCX_INVOKE_CLIENT_COMMAND;
+   sCommand.sHeader.nMessageSize = (sizeof(SCHANNEL6_INVOKE_CLIENT_COMMAND_COMMAND) - sizeof(SCHANNEL6_COMMAND_HEADER))/sizeof(uint32_t);
+   sCommand.sInvokeClientCommand.nClientCommandIdentifier = commandID;
+    if (timeLimit == NULL)
+   {
+      sCommand.sInvokeClientCommand.sTimeout = SCTIME_INFINITE;
+   }
+   else
+   {
+      sCommand.sInvokeClientCommand.sTimeout = *(uint64_t*)timeLimit;
+   }
+   sCommand.sInvokeClientCommand.hClientSession     = session->imp._hClientSession;
+   sCommand.sInvokeClientCommand.nCancellationID = (uint32_t)operation; // used for TEEC_RequestCancellation
+
+   if (operation != NULL)
+   {
+      operation->imp._pContext = session->imp._pContext;
+      operation->imp._hSession = session->imp._hClientSession;
+      operation->started = 1;
+   }
+
+   nError = scxExchangeMessage(context, &sCommand, &sAnswer, operation);
+
+   if (operation != NULL)
+   {
+      operation->started = 2;
+      operation->imp._hSession = S_HANDLE_NULL;
+      operation->imp._pContext = NULL;
+   }
+
+   if (nError != TEEC_SUCCESS)
+   {
+      nReturnOrigin = TEEC_ORIGIN_COMMS;
+   }
+   else
+   {
+       nError = sAnswer.sInvokeClientCommand.nErrorCode;
+       nReturnOrigin = sAnswer.sInvokeClientCommand.nReturnOrigin;
+    }
+
+   if (returnOrigin != NULL) *returnOrigin = nReturnOrigin;
+
+   return nError;
+
+}
+
+//-----------------------------------------------------------------------------------------------------
+/*
+ * Retrieves information about the implementation
+ */
+void TEEC_GetImplementationInfo(
+                                TEEC_Context*            context,
+                                TEEC_ImplementationInfo* description)
+{
+   TRACE_INFO("TEEC_GetImplementationInfo");
+
+   memset(description, 0, sizeof(TEEC_ImplementationInfo));
+
+   strcpy(description->apiDescription, S_VERSION_STRING);
+
+   if (context != NULL)
+   {
+      SCX_VERSION_INFORMATION_BUFFER sInfoBuffer;
+      uint32_t nResult;
+
+      nResult = ioctl((S_HANDLE)context->imp._hConnection, IOCTL_SCX_GET_DESCRIPTION, &sInfoBuffer);
+      if (nResult != S_SUCCESS)
+      {
+         TRACE_ERROR("TEEC_GetImplementationInfo[0x%X]: ioctl returned error: 0x%x ( %d)\n",context, nResult, errno);
+         return;
+      }
+
+      memcpy(description->commsDescription, sInfoBuffer.sDriverDescription, 64);
+      description->commsDescription[64] = 0;
+      memcpy(description->TEEDescription, sInfoBuffer.sSecureWorldDescription, 64);
+      description->TEEDescription[64] = 0;
+   }
+}
+
+void TEEC_GetImplementationLimits(
+   TEEC_ImplementationLimits* limits)
+{
+   memset(limits, 0, sizeof(TEEC_ImplementationLimits));
+
+   /* A temp mem ref can not be mapped on more than 1Mb */
+   limits->pageSize = SIZE_4KB;
+   limits->tmprefMaxSize = SIZE_1MB;
+   limits->sharedMemMaxSize = SIZE_1MB * 8;
+ }
diff --git a/security/tf_daemon/Android.mk b/security/tf_daemon/Android.mk
new file mode 100644
index 0000000..eccba3d
--- /dev/null
+++ b/security/tf_daemon/Android.mk
@@ -0,0 +1,31 @@
+ifeq ($(TARGET_BOARD_PLATFORM),omap4)
+
+LOCAL_PATH := $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_PRELINK_MODULE := false
+LOCAL_ARM_MODE := arm
+
+LOCAL_SRC_FILES := \
+	delegation_client.c \
+	delegation_client_extension.c \
+	smc_properties.c \
+	smc_properties_parser.c \
+	lib_manifest2.c
+
+LOCAL_CFLAGS += -DLINUX
+LOCAL_CFLAGS += -D__ANDROID32__
+LOCAL_CFLAGS += -DSUPPORT_DELEGATION_EXTENSION
+
+ifdef S_VERSION_BUILD
+LOCAL_CFLAGS += -DS_VERSION_BUILD=$(S_VERSION_BUILD)
+endif
+
+LOCAL_CFLAGS += -I $(LOCAL_PATH)/../tf_sdk/include/
+
+LOCAL_MODULE:= tf_daemon
+LOCAL_STATIC_LIBRARIES := libtee_client_api_driver
+LOCAL_MODULE_TAGS := optional
+
+include $(BUILD_EXECUTABLE)
+endif
diff --git a/security/tf_daemon/delegation_client.c b/security/tf_daemon/delegation_client.c
new file mode 100644
index 0000000..54ee112
--- /dev/null
+++ b/security/tf_daemon/delegation_client.c
@@ -0,0 +1,1401 @@
+/**
+ * Copyright(c) 2011 Trusted Logic.   All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *  * Neither the name Trusted Logic nor the names of its
+ *    contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#if defined(__ANDROID32__)
+#include <stddef.h>
+#endif
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+/*
+ * When porting to a new OS, insert here the appropriate include files
+ */
+#include <sys/stat.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <fcntl.h>
+
+#if defined(LINUX) || defined(__ANDROID32__)
+#include <unistd.h>
+#include <sys/resource.h>
+
+
+#if defined(__ANDROID32__)
+/* fdatasync does not exist on Android */
+#define fdatasync fsync
+#else
+/*
+ * http://linux.die.net/man/2/fsync
+ * The function fdatasync seems to be absent of the header file
+ * in some distributions
+ */
+int fdatasync(int fd);
+#endif /* __ANDROID32__ */
+#include <syslog.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <pthread.h>
+#include <semaphore.h>
+#define PATH_SEPARATOR '/'
+#endif /* LINUX || __ANDROID32__ */
+
+#ifdef WIN32
+#include <windows.h>
+#include <io.h>
+#define PATH_SEPARATOR '\\'
+#endif
+
+#ifdef __SYMBIAN32__
+#include <unistd.h>
+#include "os_symbian.h"
+#define PATH_SEPARATOR '\\'
+#endif
+
+#include <stdarg.h>
+#include <assert.h>
+
+#include "service_delegation_protocol.h"
+
+#include "s_version.h"
+#include "s_error.h"
+#include "tee_client_api.h"
+
+/* You can define the preprocessor constant SUPPORT_DELEGATION_EXTENSION
+   if you want to pass extended options in a configuration file (option '-c').
+   It is up to you to define the format of this configuration file and the
+   extended option in the source file delegation_client_extension.c. You can
+   use extended options, e.g., to control the name of each partition file. */
+#ifdef SUPPORT_DELEGATION_EXTENSION
+#include "delegation_client_extension.h"
+#endif
+
+/*----------------------------------------------------------------------------
+ * Design notes
+ * ============
+ *
+ * This implementation of the delegation daemon supports the protocol
+ * specified in the Product Reference Manual ("Built-in Services Protocols Specification")
+ *
+ *----------------------------------------------------------------------------*/
+
+/*----------------------------------------------------------------------------
+ * Defines and structures
+ *----------------------------------------------------------------------------*/
+#define ECHANGE_BUFFER_INSTRUCTIONS_NB 100
+
+#define DEFAULT_WORKSPACE_SIZE (128*1024)
+
+/* A single shared memory block is used to contain the administrative data, the
+   instruction buffer and the workspace. The size of the instruction buffer is
+   fixed, but the size of workspace can be configured using the "-workspaceSize"
+   command-line option. */
+typedef struct
+{
+   DELEGATION_ADMINISTRATIVE_DATA sAdministrativeData;
+   uint32_t                       sInstructions[ECHANGE_BUFFER_INSTRUCTIONS_NB];
+   uint8_t                        sWorkspace[1/*g_nWorkspaceSize*/];
+} DELEGATION_EXCHANGE_BUFFER;
+
+#define MD_VAR_NOT_USED(variable)  do{(void)(variable);}while(0);
+
+#define MD_INLINE __inline
+
+/* ----------------------------------------------
+   Traces and logs
+
+   On Linux, traces and logs go either to the console (stderr) or to the syslog.
+   When the daemon is started, the logs go to the console. Once and if the daemon
+   is detached, the logs go to syslog.
+
+   On other systems, traces and logs go systematically to stderr
+
+   The difference between traces and logs is that traces are compiled out
+   in release builds whereas logs are visible to the customer.
+
+   -----------------------------------------------*/
+#if defined(LINUX) || (defined __ANDROID32__)
+
+static bool bDetached = false;
+
+static MD_INLINE void LogError(const char* format, ...)
+{
+   va_list ap;
+   va_start(ap, format);
+   if (bDetached)
+   {
+      vsyslog(LOG_ERR, format, ap);
+   }
+   else
+   {
+      fprintf(stderr, "ERROR: ");
+      vfprintf(stderr, format, ap);
+      fprintf(stderr, "\n");
+   }
+   va_end(ap);
+}
+
+static MD_INLINE void LogWarning(const char* format, ...)
+{
+   va_list ap;
+   va_start(ap, format);
+   if (bDetached)
+   {
+      vsyslog(LOG_WARNING, format, ap);
+   }
+   else
+   {
+      fprintf(stderr, "WARNING: ");
+      vfprintf(stderr, format, ap);
+      fprintf(stderr, "\n");
+   }
+   va_end(ap);
+}
+static MD_INLINE void LogInfo(const char* format, ...)
+{
+   va_list ap;
+   va_start(ap, format);
+   if (bDetached)
+   {
+      vsyslog(LOG_INFO, format, ap);
+   }
+   else
+   {
+      vfprintf(stderr, format, ap);
+      fprintf(stderr, "\n");
+   }
+   va_end(ap);
+}
+
+static MD_INLINE void TRACE_ERROR(const char* format, ...)
+{
+#ifndef NDEBUG
+   va_list ap;
+   va_start(ap, format);
+   if (bDetached)
+   {
+      vsyslog(LOG_ERR, format, ap);
+   }
+   else
+   {
+      fprintf(stderr, "TRACE: ERROR: ");
+      vfprintf(stderr, format, ap);
+      fprintf(stderr, "\n");
+   }
+   va_end(ap);
+#else
+   MD_VAR_NOT_USED(format);
+#endif /* NDEBUG */
+}
+
+static MD_INLINE void TRACE_WARNING(const char* format, ...)
+{
+#ifndef NDEBUG
+   va_list ap;
+   va_start(ap, format);
+   if (bDetached)
+   {
+      vsyslog(LOG_WARNING, format, ap);
+   }
+   else
+   {
+      fprintf(stderr, "TRACE: WARNING: ");
+      vfprintf(stderr, format, ap);
+      fprintf(stderr, "\n");
+   }
+   va_end(ap);
+#else
+   MD_VAR_NOT_USED(format);
+#endif /* NDEBUG */
+}
+
+static MD_INLINE void TRACE_INFO(const char* format, ...)
+{
+#ifndef NDEBUG
+   va_list ap;
+   va_start(ap, format);
+   if (bDetached)
+   {
+      vsyslog(LOG_DEBUG, format, ap);
+   }
+   else
+   {
+      fprintf(stderr, "TRACE: ");
+      vfprintf(stderr, format, ap);
+      fprintf(stderr, "\n");
+   }
+   va_end(ap);
+#else
+   MD_VAR_NOT_USED(format);
+#endif /* NDEBUG */
+}
+#elif defined __SYMBIAN32__
+/* defined in os_symbian.h */
+
+#elif defined NO_LOG_NO_TRACE
+static MD_INLINE void LogError(const char* format, ...)
+{
+   MD_VAR_NOT_USED(format);
+}
+static MD_INLINE void LogWarning(const char* format, ...)
+{
+   MD_VAR_NOT_USED(format);
+}
+static MD_INLINE void LogInfo(const char* format, ...)
+{
+   MD_VAR_NOT_USED(format);
+}
+
+static MD_INLINE void TRACE_ERROR(const char* format, ...)
+{
+   MD_VAR_NOT_USED(format);
+}
+
+static MD_INLINE void TRACE_WARNING(const char* format, ...)
+{
+   MD_VAR_NOT_USED(format);
+}
+
+static MD_INLINE void TRACE_INFO(const char* format, ...)
+{
+   MD_VAR_NOT_USED(format);
+}
+
+#else
+/* !defined(LINUX) || !defined(__ANDROID32__) */
+
+static MD_INLINE void LogError(const char* format, ...)
+{
+   va_list ap;
+   va_start(ap, format);
+   fprintf(stderr, "ERROR: ");
+   vfprintf(stderr, format, ap);
+   fprintf(stderr, "\n");
+   va_end(ap);
+}
+static MD_INLINE void LogWarning(const char* format, ...)
+{
+   va_list ap;
+   va_start(ap, format);
+   fprintf(stderr, "WARNING: ");
+   vfprintf(stderr, format, ap);
+   fprintf(stderr, "\n");
+   va_end(ap);
+}
+static MD_INLINE void LogInfo(const char* format, ...)
+{
+   va_list ap;
+   va_start(ap, format);
+   vfprintf(stderr, format, ap);
+   fprintf(stderr, "\n");
+   va_end(ap);
+}
+
+static MD_INLINE void TRACE_ERROR(const char* format, ...)
+{
+#ifndef NDEBUG
+   va_list ap;
+   va_start(ap, format);
+   fprintf(stderr, "TRACE: ERROR: ");
+   vfprintf(stderr, format, ap);
+   fprintf(stderr, "\n");
+   va_end(ap);
+#else
+   MD_VAR_NOT_USED(format);
+#endif /* NDEBUG */
+}
+
+static MD_INLINE void TRACE_WARNING(const char* format, ...)
+{
+#ifndef NDEBUG
+   va_list ap;
+   va_start(ap, format);
+   fprintf(stderr, "TRACE: WARNING: ");
+   vfprintf(stderr, format, ap);
+   fprintf(stderr, "\n");
+   va_end(ap);
+#else
+   MD_VAR_NOT_USED(format);
+#endif /* NDEBUG */
+}
+
+static MD_INLINE void TRACE_INFO(const char* format, ...)
+{
+#ifndef NDEBUG
+   va_list ap;
+   va_start(ap, format);
+   fprintf(stderr, "TRACE: ");
+   vfprintf(stderr, format, ap);
+   fprintf(stderr, "\n");
+   va_end(ap);
+#else
+   MD_VAR_NOT_USED(format);
+#endif /* NDEBUG */
+}
+#endif /* defined(LINUX) || defined(__ANDROID32__) */
+
+/*----------------------------------------------------------------------------
+ * Globals
+ *----------------------------------------------------------------------------*/
+/* The sector size */
+static uint32_t g_nSectorSize;
+
+/* The workspace size */
+static uint32_t g_nWorkspaceSize = DEFAULT_WORKSPACE_SIZE;
+
+/* UUID of the delegation service */
+static const TEEC_UUID g_sServiceId = SERVICE_DELEGATION_UUID;
+
+/* pWorkspaceBuffer points to the workspace buffer shared with the secure
+   world to transfer the sectors in the READ and WRITE instructions  */
+static uint8_t* g_pWorkspaceBuffer;
+static DELEGATION_EXCHANGE_BUFFER * g_pExchangeBuffer;
+TEEC_SharedMemory sExchangeSharedMem;
+/*
+   The absolute path name for each of the 16 possible partitions.
+ */
+static char* g_pPartitionNames[16];
+
+/* The file context for each of the 16 possible partitions. An entry
+   in this array is NULL if the corresponding partition is currently not opened
+ */
+static FILE* g_pPartitionFiles[16];
+
+/*----------------------------------------------------------------------------
+ * Utilities functions
+ *----------------------------------------------------------------------------*/
+static void printUsage(void)
+{
+   LogInfo("usage : tf_daemon [options]");
+   LogInfo("where [options] are:");
+   LogInfo("-h --help  Display help.");
+#ifdef SUPPORT_DELEGATION_EXTENSION
+   LogInfo("-c <conf>  Configuration file path.");
+#else
+   /* If the compilation parameter SUPPORT_DELEGATION_EXTENSION is not set, each
+      partition is stored as a file within the base dir */
+   LogInfo("-storageDir <baseDir>  Set the directory where the data will be stored; this directory");
+   LogInfo("           must be writable and executable (this parameter is mandatory)");
+#endif
+   LogInfo("-d         Turns on debug mode.  If not specified, the daemon will fork itself");
+   LogInfo("           and get detached from the console.");
+#ifndef SUPPORT_DELEGATION_EXTENSION
+   LogInfo("-workspaceSize <integer>  Set the size in bytes of the workspace. Must be greater or equal to 8 sectors.");
+   LogInfo("           (default is 128KB)");
+#endif
+}
+
+static TEEC_Result errno2serror(void)
+{
+   switch (errno)
+   {
+   case EINVAL:
+      return S_ERROR_BAD_PARAMETERS;
+   case EMFILE:
+      return S_ERROR_NO_MORE_HANDLES;
+   case ENOENT:
+      return S_ERROR_ITEM_NOT_FOUND;
+   case EEXIST:
+      return S_ERROR_ITEM_EXISTS;
+   case ENOSPC:
+      return S_ERROR_STORAGE_NO_SPACE;
+   case ENOMEM:
+      return S_ERROR_OUT_OF_MEMORY;
+   case EBADF:
+   case EACCES:
+   default:
+      return S_ERROR_STORAGE_UNREACHABLE;
+   }
+}
+
+/*
+ * Check if the directory in parameter exists with Read/Write access
+ * Return 0 in case of success and 1 otherwise.
+ */
+int static_checkStorageDirAndAccessRights(char * directoryName)
+{
+#ifdef __SYMBIAN32__
+   /* it looks like stat is not working properly on Symbian
+      Create and remove dummy file to check access rights */
+   FILE *stream;
+   char *checkAccess = NULL;
+
+   if (directoryName == NULL)
+   {
+      LogError("Directory Name is NULL");
+      return 1;
+   }
+
+   checkAccess = malloc(strlen(directoryName)+1/* \ */ +1 /* a */ + 1 /* 0 */);
+   if (!checkAccess)
+   {
+      LogError("storageDir '%s' allocation error", directoryName);
+      return 1;
+   }
+   sprintf(checkAccess,"%s\\a",directoryName);
+   stream = fopen(checkAccess, "w+b");
+   if (!stream)
+   {
+      LogError("storageDir '%s' is incorrect or cannot be reached", directoryName);
+      return 1;
+   }
+   fclose(stream);
+   unlink(checkAccess);
+#else
+   /* Non-Symbian OS: use stat */
+   struct stat buf;
+   int result = 0;
+
+   if (directoryName == NULL)
+   {
+      LogError("Directory Name is NULL");
+      return 1;
+   }
+
+   result = stat(directoryName, &buf);
+   if (result == 0)
+   {
+      /* Storage dir exists. Check access rights */
+#if defined(LINUX) || (defined __ANDROID32__)
+      if ((buf.st_mode & (S_IXUSR | S_IWUSR)) != (S_IXUSR | S_IWUSR))
+      {
+         LogError("storageDir '%s' does not have read-write access", directoryName);
+         return 1;
+      }
+#endif
+   }
+   else if (errno == ENOENT)
+   {
+      LogError("storageDir '%s' does not exist", directoryName);
+      return 1;
+   }
+   else
+   {
+      /* Another error */
+      LogError("storageDir '%s' is incorrect or cannot be reached", directoryName);
+      return 1;
+   }
+#endif
+   return 0;
+}
+
+
+
+/*----------------------------------------------------------------------------
+ * Instructions
+ *----------------------------------------------------------------------------*/
+
+/**
+ * This function executes the DESTROY_PARTITION instruction
+ *
+ * @param nPartitionID: the partition identifier
+ **/
+static TEEC_Result partitionDestroy(uint32_t nPartitionID)
+{
+   TEEC_Result  nError = S_SUCCESS;
+
+   if (g_pPartitionFiles[nPartitionID] != NULL)
+   {
+      /* The partition must not be currently opened */
+      LogError("g_pPartitionFiles not NULL");
+      return S_ERROR_BAD_STATE;
+   }
+
+   /* Try to erase the file */
+#if defined(LINUX) || (defined __ANDROID32__) || defined (__SYMBIAN32__)
+   if (unlink(g_pPartitionNames[nPartitionID]) != 0)
+#endif
+#ifdef WIN32
+   if (_unlink(g_pPartitionNames[nPartitionID]) != 0)
+#endif
+   {
+      /* File in use or OS didn't allow the operation */
+      nError = errno2serror();
+   }
+
+   return nError;
+}
+
+/**
+ * This function executes the CREATE_PARTITION instruction. When successful,
+ * it fills the g_pPartitionFiles[nPartitionID] slot.
+ *
+ * @param nPartitionID: the partition identifier
+ **/
+static TEEC_Result partitionCreate(uint32_t nPartitionID)
+{
+   uint32_t nError = S_SUCCESS;
+
+   if (g_pPartitionFiles[nPartitionID] != NULL)
+   {
+      /* The partition is already opened */
+      LogError("g_pPartitionFiles not NULL");
+      return S_ERROR_BAD_STATE;
+   }
+
+   /* Create the file unconditionnally */
+   LogInfo("Create storage file \"%s\"", g_pPartitionNames[nPartitionID]);
+   g_pPartitionFiles[nPartitionID] = fopen(g_pPartitionNames[nPartitionID], "w+b");
+
+   if (g_pPartitionFiles[nPartitionID] == NULL)
+   {
+      LogError("Cannot create storage file \"%s\"", g_pPartitionNames[nPartitionID]);
+      nError = errno2serror();
+      return nError;
+   }
+
+   return nError;
+}
+
+/**
+ * This function executes the OPEN_PARTITION instruction. When successful,
+ * it fills the g_pPartitionFiles[nPartitionID] slot and writes the partition
+ * size in hResultEncoder
+ *
+ * @param nPartitionID: the partition identifier
+ * @param pnPartitionSize: filled with the number of sectors in the partition
+ **/
+static TEEC_Result partitionOpen(uint32_t nPartitionID, uint32_t* pnPartitionSize)
+{
+   uint32_t nError = S_SUCCESS;
+
+   if (g_pPartitionFiles[nPartitionID] != NULL)
+   {
+      /* No partition must be currently opened in the session */
+      LogError("g_pPartitionFiles not NULL");
+      return S_ERROR_BAD_STATE;
+   }
+
+   /* Open the file */
+   g_pPartitionFiles[nPartitionID] = fopen(g_pPartitionNames[nPartitionID], "r+b");
+   if (g_pPartitionFiles[nPartitionID] == NULL)
+   {
+      if (errno == ENOENT)
+      {
+         /* File does not exist */
+         LogError("Storage file \"%s\" does not exist", g_pPartitionNames[nPartitionID]);
+         nError = S_ERROR_ITEM_NOT_FOUND;
+         return nError;
+      }
+      else
+      {
+         LogError("cannot open storage file \"%s\"", g_pPartitionNames[nPartitionID]);
+         nError = errno2serror();
+         return nError;
+      }
+   }
+   /* Determine the current number of sectors */
+   fseek(g_pPartitionFiles[nPartitionID], 0L, SEEK_END);
+   *pnPartitionSize = ftell(g_pPartitionFiles[nPartitionID]) / g_nSectorSize;
+
+   LogInfo("storage file \"%s\" successfully opened (size = %d KB (%d bytes))",
+      g_pPartitionNames[nPartitionID],
+      ((*pnPartitionSize) * g_nSectorSize) / 1024,
+      ((*pnPartitionSize) * g_nSectorSize));
+
+   return nError;
+}
+
+
+/**
+ * This function executes the CLOSE_PARTITION instruction.
+ * It closes the partition file.
+ *
+ * @param nPartitionID: the partition identifier
+ **/
+static TEEC_Result partitionClose(uint32_t nPartitionID)
+{
+   if (g_pPartitionFiles[nPartitionID] == NULL)
+   {
+      /* The partition is currently not opened */
+      return S_ERROR_BAD_STATE;
+   }
+   fclose(g_pPartitionFiles[nPartitionID]);
+   g_pPartitionFiles[nPartitionID] = NULL;
+   return S_SUCCESS;
+}
+
+/**
+ * This function executes the READ instruction.
+ *
+ * @param nPartitionID: the partition identifier
+ * @param nSectorIndex: the index of the sector to read
+ * @param nWorkspaceOffset: the offset in the workspace where the sector must be written
+ **/
+static TEEC_Result partitionRead(uint32_t nPartitionID, uint32_t nSectorIndex, uint32_t nWorkspaceOffset)
+{
+   FILE* pFile;
+
+   TRACE_INFO(">Partition %1X: read sector 0x%08X into workspace at offset 0x%08X",
+      nPartitionID, nSectorIndex, nWorkspaceOffset);
+
+   pFile = g_pPartitionFiles[nPartitionID];
+
+   if (pFile == NULL)
+   {
+      /* The partition is not opened */
+      return S_ERROR_BAD_STATE;
+   }
+
+   if (fseek(pFile, nSectorIndex*g_nSectorSize, SEEK_SET) != 0)
+   {
+      LogError("fseek error: %s", strerror(errno));
+      return errno2serror();
+   }
+
+   if (fread(g_pWorkspaceBuffer + nWorkspaceOffset,
+             g_nSectorSize, 1,
+             pFile) != 1)
+   {
+      if (feof(pFile))
+      {
+         LogError("fread error: End-Of-File detected");
+         return S_ERROR_ITEM_NOT_FOUND;
+      }
+      LogError("fread error: %s", strerror(errno));
+      return errno2serror();
+   }
+
+   return S_SUCCESS;
+}
+
+/**
+ * This function executes the WRITE instruction.
+ *
+ * @param nPartitionID: the partition identifier
+ * @param nSectorIndex: the index of the sector to read
+ * @param nWorkspaceOffset: the offset in the workspace where the sector must be read
+ **/
+static TEEC_Result partitionWrite(uint32_t nPartitionID, uint32_t nSectorIndex, uint32_t nWorkspaceOffset)
+{
+   FILE* pFile;
+
+   TRACE_INFO(">Partition %1X: write sector 0x%X from workspace at offset 0x%X",
+      nPartitionID, nSectorIndex, nWorkspaceOffset);
+
+   pFile = g_pPartitionFiles[nPartitionID];
+
+   if (pFile == NULL)
+   {
+      /* The partition is not opened */
+      return S_ERROR_BAD_STATE;
+   }
+
+   if (fseek(pFile, nSectorIndex*g_nSectorSize, SEEK_SET) != 0)
+   {
+      LogError("fseek error: %s", strerror(errno));
+      return errno2serror();
+   }
+
+   if (fwrite(g_pWorkspaceBuffer + nWorkspaceOffset,
+              g_nSectorSize, 1,
+              pFile) != 1)
+   {
+      LogError("fread error: %s", strerror(errno));
+      return errno2serror();
+   }
+   return S_SUCCESS;
+}
+
+
+/**
+ * This function executes the SET_SIZE instruction.
+ *
+ * @param nPartitionID: the partition identifier
+ * @param nNewSectorCount: the new sector count
+ **/
+static TEEC_Result partitionSetSize(uint32_t nPartitionID, uint32_t nNewSectorCount)
+{
+   FILE* pFile;
+   uint32_t nCurrentSectorCount;
+
+   pFile = g_pPartitionFiles[nPartitionID];
+
+   if (pFile==NULL)
+   {
+      /* The partition is not opened */
+      return S_ERROR_BAD_STATE;
+   }
+
+   /* Determine the current size of the partition */
+   if (fseek(pFile, 0, SEEK_END) != 0)
+   {
+      LogError("fseek error: %s", strerror(errno));
+      return errno2serror();
+   }
+   nCurrentSectorCount = ftell(pFile) / g_nSectorSize;
+
+   if (nNewSectorCount > nCurrentSectorCount)
+   {
+      uint32_t nAddedBytesCount;
+      /* Enlarge the partition file. Make sure we actually write
+         some non-zero data into the new sectors. Otherwise, some file-system
+         might not really reserve the storage space but use a
+         sparse representation. In this case, a subsequent write instruction
+         could fail due to out-of-space, which we want to avoid. */
+      nAddedBytesCount = (nNewSectorCount-nCurrentSectorCount)*g_nSectorSize;
+      while (nAddedBytesCount)
+      {
+         if (fputc(0xA5, pFile)!=0xA5)
+         {
+            return errno2serror();
+         }
+         nAddedBytesCount--;
+      }
+   }
+   else if (nNewSectorCount < nCurrentSectorCount)
+   {
+      int result = 0;
+      /* Truncate the partition file */
+#if defined(LINUX) || (defined __ANDROID32__)
+      result = ftruncate(fileno(pFile),nNewSectorCount * g_nSectorSize);
+#endif
+#if defined (__SYMBIAN32__)
+	  LogError("No truncate available in Symbian C API");
+#endif
+#ifdef WIN32
+      result = _chsize(_fileno(pFile),nNewSectorCount * g_nSectorSize);
+#endif
+      if (result)
+      {
+         return errno2serror();
+      }
+   }
+   return S_SUCCESS;
+}
+
+/**
+ * This function executes the SYNC instruction.
+ *
+ * @param pPartitionID: the partition identifier
+ **/
+static TEEC_Result partitionSync(uint32_t nPartitionID)
+{
+   TEEC_Result nError = S_SUCCESS;
+   int result;
+
+   FILE* pFile = g_pPartitionFiles[nPartitionID];
+
+   if (pFile == NULL)
+   {
+      /* The partition is not currently opened */
+      return S_ERROR_BAD_STATE;
+   }
+
+   /* First make sure that the data in the stdio buffers
+      is flushed to the file descriptor */
+   result=fflush(pFile);
+   if (result)
+   {
+      nError=errno2serror();
+      goto end;
+   }
+   /* Then synchronize the file descriptor with the file-system */
+
+#if defined(LINUX) || (defined __ANDROID32__)
+   result=fdatasync(fileno(pFile));
+#endif
+#if defined (__SYMBIAN32__)
+   result=fsync(fileno(pFile));
+#endif
+#ifdef WIN32
+   result=_commit(_fileno(pFile));
+#endif
+   if (result)
+   {
+      nError=errno2serror();
+   }
+
+end:
+   return nError;
+}
+
+/**
+ * This function executes the NOTIFY instruction.
+ *
+ * @param pMessage the message string
+ * @param nMessageType the type of messages
+ **/
+static void notify(const wchar_t* pMessage, uint32_t nMessageType)
+{
+   switch (nMessageType)
+   {
+   case DELEGATION_NOTIFY_TYPE_ERROR:
+      LogError("%ls", pMessage);
+      break;
+   case DELEGATION_NOTIFY_TYPE_WARNING:
+      LogWarning("%ls", pMessage);
+      break;
+   case DELEGATION_NOTIFY_TYPE_DEBUG:
+      LogInfo("DEBUG: %ls", pMessage);
+      break;
+   case DELEGATION_NOTIFY_TYPE_INFO:
+   default:
+      LogInfo("%ls", pMessage);
+      break;
+   }
+}
+
+/*----------------------------------------------------------------------------
+ * Session main function
+ *----------------------------------------------------------------------------*/
+
+/*
+ * This function runs a session opened on the delegation service. It fetches
+ * instructions and execute them in a loop. It never returns, but may call
+ * exit when instructed to shutdown by the service
+ */
+static int runSession(TEEC_Context* pContext, TEEC_Session* pSession, TEEC_Operation* pOperation)
+{
+   memset(&g_pExchangeBuffer->sAdministrativeData, 0x00, sizeof(g_pExchangeBuffer->sAdministrativeData));
+
+   while (true)
+   {
+      S_RESULT    nError;
+      TEEC_Result                      nTeeError;
+      uint32_t                         nInstructionsIndex;
+      uint32_t                         nInstructionsBufferSize = sizeof(g_pExchangeBuffer->sInstructions);
+
+      pOperation->paramTypes = TEEC_PARAM_TYPES(
+         TEEC_MEMREF_PARTIAL_INPUT,
+         TEEC_MEMREF_PARTIAL_OUTPUT,
+         TEEC_MEMREF_PARTIAL_INOUT,
+         TEEC_NONE);
+      pOperation->params[0].memref.parent = &sExchangeSharedMem;
+      pOperation->params[0].memref.offset = offsetof(DELEGATION_EXCHANGE_BUFFER, sAdministrativeData);
+      pOperation->params[0].memref.size   = sizeof(g_pExchangeBuffer->sAdministrativeData);
+
+      pOperation->params[1].memref.parent = &sExchangeSharedMem;
+      pOperation->params[1].memref.offset = offsetof(DELEGATION_EXCHANGE_BUFFER, sInstructions);
+      pOperation->params[1].memref.size   = sizeof(g_pExchangeBuffer->sInstructions);
+
+      pOperation->params[2].memref.parent = &sExchangeSharedMem;
+      pOperation->params[2].memref.offset = offsetof(DELEGATION_EXCHANGE_BUFFER, sWorkspace);
+      pOperation->params[2].memref.size   = g_nWorkspaceSize;
+
+      nTeeError = TEEC_InvokeCommand(pSession,
+                                  SERVICE_DELEGATION_GET_INSTRUCTIONS,   /* commandID */
+                                  pOperation,     /* IN OUT operation */
+                                  NULL             /* OUT errorOrigin, optional */
+                                 );
+
+      if (nTeeError != TEEC_SUCCESS)
+      {
+         LogError("TEEC_InvokeCommand error: 0x%08X", nTeeError);
+         LogError("Daemon exits");
+         exit(2);
+      }
+
+      if (pOperation->params[1].tmpref.size >  nInstructionsBufferSize)
+      {
+         /* Should not happen, probably an error from the service */
+         pOperation->params[1].tmpref.size = 0;
+      }
+
+      /* Reset the operation results */
+      nError = TEEC_SUCCESS;
+      g_pExchangeBuffer->sAdministrativeData.nSyncExecuted = 0;
+      memset(g_pExchangeBuffer->sAdministrativeData.nPartitionErrorStates, 0x00, sizeof(g_pExchangeBuffer->sAdministrativeData.nPartitionErrorStates));
+      memset(g_pExchangeBuffer->sAdministrativeData.nPartitionOpenSizes, 0x00, sizeof(g_pExchangeBuffer->sAdministrativeData.nPartitionOpenSizes));
+
+      /* Execute the instructions */
+      nInstructionsIndex = 0;
+      nInstructionsBufferSize = pOperation->params[1].tmpref.size;
+      while (true)
+      {
+         DELEGATION_INSTRUCTION * pInstruction;
+         uint32_t nInstructionID;
+         pInstruction = (DELEGATION_INSTRUCTION *)(&g_pExchangeBuffer->sInstructions[nInstructionsIndex/4]);
+         if (nInstructionsIndex + 4 <= nInstructionsBufferSize)
+         {
+            nInstructionID = pInstruction->sGeneric.nInstructionID;
+            nInstructionsIndex+=4;
+         }
+         else
+         {
+            goto instruction_parse_end;
+         }
+         if ((nInstructionID & 0x0F) == 0)
+         {
+            /* Partition-independent instruction */
+            switch (nInstructionID)
+            {
+            case DELEGATION_INSTRUCTION_SHUTDOWN:
+               {
+                  exit(0);
+                  /* The implementation of the TF Client API will automatically
+                     destroy the context and release any associated resource */
+               }
+            case DELEGATION_INSTRUCTION_NOTIFY:
+               {
+                  /* Parse the instruction parameters */
+                  wchar_t  pMessage[100];
+                  uint32_t nMessageType;
+                  uint32_t nMessageSize;
+                  memset(pMessage, 0, 100*sizeof(wchar_t));
+
+                  if (nInstructionsIndex + 8 <= nInstructionsBufferSize)
+                  {
+                     nMessageType = pInstruction->sNotify.nMessageType;
+                     nMessageSize = pInstruction->sNotify.nMessageSize;
+                     nInstructionsIndex+=8;
+                  }
+                  else
+                  {
+                     goto instruction_parse_end;
+                  }
+                  if (nMessageSize > (99)*sizeof(wchar_t))
+                  {
+                     /* How to handle the error correctly in this case ? */
+                     goto instruction_parse_end;
+                  }
+                  if (nInstructionsIndex + nMessageSize <= nInstructionsBufferSize)
+                  {
+                     memcpy(pMessage, &pInstruction->sNotify.nMessage[0], nMessageSize);
+                     nInstructionsIndex+=nMessageSize;
+                  }
+                  else
+                  {
+                     goto instruction_parse_end;
+                  }
+                  /* Align the pInstructionsIndex on 4 bytes */
+                  nInstructionsIndex = (nInstructionsIndex+3)&~3;
+                  notify(pMessage, nMessageType);
+                  break;
+               }
+            default:
+               LogError("Unknown instruction identifier: %02X", nInstructionID);
+               nError = S_ERROR_BAD_PARAMETERS;
+               break;
+            }
+         }
+         else
+         {
+            /* Partition-specific instruction */
+            uint32_t nPartitionID = (nInstructionID & 0xF0) >> 4;
+            if (g_pExchangeBuffer->sAdministrativeData.nPartitionErrorStates[nPartitionID] == S_SUCCESS)
+            {
+               /* Execute the instruction only if there is currently no
+                  error on the partition */
+               switch (nInstructionID & 0x0F)
+               {
+               case DELEGATION_INSTRUCTION_PARTITION_CREATE:
+                  nError = partitionCreate(nPartitionID);
+                  TRACE_INFO("INSTRUCTION: ID=0x%x pid=%d err=%d", (nInstructionID & 0x0F), nPartitionID, nError);
+                  break;
+               case DELEGATION_INSTRUCTION_PARTITION_OPEN:
+                  {
+                     uint32_t nPartitionSize = 0;
+                     nError = partitionOpen(nPartitionID, &nPartitionSize);
+                     TRACE_INFO("INSTRUCTION: ID=0x%x pid=%d pSize=%d err=%d", (nInstructionID & 0x0F), nPartitionID, nPartitionSize, nError);
+                     if (nError == S_SUCCESS)
+                     {
+                        g_pExchangeBuffer->sAdministrativeData.nPartitionOpenSizes[nPartitionID] = nPartitionSize;
+                     }
+                     break;
+                  }
+               case DELEGATION_INSTRUCTION_PARTITION_READ:
+                  {
+                     /* Parse parameters */
+                     uint32_t nSectorID;
+                     uint32_t nWorkspaceOffset;
+                     if (nInstructionsIndex + 8 <= nInstructionsBufferSize)
+                     {
+                        nSectorID        = pInstruction->sReadWrite.nSectorID;
+                        nWorkspaceOffset = pInstruction->sReadWrite.nWorkspaceOffset;
+                        nInstructionsIndex+=8;
+                     }
+                     else
+                     {
+                        goto instruction_parse_end;
+                     }
+                     nError = partitionRead(nPartitionID, nSectorID, nWorkspaceOffset);
+                     TRACE_INFO("INSTRUCTION: ID=0x%x pid=%d sid=%d woff=%d err=%d", (nInstructionID & 0x0F), nPartitionID, nSectorID, nWorkspaceOffset, nError);
+                     break;
+                  }
+               case DELEGATION_INSTRUCTION_PARTITION_WRITE:
+                  {
+                     /* Parse parameters */
+                     uint32_t nSectorID;
+                     uint32_t nWorkspaceOffset;
+                     if (nInstructionsIndex + 8 <= nInstructionsBufferSize)
+                     {
+                        nSectorID        = pInstruction->sReadWrite.nSectorID;
+                        nWorkspaceOffset = pInstruction->sReadWrite.nWorkspaceOffset;
+                        nInstructionsIndex+=8;
+                     }
+                     else
+                     {
+                        goto instruction_parse_end;
+                     }
+                     nError = partitionWrite(nPartitionID, nSectorID, nWorkspaceOffset);
+                     TRACE_INFO("INSTRUCTION: ID=0x%x pid=%d sid=%d woff=%d err=%d", (nInstructionID & 0x0F), nPartitionID, nSectorID, nWorkspaceOffset, nError);
+                     break;
+                  }
+               case DELEGATION_INSTRUCTION_PARTITION_SYNC:
+                  nError = partitionSync(nPartitionID);
+                  TRACE_INFO("INSTRUCTION: ID=0x%x pid=%d err=%d", (nInstructionID & 0x0F), nPartitionID, nError);
+                  if (nError == S_SUCCESS)
+                  {
+                     g_pExchangeBuffer->sAdministrativeData.nSyncExecuted++;
+                  }
+                  break;
+               case DELEGATION_INSTRUCTION_PARTITION_SET_SIZE:
+                  {
+                     uint32_t nNewSize;
+                     if (nInstructionsIndex + 4 <= nInstructionsBufferSize)
+                     {
+                        nNewSize = pInstruction->sSetSize.nNewSize;
+                        nInstructionsIndex+=4;
+                     }
+                     else
+                     {
+                        goto instruction_parse_end;
+                     }
+                     nError = partitionSetSize(nPartitionID, nNewSize);
+                     TRACE_INFO("INSTRUCTION: ID=0x%x pid=%d nNewSize=%d err=%d", (nInstructionID & 0x0F), nPartitionID, nNewSize, nError);
+                     break;
+                  }
+               case DELEGATION_INSTRUCTION_PARTITION_CLOSE:
+                  nError = partitionClose(nPartitionID);
+                  TRACE_INFO("INSTRUCTION: ID=0x%x pid=%d err=%d", (nInstructionID & 0x0F), nPartitionID, nError);
+                  break;
+               case DELEGATION_INSTRUCTION_PARTITION_DESTROY:
+                  nError = partitionDestroy(nPartitionID);
+                  TRACE_INFO("INSTRUCTION: ID=0x%x pid=%d err=%d", (nInstructionID & 0x0F), nPartitionID, nError);
+                  break;
+               }
+               g_pExchangeBuffer->sAdministrativeData.nPartitionErrorStates[nPartitionID] = nError;
+            }
+         }
+      }
+instruction_parse_end:
+      memset(pOperation, 0, sizeof(TEEC_Operation));
+   }
+}
+
+/**
+ * This function opens a new session to the delegation service.
+ **/
+static int createSession(TEEC_Context* pContext, TEEC_Session* pSession, TEEC_Operation* pOperation)
+{
+   TEEC_Result nError;
+   uint32_t nExchangeBufferSize;
+
+   memset(pOperation, 0, sizeof(TEEC_Operation));
+   pOperation->paramTypes = TEEC_PARAM_TYPES(
+      TEEC_VALUE_OUTPUT, TEEC_NONE, TEEC_NONE, TEEC_NONE);
+   nError = TEEC_OpenSession(pContext,
+                             pSession,                /* OUT session */
+                             &g_sServiceId,           /* destination UUID */
+                             TEEC_LOGIN_PRIVILEGED,   /* connectionMethod */
+                             NULL,                    /* connectionData */
+                             pOperation,              /* IN OUT operation */
+                             NULL                     /* OUT errorOrigin, optional */
+                             );
+   if (nError != TEEC_SUCCESS)
+   {
+      LogError("Error on TEEC_OpenSession : 0x%x", nError);
+      exit(2);
+   }
+   /* Read sector size */
+   g_nSectorSize = pOperation->params[0].value.a;
+   LogInfo("Sector Size: %d bytes", g_nSectorSize);
+
+   /* Check sector size */
+   if (!(g_nSectorSize == 512 || g_nSectorSize == 1024 || g_nSectorSize == 2048 || g_nSectorSize == 4096))
+   {
+      LogError("Incorrect sector size: terminating...");
+      exit(2);
+   }
+
+   /* Check workspace size */
+   if (g_nWorkspaceSize < 8 * g_nSectorSize)
+   {
+      g_nWorkspaceSize = 8 * g_nSectorSize;
+      LogWarning("Workspace size too small, automatically set to %d bytes", g_nWorkspaceSize);
+   }
+   /* Compute the size of the exchange buffer */
+   nExchangeBufferSize = sizeof(DELEGATION_EXCHANGE_BUFFER)-1+g_nWorkspaceSize;
+   g_pExchangeBuffer  = (DELEGATION_EXCHANGE_BUFFER*)malloc(nExchangeBufferSize);
+	 if (g_pExchangeBuffer == NULL)
+   {
+      LogError("Cannot allocate exchange buffer of %d bytes", nExchangeBufferSize);
+      LogError("Now exiting...");
+      exit(2);
+   }
+   g_pWorkspaceBuffer = (uint8_t*)g_pExchangeBuffer->sWorkspace;
+   memset(g_pExchangeBuffer, 0x00, nExchangeBufferSize);
+   memset(g_pPartitionFiles,0,16*sizeof(FILE*));
+
+   /* Register the exchange buffer as a shared memory block */
+   sExchangeSharedMem.buffer = g_pExchangeBuffer;
+   sExchangeSharedMem.size   = nExchangeBufferSize;
+   sExchangeSharedMem.flags  = TEEC_MEM_INPUT | TEEC_MEM_OUTPUT;
+   nError = TEEC_RegisterSharedMemory(pContext, &sExchangeSharedMem);
+   if (nError != TEEC_SUCCESS)
+   {
+      LogError("Error on TEEC_RegisterSharedMemory : 0x%x", nError);
+      free(g_pExchangeBuffer);
+      exit(2);
+   }
+   LogInfo("Daemon now connected");
+   return 0;
+}
+
+
+/*----------------------------------------------------------------------------
+ * Main
+ *----------------------------------------------------------------------------*/
+
+#ifdef INCLUDE_CLIENT_DELEGATION
+int delegation_main(int argc, char* argv[])
+#else
+int main(int argc, char* argv[])
+#endif
+{
+   TEEC_Result    nError;
+   TEEC_Context   sContext;
+   TEEC_Session   sSession;
+   TEEC_Operation sOperation;
+   bool        debug = false;
+
+#ifndef SUPPORT_DELEGATION_EXTENSION
+   char * baseDir = NULL;
+
+   LogInfo("TFSW Normal-World Daemon");
+#else
+   LogInfo("TFSW Normal-World Ext Daemon");
+#endif
+   LogInfo(S_VERSION_STRING);
+   LogInfo("");
+
+   /* Skip program name */
+   argv++;
+   argc--;
+
+   while (argc != 0)
+   {
+      if (strcmp(argv[0], "-d") == 0)
+      {
+         debug = true;
+      }
+#ifdef SUPPORT_DELEGATION_EXTENSION
+      else if (strcmp(argv[0], "-c") == 0)
+      {
+         int error;
+         argc--;
+         argv++;
+         if (argc == 0)
+         {
+            printUsage();
+            return 1;
+         }
+         /* Note that the function parseCommandLineExtension can modify the
+            content of the g_partitionNames array */
+         error = parseCommandLineExtension(argv[0], g_pPartitionNames);
+         if ( error != 0 )
+         {
+            printUsage();
+            return error;
+         }
+      }
+#else
+      else if (strcmp(argv[0], "-storageDir") == 0)
+      {
+         uint32_t i = 0;
+         argc--;
+         argv++;
+         if (argc == 0)
+         {
+            printUsage();
+            return 1;
+         }
+         if (baseDir != NULL)
+         {
+            LogError("Only one storage directory may be specified");
+            return 1;
+         }
+         baseDir = malloc(strlen(argv[0])+1); /* Zero-terminated string */
+         if (baseDir == NULL)
+         {
+             LogError("Out of memory");
+             return 2;
+         }
+
+         strcpy(baseDir, argv[0]);
+
+         /* Set default names to the partitions */
+         for ( i=0; i<16 ;i++ )
+         {
+            g_pPartitionNames[i] = NULL;
+            g_pPartitionNames[i] = malloc(strlen(baseDir) + 1 /* separator */ + sizeof("Store_X.tf"));
+            if (g_pPartitionNames[i] != NULL)
+            {
+               sprintf(g_pPartitionNames[i], "%s%cStore_%1X.tf", baseDir, PATH_SEPARATOR, i);
+            }
+            else
+            {
+               free(baseDir);
+               i=0;
+               while(g_pPartitionNames[i] != NULL) free(g_pPartitionNames[i++]);
+               LogError("Out of memory");
+               return 2;
+            }
+         }
+      }
+      else if (strcmp(argv[0], "-workspaceSize") == 0)
+      {
+         argc--;
+         argv++;
+         if (argc == 0)
+         {
+            printUsage();
+            return 1;
+         }
+         g_nWorkspaceSize=atol(argv[0]);
+      }
+#endif /* ! SUPPORT_DELEGATION_EXTENSION */
+      /*****************************************/
+      else if (strcmp(argv[0], "--help") == 0 || strcmp(argv[0], "-h") == 0)
+      {
+         printUsage();
+         return 0;
+      }
+      else
+      {
+         printUsage();
+         return 1;
+      }
+      argc--;
+      argv++;
+   }
+
+#ifndef SUPPORT_DELEGATION_EXTENSION
+   if (baseDir == NULL)
+   {
+      LogError("-storageDir option is mandatory");
+      return 1;
+   }
+   else
+   {
+      if (static_checkStorageDirAndAccessRights(baseDir) != 0)
+      {
+         return 1;
+      }
+   }
+#endif /* #ifndef SUPPORT_DELEGATION_EXTENSION */
+
+   /*
+    * Detach the daemon from the console
+    */
+
+#if defined(LINUX) || (defined __ANDROID32__)
+   {
+      /*
+       * Turns this application into a daemon => fork off parent process, setup logging, ...
+       */
+
+      /* Our process ID and Session ID */
+      pid_t pid, sid;
+
+      if (!debug)
+      {
+         LogInfo("tf_daemon is detaching from console... Further traces go to syslog");
+         /* Fork off the parent process */
+         pid = fork();
+         if (pid < 0)
+         {
+            LogError("daemon forking failed");
+            return 1;
+         }
+
+         if (pid > 0)
+         {
+            /* parent */
+            return 0;
+         }
+         bDetached = true;
+      }
+
+      /* Change the file mode mask */
+      umask(0077);
+
+      if (!debug)
+      {
+         /* Open any logs here */
+         openlog("tf_daemon", 0, LOG_DAEMON);
+
+         /* Detach from the console */
+         sid = setsid();
+         if (sid < 0)
+         {
+            /* Log the failure */
+            LogError("daemon group creation failed");
+            return 1;
+         }
+         /* Close out the standard file descriptors */
+         close(STDIN_FILENO);
+         close(STDOUT_FILENO);
+         close(STDERR_FILENO);
+      }
+   }
+   /* Change priority so that tf_driver.ko with no polling thread is faster */
+   if (setpriority(PRIO_PROCESS, 0, 19)!=0)
+   {
+      LogError("Daemon cannot change priority");
+      return 1;
+   }
+
+#endif
+
+   TRACE_INFO("Sector size is %d", g_nSectorSize);
+
+   LogInfo("tf_daemon - started");
+
+   nError = TEEC_InitializeContext(NULL,  /* const char * name */
+                                   &sContext);   /* TEEC_Context* context */
+   if (nError != TEEC_SUCCESS)
+   {
+      LogError("TEEC_InitializeContext error: 0x%08X", nError);
+      LogError("Now exiting...");
+      exit(2);
+   }
+
+   /* Open a session */
+   if(createSession(&sContext, &sSession, &sOperation) == 0)
+   {
+      /* Run the session. This should never return */
+      runSession(&sContext, &sSession, &sOperation);
+   }
+   TEEC_FinalizeContext(&sContext);
+
+   return 3;
+}
diff --git a/security/tf_daemon/delegation_client_extension.c b/security/tf_daemon/delegation_client_extension.c
new file mode 100644
index 0000000..66e0f39
--- /dev/null
+++ b/security/tf_daemon/delegation_client_extension.c
@@ -0,0 +1,138 @@
+/**
+ * Copyright(c) 2011 Trusted Logic.   All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *  * Neither the name Trusted Logic nor the names of its
+ *    contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*----------------------------------------------------------------------------
+ * Notes
+ * =====
+ *
+ * This file is an extension to the delegation client for SMC omap3. It
+ * permits to manage two differences with the original client:
+ *  - command line parsing to take into account a file as input
+ *  - associate a specific path to each partition
+ *
+ *----------------------------------------------------------------------------*/
+#include <stdarg.h>
+#include <assert.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "s_version.h"
+#include "s_error.h"
+#include "s_type.h"
+#include "smc_properties.h"
+
+/*
+ * This function :
+ *    1) parses the configuration file of the SMC
+ *    2) checks that all mandatory partition name are present and valid
+ *    3) associates partition names to one of the 16 partition IDs
+ *    4) Mapping is as follow:
+ *          -- partition 0 <--> File System
+ *          -- partition 1 <--> Keystore System
+ *          -- partition 2 <--> Keystore User
+ *          -- partition 15 <--> Super Partition
+ *
+ * It returns 0 in case of success and the error code requested by tf_daemon otherwise.
+ */
+int parseCommandLineExtension(char* configurationFileName, char* partitionNames[16])
+{
+   int error = 0;
+   uint32_t i = 0;
+   char * tmpChar = NULL;
+
+   if (configurationFileName == NULL)
+   {
+      return 1;
+   }
+
+   error = smcPropertiesParse(configurationFileName);
+   if ( error != 0 )
+   {
+      return error;
+   }
+
+   /* Allocate SMC partition file Name */
+   for(i=0; i<15; i++)
+   {
+      partitionNames[i] = NULL;
+   }
+
+
+   /* File System File Name */
+   tmpChar = smcGetPropertyAsString(FILE_SYSTEM_FILE_NAME);
+   if ( tmpChar == NULL )
+   {
+      printf("Main system partition storage file name is missing.\n");
+      goto return_error;
+   }
+   partitionNames[0] = malloc (strlen(tmpChar) + 1);
+   sprintf(partitionNames[0], "%s", tmpChar);
+
+   /* Keystore System File Name */
+   tmpChar = smcGetPropertyAsString(KEYSTORE_SYSTEM_FILE_NAME);
+   if ( tmpChar == NULL )
+   {
+      printf("Main system partition storage file name is missing.\n");
+      goto return_error;
+   }
+   partitionNames[1] = malloc (strlen(tmpChar) + 1);
+   sprintf(partitionNames[1], "%s", tmpChar);
+
+   /* Keystore User File Name */
+   tmpChar = smcGetPropertyAsString(KEYSTORE_USER_FILE_NAME);
+   if ( tmpChar == NULL )
+   {
+      printf("Main system partition storage file name is missing.\n");
+      goto return_error;
+   }
+   partitionNames[2] = malloc (strlen(tmpChar) + 1);
+   sprintf(partitionNames[2], "%s", tmpChar);
+
+   /* Super Partition File Name */
+   tmpChar = smcGetPropertyAsString(SUPER_PARTITION_FILE_NAME);
+   if ( tmpChar == NULL )
+   {
+      printf("Main system partition storage file name is missing.\n");
+      goto return_error;
+   }
+   partitionNames[15] = malloc (strlen(tmpChar) + 1);
+   sprintf(partitionNames[15], "%s", tmpChar);
+
+   /* return Success */
+   return 0;
+
+return_error:
+   for (i=0; i<15; i++)
+   {
+      if (partitionNames[i] != NULL) free(partitionNames[i]);
+   }
+   return 1;
+}
diff --git a/security/tf_daemon/delegation_client_extension.h b/security/tf_daemon/delegation_client_extension.h
new file mode 100644
index 0000000..af4a159
--- /dev/null
+++ b/security/tf_daemon/delegation_client_extension.h
@@ -0,0 +1,55 @@
+/**
+ * Copyright(c) 2011 Trusted Logic.   All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *  * Neither the name Trusted Logic nor the names of its
+ *    contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*----------------------------------------------------------------------------
+ * Notes
+ * =====
+ *
+ * This file is an extension to the delegation client for SMC.
+ * It permits to manage two differences with the original client:
+ *  - command line parsing to take into account a file as input
+ *  - associate a specific path to each partition
+ *
+ *----------------------------------------------------------------------------*/
+
+/*
+ * This function :
+ *    1) parses the configuration file of the SMC
+ *    2) checks that all mandatory partition name are present and valid
+ *    3) associates partition names to one of the 16 partition IDs
+ *    4) Mapping is as follow:
+ *          -- partition 0 <--> File System
+ *          -- partition 1 <--> Keystore System
+ *          -- partition 2 <--> Keystore User
+ *          -- partition 15 <--> Super Partition
+ *
+ * It returns 0 in case of success and the error code requested by tf_daemon otherwise.
+ */
+int parseCommandLineExtension(char* configurationFileName, char* partitionNames[16]);
diff --git a/security/tf_daemon/lib_manifest2.c b/security/tf_daemon/lib_manifest2.c
new file mode 100644
index 0000000..558b821
--- /dev/null
+++ b/security/tf_daemon/lib_manifest2.c
@@ -0,0 +1,678 @@
+/**
+ * Copyright(c) 2011 Trusted Logic.   All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *  * Neither the name Trusted Logic nor the names of its
+ *    contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include "lib_manifest2.h"
+#include <string.h>
+
+#define CHAR_CR  (uint8_t)0x0D
+#define CHAR_LF  (uint8_t)0x0A
+#define CHAR_TAB (uint8_t)0x09
+
+#ifdef LIB_TOOL_IMPLEMENTATION
+#include "exos_trace.h"
+#define LOG_ERROR(pContext, msg, ...) log_error("%s - line %d: " msg, pContext->pManifestName, pContext->nLine, __VA_ARGS__)
+static void log_error(const char* msg, ...)
+{
+   va_list arg_list;
+   va_start(arg_list, msg);
+   exosTraceVPrintf("LIB_MANIFEST2", EXOS_TRACE_ORG_APPLI, K_PRINT_ERROR_LOG, msg, &arg_list);
+   va_end(arg_list);
+}
+#else
+/* No error messages on the target */
+#ifdef __SYMBIAN32__
+#define LOG_ERROR(pContext...)
+#else
+#define LOG_ERROR(...)
+#endif
+#endif
+
+void libManifest2InitContext(
+   LIB_MANIFEST2_CONTEXT* pContext)
+{
+   pContext->nOffset = 0;
+   pContext->nLine = 1;
+   pContext->nSectionStartOffset = 0;
+}
+
+
+#define CHARACTER_NAME_FIRST      1
+#define CHARACTER_NAME_SUBSEQUENT 2
+#define CHARACTER_SECTION_NAME    3
+
+static bool static_checkCharacter(uint8_t x, uint32_t nType)
+{
+   /* [A-Za-z0-9] is acceptable for everyone */
+   if (x  >= (uint8_t)'a' && x <= (uint8_t)'z')
+   {
+      return true;
+   }
+   if (x >=(uint8_t)'A' && x <= (uint8_t)'Z')
+   {
+      return true;
+   }
+   if (x >= (uint8_t)'0' && x <= (uint8_t)'9')
+   {
+      return true;
+   }
+   if (nType == CHARACTER_NAME_FIRST)
+   {
+      return false;
+   }
+   /* Subsequent property name or section name characters can be [_.-] */
+   if (x == (uint8_t)'_' || x == (uint8_t)'.' || x == (uint8_t)'-')
+   {
+      return true;
+   }
+   if (nType == CHARACTER_NAME_SUBSEQUENT)
+   {
+      return false;
+   }
+   /* Space is also allowed in section names */
+   if (x == (uint8_t)' ')
+   {
+      return true;
+   }
+   return false;
+}
+
+static bool static_sectionNameEqualCaseInsensitive(
+   uint8_t* pName1,
+   uint32_t nName1Length,
+   uint8_t* pName2,
+   uint32_t nName2Length)
+{
+   uint32_t i;
+   if (nName1Length != nName2Length)
+   {
+      return false;
+   }
+   for (i = 0; i < nName1Length; i++)
+   {
+      uint8_t x1 = pName1[i];
+      uint8_t x2 = pName2[i];
+
+      /* This code assumes the characters have been checked before */
+
+      if ((x1 & ~0x20) != (x2 & ~0x20))
+      {
+         return false;
+      }
+   }
+   return true;
+}
+
+static S_RESULT static_libManifest2GetNextItemInternal(
+   LIB_MANIFEST2_CONTEXT* pContext,
+   OUT uint8_t** ppName,
+   OUT uint32_t* pNameLength,
+   OUT uint8_t** ppValue,
+   OUT uint32_t* pValueLength)
+{
+   S_RESULT nResult = S_ERROR_BAD_FORMAT;
+   uint8_t* pCurrent = pContext->pManifestContent + pContext->nOffset;
+   uint8_t* pEnd = pContext->pManifestContent + pContext->nManifestLength;
+   uint8_t* pLastNonWhitespaceChar;
+   uint32_t nCurrentSequenceCount;
+   uint32_t nCurrentChar;
+
+   if (pContext->nType != LIB_MANIFEST2_TYPE_COMPILED)
+   {
+      /* Skip leading BOM if we're at the start */
+      if (pCurrent == pContext->pManifestContent)
+      {
+         /* We're at the start. Skip leading BOM if present */
+         /* Note that the UTF-8 encoding of the BOM marker is EF BB BF */
+         if (pContext->nManifestLength >= 3
+             && pCurrent[0] == 0xEF
+             && pCurrent[1] == 0xBB
+             && pCurrent[2] == 0xBF)
+         {
+            pCurrent += 3;
+         }
+      }
+      /* Skip comments and newlines */
+      while (pCurrent < pEnd)
+      {
+         if (*pCurrent == (uint8_t)'#')
+         {
+            /* This is the start of a comment. Skip until end of line or end of file */
+            pCurrent++;
+            while (pCurrent < pEnd && *pCurrent != CHAR_LF && *pCurrent != CHAR_CR)
+            {
+               if (*pCurrent == 0)
+               {
+                  LOG_ERROR(pContext, "NUL character forbidden");
+                  goto error;
+               }
+               pCurrent++;
+            }
+         }
+         else if (*pCurrent == CHAR_CR)
+         {
+            /* Check if a LF follows */
+            pCurrent++;
+            if (pCurrent < pEnd && *pCurrent == CHAR_LF)
+            {
+               pCurrent++;
+            }
+            pContext->nLine++;
+         }
+         else if (*pCurrent == CHAR_LF)
+         {
+            pCurrent++;
+            pContext->nLine++;
+         }
+         else if (*pCurrent == ' ' || *pCurrent == '\t')
+         {
+            /* this is the start of a all-whitespace line */
+            /* NOTE: this is not allowed by the current spec: spec update needed */
+            pCurrent++;
+            while (pCurrent < pEnd)
+            {
+               if (*pCurrent == CHAR_LF || *pCurrent == CHAR_CR)
+               {
+                  /* End-of-line reached */
+                  break;
+               }
+               if (! (*pCurrent == ' ' || *pCurrent == '\t'))
+               {
+                  LOG_ERROR(pContext, "A line starting with whitespaces must contain only whitespaces. Illegal character: 0x%02X", *pCurrent);
+                  goto error;
+               }
+               pCurrent++;
+            }
+         }
+         else
+         {
+            break;
+         }
+      }
+   }
+
+   if (pCurrent >= pEnd)
+   {
+      /* No more properties */
+      nResult = S_ERROR_ITEM_NOT_FOUND;
+      goto error;
+   }
+
+   if (pContext->nType == LIB_MANIFEST2_TYPE_SOURCE_WITH_SECTIONS)
+   {
+      if (*pCurrent == '[')
+      {
+         /* This is a section descriptor */
+         pCurrent++;
+         *ppName = pCurrent;
+         *ppValue = NULL;
+         *pValueLength = 0;
+         while (true)
+         {
+            if (pCurrent >= pEnd)
+            {
+               LOG_ERROR(pContext, "EOF reached within a section name");
+               goto error;
+            }
+            if (*pCurrent == ']')
+            {
+               /* End of section name */
+               *pNameLength = pCurrent - *ppName;
+               pCurrent++;
+
+               /* Skip spaces and tabs. Note that this is a deviation from the current spec
+                 (see SWIS). Spec must be updated */
+               while (pCurrent < pEnd)
+               {
+                  if (*pCurrent == ' ' || *pCurrent == '\t')
+                  {
+                     pCurrent++;
+                  }
+                  else if (*pCurrent == CHAR_CR || *pCurrent == CHAR_LF)
+                  {
+                     /* End of line */
+                     break;
+                  }
+                  else
+                  {
+                     LOG_ERROR(pContext, "Non-space character follows a sectino header: 0x02X", *pCurrent);
+                  }
+               }
+               pContext->nOffset = pCurrent - pContext->pManifestContent;
+               pContext->nSectionStartOffset = pContext->nOffset;
+               return S_SUCCESS;
+            }
+            /* Check section name character */
+            if (!static_checkCharacter(*pCurrent, CHARACTER_SECTION_NAME))
+            {
+               LOG_ERROR(pContext, "Invalid character for a section name: 0x%02X", *pCurrent);
+               goto error;
+            }
+            pCurrent++;
+         }
+      }
+
+      if (pContext->nSectionStartOffset == 0)
+      {
+         /* No section has been found yet. This is a bad format */
+         LOG_ERROR(pContext, "Property found outside any section");
+         goto error;
+      }
+   }
+
+   *ppName = pCurrent;
+
+   /* Check first character of name is in [A-Za-z0-9] */
+   if (!static_checkCharacter(*pCurrent, CHARACTER_NAME_FIRST))
+   {
+      LOG_ERROR(pContext, "Invalid first character for a property name: 0x%02X", *pCurrent);
+      goto error;
+   }
+   pCurrent++;
+   pLastNonWhitespaceChar = pCurrent;
+   while (true)
+   {
+      if (pCurrent == pEnd)
+      {
+         LOG_ERROR(pContext, "EOF reached within a property name");
+         goto error;
+      }
+      if (*pCurrent == ':')
+      {
+         /* Colon reached */
+         break;
+      }
+      if (pContext->nType != LIB_MANIFEST2_TYPE_COMPILED)
+      {
+         /* In source manifest, allow space characters before the colon.
+            This is a deviation from the spec. Spec must be updated */
+         if (*pCurrent == ' ' || *pCurrent == '\t')
+         {
+            pCurrent++;
+            continue;
+         }
+      }
+      if (!static_checkCharacter(*pCurrent, CHARACTER_NAME_SUBSEQUENT))
+      {
+         LOG_ERROR(pContext, "Invalid character for a property name: 0x%02X", *pCurrent);
+         goto error;
+      }
+      if (pContext->nType != LIB_MANIFEST2_TYPE_COMPILED)
+      {
+         /* Even in a source manifest, property name cannot contain spaces! */
+         if (pCurrent != pLastNonWhitespaceChar)
+         {
+            LOG_ERROR(pContext, "Property name cannot contain spaces");
+            goto error;
+         }
+      }
+      pCurrent++;
+      pLastNonWhitespaceChar = pCurrent;
+   }
+   *pNameLength = pLastNonWhitespaceChar - *ppName;
+   pCurrent++;
+   /* Skip spaces and tabs on the right of the colon */
+   while (pCurrent < pEnd && (*pCurrent == ' ' || *pCurrent == '\t'))
+   {
+      pCurrent++;
+   }
+   *ppValue = pCurrent;
+   pLastNonWhitespaceChar = pCurrent-1;
+
+   nCurrentSequenceCount = 0;
+   nCurrentChar = 0;
+
+   while (pCurrent < pEnd)
+   {
+      uint32_t x;
+      x = *pCurrent;
+      if ((x & 0x80) == 0)
+      {
+         if (nCurrentSequenceCount != 0)
+         {
+            /* We were expecting a 10xxxxxx byte: ill-formed UTF-8 */
+            LOG_ERROR(pContext, "Invalid UTF-8 sequence");
+            goto error;
+         }
+         else if (x == 0)
+         {
+            /* The null character is forbidden */
+            LOG_ERROR(pContext, "NUL character forbidden");
+            goto error;
+         }
+         /* We have a well-formed Unicode character */
+         nCurrentChar = x;
+      }
+      else if ((x & 0xC0) == 0xC0)
+      {
+         /* Start of a sequence */
+         if (nCurrentSequenceCount != 0)
+         {
+            /* We were expecting a 10xxxxxx byte: ill-formed UTF-8 */
+            LOG_ERROR(pContext, "Invalid UTF-8 sequence");
+            goto error;
+         }
+         else if ((x & 0xE0) == 0xC0)
+         {
+            /* 1 byte follows */
+            nCurrentChar = x & 0x1F;
+            nCurrentSequenceCount = 1;
+            if ((x & 0x1E) == 0)
+            {
+               /* Illegal UTF-8: overlong encoding of character in the [0x00-0x7F] range
+                  (must use 1-byte encoding, not a 2-byte encoding) */
+               LOG_ERROR(pContext, "Invalid UTF-8 sequence");
+               goto error;
+            }
+         }
+         else if ((x & 0xF0) == 0xE0)
+         {
+            /* 2 bytes follow */
+            nCurrentChar = x & 0x0F;
+            nCurrentSequenceCount = 2;
+         }
+         else if ((x & 0xF8) == 0xF0)
+         {
+            /* 3 bytes follow */
+            nCurrentChar = x & 0x07;
+            nCurrentSequenceCount = 3;
+         }
+         else
+         {
+            /* Illegal start of sequence */
+            LOG_ERROR(pContext, "Invalid UTF-8 sequence");
+            goto error;
+         }
+      }
+      else if ((x & 0xC0) == 0x80)
+      {
+         /* Continuation byte */
+         if (nCurrentSequenceCount == 0)
+         {
+            /* We were expecting a sequence start, not a continuation byte */
+            LOG_ERROR(pContext, "Invalid UTF-8 sequence");
+            goto error;
+         }
+         else
+         {
+            if (nCurrentSequenceCount == 2)
+            {
+               /* We're in a 3-byte sequence, check that we're not using an overlong sequence */
+               if (nCurrentChar == 0 && (x & 0x20) == 0)
+               {
+                  /* The character starts with at least 5 zero bits, so has fewer than 11 bits. It should
+                     have used a 2-byte sequence, not a 3-byte sequence */
+                  LOG_ERROR(pContext, "Invalid UTF-8 sequence");
+                  goto error;
+               }
+            }
+            else if (nCurrentSequenceCount == 3)
+            {
+               if (nCurrentChar == 0 && (x & 0x30) == 0)
+               {
+                  /* The character starts with at least 5 zero bits, so has fewer than 16 bits. It should
+                     have used a 3-byte sequence, not a 4-byte sequence */
+                  LOG_ERROR(pContext, "Invalid UTF-8 sequence");
+                  goto error;
+               }
+            }
+            nCurrentSequenceCount--;
+            nCurrentChar = (nCurrentChar << 6) | (x & 0x3F);
+         }
+      }
+      else
+      {
+         /* Illegal byte */
+         LOG_ERROR(pContext, "Invalid UTF-8 sequence");
+         goto error;
+      }
+      if (nCurrentSequenceCount == 0)
+      {
+         /* nCurrentChar contains the current Unicode character */
+         /* check character */
+         if ((nCurrentChar >= 0xD800 && nCurrentChar < 0xE000) || nCurrentChar >= 0x110000)
+         {
+            /* Illegal code point */
+            LOG_ERROR(pContext, "Invalid UTF-8 code point 0x%X", nCurrentChar);
+            goto error;
+         }
+
+         if (*pCurrent == CHAR_CR)
+         {
+            if (pContext->nType == LIB_MANIFEST2_TYPE_COMPILED)
+            {
+               /* Check if a LF follows */
+               pCurrent++;
+               if (pCurrent < pEnd && *pCurrent == CHAR_LF)
+               {
+                  pCurrent++;
+               }
+               pContext->nLine++;
+            }
+            goto end;
+         }
+         else if (*pCurrent == CHAR_LF)
+         {
+            if (pContext->nType == LIB_MANIFEST2_TYPE_COMPILED)
+            {
+               pCurrent++;
+               pContext->nLine++;
+            }
+            goto end;
+         }
+      }
+      if (*pCurrent != ' ' && *pCurrent != CHAR_TAB)
+      {
+         /* It's a non-whitespace char */
+         pLastNonWhitespaceChar = pCurrent;
+      }
+      pCurrent++;
+   }
+
+   /* Hit the end of the manifest; Check that we're not in the middle of a sequence */
+   if (nCurrentSequenceCount != 0)
+   {
+      LOG_ERROR(pContext, "File ends in the middle of an UTF-8 sequence");
+      goto error;
+   }
+
+end:
+
+   *pValueLength = pLastNonWhitespaceChar - *ppValue + 1;
+   pContext->nOffset = pCurrent - pContext->pManifestContent;
+
+   return S_SUCCESS;
+
+error:
+   *ppName = NULL;
+   *pNameLength = 0;
+   *ppValue = NULL;
+   *pValueLength = 0;
+   return nResult;
+}
+
+S_RESULT libManifest2GetNextItem(
+   LIB_MANIFEST2_CONTEXT* pContext,
+   OUT uint8_t** ppName,
+   OUT uint32_t* pNameLength,
+   OUT uint8_t** ppValue,
+   OUT uint32_t* pValueLength)
+{
+   if (pContext->nType == LIB_MANIFEST2_TYPE_COMPILED)
+   {
+      /* Don't check for duplicates in binary manifests */
+      return static_libManifest2GetNextItemInternal(
+         pContext,
+         ppName,
+         pNameLength,
+         ppValue,
+         pValueLength);
+   }
+   else
+   {
+      uint32_t nOriginalOffset = pContext->nOffset;
+      uint32_t nOffset;
+      uint32_t nLine;
+      uint32_t nSectionStartOffset;
+      S_RESULT nResult;
+      uint8_t* pDupName;
+      uint32_t nDupNameLength;
+      uint8_t* pDupValue;
+      uint32_t nDupValueLength;
+
+      /* First get the item */
+      nResult = static_libManifest2GetNextItemInternal(
+         pContext,
+         ppName,
+         pNameLength,
+         ppValue,
+         pValueLength);
+      if (nResult != S_SUCCESS)
+      {
+         return nResult;
+      }
+      /* Save the state of the parser */
+      nOffset = pContext->nOffset;
+      nLine = pContext->nLine;
+      nSectionStartOffset = pContext->nSectionStartOffset;
+      if (pContext->nType == LIB_MANIFEST2_TYPE_SOURCE)
+      {
+         pContext->nOffset = 0;
+      }
+      else if (*ppValue == NULL)
+      {
+         /* The item was a section header. Iterate on all section headers and
+            check for duplicates */
+         pContext->nOffset = 0;
+      }
+      else
+      {
+         if (nSectionStartOffset == 0)
+         {
+            LOG_ERROR(pContext, "Property definition outside any section");
+            goto bad_format;
+         }
+         /* Iterate only on the properties in the section */
+         pContext->nOffset = nSectionStartOffset;
+      }
+      while (pContext->nOffset < nOriginalOffset)
+      {
+         static_libManifest2GetNextItemInternal(
+            pContext,
+            &pDupName,
+            &nDupNameLength,
+            &pDupValue,
+            &nDupValueLength);
+         if (pContext->nType == LIB_MANIFEST2_TYPE_SOURCE_WITH_SECTIONS && *ppValue == NULL)
+         {
+            /* Check for duplicate section names */
+            if (pDupValue == NULL
+                &&
+                static_sectionNameEqualCaseInsensitive(
+                   *ppName,
+                   *pNameLength,
+                   pDupName,
+                   nDupNameLength))
+            {
+               pContext->nOffset = nOffset;
+               pContext->nLine = nLine;
+               pContext->nSectionStartOffset = nSectionStartOffset;
+               LOG_ERROR(pContext, "Duplicate section %.*s", nDupNameLength, pDupName);
+               goto bad_format;
+            }
+         }
+         else
+         {
+            /* Check for duplicate property name */
+            if (nDupNameLength == *pNameLength &&
+                memcmp(pDupName, *ppName, nDupNameLength) == 0)
+            {
+               /* Duplicated property */
+               pContext->nOffset = nOffset;
+               pContext->nLine = nLine;
+               pContext->nSectionStartOffset = nSectionStartOffset;
+               LOG_ERROR(pContext,"Duplicate property %.*s", nDupNameLength, pDupName);
+               goto bad_format;
+            }
+         }
+      }
+      /* Everything's fine. restore context and exit  */
+      /* Restore the context */
+      pContext->nOffset = nOffset;
+      pContext->nLine = nLine;
+      pContext->nSectionStartOffset = nSectionStartOffset;
+
+      return S_SUCCESS;
+bad_format:
+      *ppName = NULL;
+      *pNameLength = 0;
+      *ppValue = NULL;
+      *pValueLength = 0;
+      return S_ERROR_BAD_FORMAT;
+   }
+}
+
+
+S_RESULT libManifest2CheckFormat(
+   LIB_MANIFEST2_CONTEXT* pContext,
+   uint32_t* pnItemCount)
+{
+   uint32_t nPropertyCount = 0;
+   uint8_t* pName;
+   uint32_t nNameLength;
+   uint8_t* pValue;
+   uint32_t nValueLength;
+   S_RESULT nResult;
+
+   pContext->nOffset = 0;
+   pContext->nLine = 1;
+   pContext->nSectionStartOffset = 0;
+
+   while (true)
+   {
+      nResult = libManifest2GetNextItem(
+         pContext,
+         &pName,
+         &nNameLength,
+         &pValue,
+         &nValueLength);
+      if (nResult == S_ERROR_ITEM_NOT_FOUND)
+      {
+         if (pnItemCount != NULL)
+         {
+            *pnItemCount = nPropertyCount;
+         }
+         return S_SUCCESS;
+      }
+      if (nResult != S_SUCCESS)
+      {
+         return nResult;
+      }
+      nPropertyCount++;
+   }
+}
diff --git a/security/tf_daemon/lib_manifest2.h b/security/tf_daemon/lib_manifest2.h
new file mode 100644
index 0000000..5ce727b
--- /dev/null
+++ b/security/tf_daemon/lib_manifest2.h
@@ -0,0 +1,111 @@
+/**
+ * Copyright(c) 2011 Trusted Logic.   All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *  * Neither the name Trusted Logic nor the names of its
+ *    contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This API allows parsing manifest files. A manifest is a text file that contains
+ * a property set. A property is a name-value pair.
+ *
+ * The BNF syntax of a manifest file is :
+ *
+ * See Spec of Client Authentication
+ *
+ * Note: for each property, trailing spaces and tabs between the ':' separator
+ * and the first character of the property value are discarded.
+ */
+
+
+#ifndef __LIB_MANIFEST2_H__
+#define __LIB_MANIFEST2_H__
+
+#include "s_error.h"
+#include "s_type.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+#if 0
+}  /* balance curly quotes */
+#endif
+
+/* The input file is a compiled manifest */
+#define LIB_MANIFEST2_TYPE_COMPILED 1
+/* The input file is a source manifest */
+#define LIB_MANIFEST2_TYPE_SOURCE 2
+/* The input file is a source manifest with sections */
+#define LIB_MANIFEST2_TYPE_SOURCE_WITH_SECTIONS 3
+
+typedef struct
+{
+   char* pManifestName;
+   uint32_t nType;
+   uint8_t* pManifestContent;
+   uint32_t nManifestLength;
+   uint32_t nOffset;
+   uint32_t nLine;
+   uint32_t nSectionStartOffset;
+}
+LIB_MANIFEST2_CONTEXT;
+
+/* Must be used before libManifest2GetNextItem.
+   The fields nType, pManifestContent, nManifestLength, and pManifestName (if applicable)
+   must be filled-in before.
+*/
+void libManifest2InitContext(
+   LIB_MANIFEST2_CONTEXT* pContext);
+
+/**
+ * Returns S_ITEM_NOT_FOUND for the last itel
+ *
+ * If type is LIB_MANIFEST2_TYPE_SOURCE, supports comments, multiple newlines, and leading BOM,
+ * and checks that properties are not duplicated
+ *
+ * If type is LIB_MANIFEST2_TYPE_SOURCE_WITH_SECTIONS, returns *pValue == NULL for a section
+ * Check that the section name contains only ASCII characters and that there is no duplicate
+ * sections (same name, case insensitive)
+ **/
+S_RESULT libManifest2GetNextItem(
+   LIB_MANIFEST2_CONTEXT* pContext,
+   OUT uint8_t** ppName,
+   OUT uint32_t* pNameLength,
+   OUT uint8_t** ppValue,
+   OUT uint32_t* pValueLength);
+
+S_RESULT libManifest2CheckFormat(
+   LIB_MANIFEST2_CONTEXT* pContext,
+   uint32_t* pnItemCount);
+
+#if 0
+{  /* balance curly quotes */
+#endif
+#ifdef __cplusplus
+}  /* closes extern "C" */
+#endif
+
+#endif  /* !defined(__LIB_MANIFEST_H__) */
diff --git a/security/tf_daemon/s_version.h b/security/tf_daemon/s_version.h
new file mode 100644
index 0000000..d112ea0
--- /dev/null
+++ b/security/tf_daemon/s_version.h
@@ -0,0 +1,113 @@
+/**
+ * Copyright(c) 2011 Trusted Logic.   All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *  * Neither the name Trusted Logic nor the names of its
+ *    contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#ifndef __S_VERSION_H__
+#define __S_VERSION_H__
+
+/*
+ * Usage: define S_VERSION_BUILD on the compiler's command line.
+ *
+ * Then set:
+ * - S_VERSION_OS
+ * - S_VERSION_PLATFORM
+ * - S_VERSION_MAIN
+ * - S_VERSION_ENG is optional
+ * - S_VERSION_PATCH is optional
+ * - S_VERSION_BUILD = 0 if S_VERSION_BUILD not defined or empty
+ */
+#if defined(WIN32)
+#define S_VERSION_OS "W"          /* "W" for Windows PC (XP, Vista…) */
+#define S_VERSION_PLATFORM "X"    /* "X" for ix86 PC simulators */
+#elif defined(__ANDROID32__)
+#define S_VERSION_OS "A"          /* "A" for Android */
+#define S_VERSION_PLATFORM "G"    /* "G" for 4430 */
+#elif defined(LINUX)
+#define S_VERSION_OS "L"          /* "L" for Linux */
+#define S_VERSION_PLATFORM "X"    /* "X" for ix86 PC simulators */
+#else
+#define S_VERSION_OS "X"          /* "X" for Secure-World */
+#define S_VERSION_PLATFORM "G"    /* "G" for 4430 */
+#endif
+
+/*
+ * This version number must be updated for each new release
+ */
+#define S_VERSION_MAIN  "01.04"
+#define S_VERSION_RESOURCE 1,4,0,S_VERSION_BUILD
+
+/*
+* If this is a patch or engineering version use the following
+* defines to set the version number. Else set these values to 0.
+*/
+#define S_VERSION_PATCH 11
+#define S_VERSION_ENG 0
+
+#ifdef S_VERSION_BUILD
+/* TRICK: detect if S_VERSION is defined but empty */
+#if 0 == S_VERSION_BUILD-0
+#undef  S_VERSION_BUILD
+#define S_VERSION_BUILD 0
+#endif
+#else
+/* S_VERSION_BUILD is not defined */
+#define S_VERSION_BUILD 0
+#endif
+
+#define __STRINGIFY(X) #X
+#define __STRINGIFY2(X) __STRINGIFY(X)
+
+#if S_VERSION_ENG != 0
+#define _S_VERSION_ENG "e" __STRINGIFY2(S_VERSION_ENG)
+#else
+#define _S_VERSION_ENG ""
+#endif
+
+#if S_VERSION_PATCH != 0
+#define _S_VERSION_PATCH "p" __STRINGIFY2(S_VERSION_PATCH)
+#else
+#define _S_VERSION_PATCH ""
+#endif
+
+#if !defined(NDEBUG) || defined(_DEBUG)
+#define S_VERSION_VARIANT "D   "
+#else
+#define S_VERSION_VARIANT "    "
+#endif
+
+#define S_VERSION_STRING \
+	"SMC" \
+	S_VERSION_OS \
+	S_VERSION_PLATFORM \
+	S_VERSION_MAIN \
+	_S_VERSION_PATCH \
+	_S_VERSION_ENG \
+	"."  __STRINGIFY2(S_VERSION_BUILD) " " \
+	S_VERSION_VARIANT
+
+#endif /* __S_VERSION_H__ */
diff --git a/security/tf_daemon/service_delegation_protocol.h b/security/tf_daemon/service_delegation_protocol.h
new file mode 100644
index 0000000..22b291d
--- /dev/null
+++ b/security/tf_daemon/service_delegation_protocol.h
@@ -0,0 +1,114 @@
+/**
+ * Copyright(c) 2011 Trusted Logic.   All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *  * Neither the name Trusted Logic nor the names of its
+ *    contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __SERVICE_DELEGATION_PROTOCOL_H__
+#define __SERVICE_DELEGATION_PROTOCOL_H__
+
+#include "s_type.h"
+
+/* -----------------------------------------------------------------------------
+   UUID
+----------------------------------------------------------------------------- */
+/** Service Identifier: {71139E60-ECAE-11DF-98CF-0800200C9A66} */
+#define SERVICE_DELEGATION_UUID { 0x71139e60, 0xecae, 0x11df, { 0x98, 0xcf, 0x08, 0x00, 0x20, 0x0c, 0x9a, 0x66 } }
+
+
+/* -----------------------------------------------------------------------------
+   Command identifiers
+----------------------------------------------------------------------------- */
+/* See your Product Reference Manual for a specification of the delegation protocol */
+
+/**
+ * Command identifier : get instruction
+ *
+ */
+#define SERVICE_DELEGATION_GET_INSTRUCTIONS      0x00000002
+
+/* Instruction codes */
+#define DELEGATION_INSTRUCTION_SHUTDOWN             0xF0
+#define DELEGATION_INSTRUCTION_NOTIFY               0xE0
+
+/* Partition-specific instruction codes (high-nibble encodes the partition identifier) */
+#define DELEGATION_INSTRUCTION_PARTITION_CREATE     0x01
+#define DELEGATION_INSTRUCTION_PARTITION_OPEN       0x02
+#define DELEGATION_INSTRUCTION_PARTITION_READ       0x03
+#define DELEGATION_INSTRUCTION_PARTITION_WRITE      0x04
+#define DELEGATION_INSTRUCTION_PARTITION_SET_SIZE   0x05
+#define DELEGATION_INSTRUCTION_PARTITION_SYNC       0x06
+#define DELEGATION_INSTRUCTION_PARTITION_CLOSE      0x07
+#define DELEGATION_INSTRUCTION_PARTITION_DESTROY    0x08
+
+#define DELEGATION_NOTIFY_TYPE_ERROR                0x000000E1
+#define DELEGATION_NOTIFY_TYPE_WARNING              0x000000E2
+#define DELEGATION_NOTIFY_TYPE_INFO                 0x000000E3
+#define DELEGATION_NOTIFY_TYPE_DEBUG                0x000000E4
+
+typedef struct
+{
+   uint32_t nInstructionID;
+} DELEGATION_GENERIC_INSTRUCTION;
+
+typedef struct
+{
+   uint32_t nInstructionID;
+   uint32_t nMessageType;
+   uint32_t nMessageSize;
+   char     nMessage[1];
+} DELEGATION_NOTIFY_INSTRUCTION;
+
+typedef struct
+{
+   uint32_t nInstructionID;
+   uint32_t nSectorID;
+   uint32_t nWorkspaceOffset;
+} DELEGATION_RW_INSTRUCTION;
+
+typedef struct
+{
+   uint32_t nInstructionID;
+   uint32_t nNewSize;
+} DELEGATION_SET_SIZE_INSTRUCTION;
+
+typedef union
+{
+   DELEGATION_GENERIC_INSTRUCTION    sGeneric;
+   DELEGATION_NOTIFY_INSTRUCTION     sNotify;
+   DELEGATION_RW_INSTRUCTION         sReadWrite;
+   DELEGATION_SET_SIZE_INSTRUCTION   sSetSize;
+} DELEGATION_INSTRUCTION;
+
+typedef struct
+{
+   uint32_t    nSyncExecuted;
+   uint32_t    nPartitionErrorStates[16];
+   uint32_t    nPartitionOpenSizes[16];
+} DELEGATION_ADMINISTRATIVE_DATA;
+
+#endif /* __SERVICE_DELEGATION_PROTOCOL_H__ */
diff --git a/security/tf_daemon/smc_properties.c b/security/tf_daemon/smc_properties.c
new file mode 100644
index 0000000..ce1e7e3
--- /dev/null
+++ b/security/tf_daemon/smc_properties.c
@@ -0,0 +1,323 @@
+/**
+ * Copyright(c) 2011 Trusted Logic.   All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *  * Neither the name Trusted Logic nor the names of its
+ *    contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <ctype.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <fcntl.h>
+
+#if defined(_WIN32_WCE)
+#include "os_wm.h"
+#else
+#include <sys/stat.h>
+#endif
+
+#include "smc_properties.h"
+#include "smc_properties_parser.h"
+#include "s_type.h"
+#include "s_error.h"
+
+#if defined(__SYMBIAN32__)
+#include "smc_properties_symbian.h"
+#endif
+
+
+#define SECURE_CONFIG_FILE_HDR     66
+#define SECURE_CONFIG_FILE_VERSION 01
+
+
+#define SYSTEM_SECTION_NAME               "Global"
+
+typedef enum {
+   MANDATORY_FILE_SYSTEM_FILE_NAME,
+   MANDATORY_KEYSTORE_SYSTEM_FILE_NAME,
+   MANDATORY_KEYSTORE_USER_FILE_NAME,
+   MANDATORY_SUPER_PARTITION_FILE_NAME,
+
+   NB_MANDATORY_PROPS,
+} MANDATORY_PROPS;
+
+
+typedef enum
+{
+   STATE_NONE,
+   STATE_DECIMAL,
+   STATE_HEXA,
+   STATE_BINARY
+} INTEGER_FORMAT;
+
+#if defined (LINUX) || defined(__ANDROID32__)
+#define SEPARATOR_CHAR '/'
+
+#elif defined (WIN32) || defined (__SYMBIAN32__) || defined (_WIN32_WCE)
+#define SEPARATOR_CHAR '\\'
+
+#else
+#error SEPARATOR_CHAR not implemented...
+#endif
+
+#if defined(__SYMBIAN32__)
+#define printf RDebugPrintf
+#endif
+
+
+/** the sturct that keep the data stored in the config file */
+static CONF_FILE gConfFile;
+
+
+
+/**
+ * check the validity of a given path (is a directory, has the READ/WRITE access rights)
+ * @param pPath the path we want to check
+ * @return true if the path is OK, else false
+ */
+static bool checkFilePath(char *pPath)
+{
+   struct stat buf;
+   uint32_t  result;
+   char *pDir = pPath;
+
+   // cobra & buffalo version : complete path (directory and filename) is given in the config file.
+   // so we extract from this path the parent directory
+   {
+      uint32_t nSlashIndex = 0;
+      uint32_t i = 0;
+      while(pPath[i] != '\0')
+      {
+         if (pPath[i] == SEPARATOR_CHAR)
+            nSlashIndex = i;
+         i++;
+      }
+      pDir = malloc(sizeof(char) * nSlashIndex);
+      if (pDir == NULL)
+      {
+         printf("Out of memory.");
+         return false;
+      }
+      strncpy(pDir, pPath, nSlashIndex);
+      pDir[nSlashIndex] = '\0';
+   }
+
+   /* check if file exists */
+   result = stat(pDir, &buf);
+   if(result != 0 )
+   {
+#if defined(__SYMBIAN32__)
+      if (SymbianCheckFSDirectory(pDir) == -1)
+      {
+         printf("Cannot create directory : %s\n.", pDir);
+         return false;
+      }
+#else
+      printf("Unknown path : %s\n.", pDir);
+      return false;
+#endif
+   }
+   else
+   {
+      /* check it's a directory */
+      if ((buf.st_mode & S_IFDIR) != S_IFDIR)
+      {
+         printf("Path %s doesn't point on a directory.\n", pDir);
+         return false;
+      }
+#if (!defined(__SYMBIAN32__)) && (!defined(_WIN32_WCE)) && (!defined(__ANDROID32__))
+      // TODO : under Symbian, Android and WM, check access right of a directory failed? I don't know why...
+       /* check read access */
+       if ((buf.st_mode & S_IREAD) != S_IREAD)
+       {
+          printf("Path %s doesn't have the READ access rights.\n", pDir);
+          return false;
+       }
+       /* check write */
+       if ((buf.st_mode & S_IWRITE) != S_IWRITE)
+       {
+          printf("Path %s doesn't have the WRITE access rights.\n", pDir);
+          return false;
+       }
+#endif
+   }
+
+   return true;
+}
+
+/**
+ * check properties (value, range...)
+ * @param sConfFile struct where are stored the properties we will check
+ * @return true if the check succeed, else false
+ */
+static bool smcPropertiesCheck(CONF_FILE sConfFile)
+{
+   NODE* pNext = NULL;
+   char *pPropVal = NULL;
+   bool bCheckResult = true;
+   bool pMandatoryProps[NB_MANDATORY_PROPS];
+   uint32_t i = 0;
+
+   // reset properties table
+   for (i=0; i<NB_MANDATORY_PROPS; i++)
+      pMandatoryProps[i] = false;
+
+   // check properties type and set MandatoryProps field to true (check later)
+   pNext = sConfFile.sSystemSectionPropertyList.pFirst;
+   while(pNext != NULL)
+   {
+      pPropVal = ((PROPERTY*)pNext)->pValue;
+
+      //printf("Checking %s = %s.\n", pNext->pName, pPropVal);
+      if(strcmp(pNext->pName, FILE_SYSTEM_FILE_NAME) == 0)
+      {
+         /* File System */
+         bCheckResult = checkFilePath(pPropVal);
+         pMandatoryProps[MANDATORY_FILE_SYSTEM_FILE_NAME] = true;
+      }
+      else if(strcmp(pNext->pName, KEYSTORE_SYSTEM_FILE_NAME) == 0)
+      {
+         bCheckResult = checkFilePath(pPropVal);
+         pMandatoryProps[MANDATORY_KEYSTORE_SYSTEM_FILE_NAME] = true;
+      }
+      else if(strcmp(pNext->pName, KEYSTORE_USER_FILE_NAME) == 0)
+      {
+         bCheckResult = checkFilePath(pPropVal);
+         pMandatoryProps[MANDATORY_KEYSTORE_USER_FILE_NAME] = true;
+      }
+      else if(strcmp(pNext->pName, SUPER_PARTITION_FILE_NAME) == 0)
+      {
+         bCheckResult = checkFilePath(pPropVal);
+         pMandatoryProps[MANDATORY_SUPER_PARTITION_FILE_NAME] = true;
+      }
+      else
+      {
+         bCheckResult = true;
+      }
+
+      if (! bCheckResult)
+      {
+         printf("Property %s = %s. Bad value!!!\n", pNext->pName, pPropVal);
+         return false;
+      }
+      pNext=pNext->pNext;
+   }
+
+   /* check all mandatory properties had been found */
+   for (i=0; i<NB_MANDATORY_PROPS; i++)
+   {
+      if (!pMandatoryProps[i])
+      {
+         char *pMissingProp = NULL;
+         switch(i){
+            case MANDATORY_FILE_SYSTEM_FILE_NAME :
+               pMissingProp = FILE_SYSTEM_FILE_NAME;
+               break;
+            case MANDATORY_KEYSTORE_SYSTEM_FILE_NAME :
+               pMissingProp = KEYSTORE_SYSTEM_FILE_NAME;
+               break;
+            case MANDATORY_KEYSTORE_USER_FILE_NAME :
+               pMissingProp = KEYSTORE_USER_FILE_NAME;
+               break;
+            case MANDATORY_SUPER_PARTITION_FILE_NAME :
+               pMissingProp = SUPER_PARTITION_FILE_NAME;
+               break;
+         }
+         printf("Mandatory property %s is missing.\n", pMissingProp);
+         bCheckResult = false;
+      }
+   }
+
+   return bCheckResult;
+}
+
+
+
+/**
+ * parse the config file
+ * @param configFile the path of the configuration file
+ * @return 0 if succeed, else 1
+ */
+int smcPropertiesParse(const char *configFile)
+{
+   S_RESULT nResult = S_SUCCESS;
+
+   // first : parse the config file
+   memset(&gConfFile, 0x00, sizeof(CONF_FILE));
+   nResult=SMCPropParseConfigFile((char *)configFile, &gConfFile);
+   if (nResult!=S_SUCCESS)
+   {
+      printf("Parsing error in file %s : %x.\n", configFile, nResult);
+      return 1;
+   }
+
+   // check properties
+   if (!smcPropertiesCheck(gConfFile))
+   {
+      printf("Properties check failed.\n");
+      return 1;
+   }
+
+   return 0;
+}
+
+
+
+/**
+ * get the value of a property
+ * @param pProp we are asking the value of this property
+ * @return the value if found, else NULL
+ */
+char *smcGetPropertyAsString(char *pProp)
+{
+   return SMCPropGetSystemProperty(&gConfFile, pProp);
+}
+
+
+/**
+ * get the value of a property
+ * @param pProp we are asking the value of this property
+ * @param pVal the value of the property
+ * @return 0 if found, else 1 (and pVal set to 0)
+ */
+int smcGetPropertyAsInt(char *pProp, int *pVal)
+{
+   char *pStr = SMCPropGetSystemProperty(&gConfFile, pProp);
+   if (pStr == NULL)
+   {
+      *pVal = 0;
+      return 1;
+   }
+   if (libString2GetStringAsInt(pStr, (uint32_t*)pVal) == S_SUCCESS)
+   {
+      return 0;
+   }
+   *pVal = 0;
+   return 1;
+}
diff --git a/security/tf_daemon/smc_properties.h b/security/tf_daemon/smc_properties.h
new file mode 100644
index 0000000..d7532ce
--- /dev/null
+++ b/security/tf_daemon/smc_properties.h
@@ -0,0 +1,75 @@
+/**
+ * Copyright(c) 2011 Trusted Logic.   All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *  * Neither the name Trusted Logic nor the names of its
+ *    contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _SMC_PROPERTIES_H__
+#define _SMC_PROPERTIES_H__
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* definition of public properties (Driver and tf_daemon) */
+#define FILE_SYSTEM_FILE_NAME             "filesystem.storage.fileName"
+#define KEYSTORE_SYSTEM_FILE_NAME         "filesystem.keystore.fileName"
+#define KEYSTORE_USER_FILE_NAME           "filesystem.keystore.user.fileName"
+#define SUPER_PARTITION_FILE_NAME         "filesystem.mc.fileName"
+
+
+/**
+ * parse the config file
+ * @param configFile the path of the configuration file
+ * @return 0 if succeed, else 1
+ */
+int smcPropertiesParse(const char *pConfigFile);
+
+
+/**
+ * get the value of a property
+ * @param pProp we are asking the value of this property
+ * @return the value if found, else NULL
+ */
+char *smcGetPropertyAsString(char *pProp);
+
+
+/**
+ * get the value of a property
+ * @param pProp we are asking the value of this property
+ * @param pVal the value of the property
+ * @return 0 if found, else 1
+ */
+int smcGetPropertyAsInt(char *pProp, int *pVal);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _SMC_PROPERTIES_H__ */
diff --git a/security/tf_daemon/smc_properties_parser.c b/security/tf_daemon/smc_properties_parser.c
new file mode 100644
index 0000000..1f97224
--- /dev/null
+++ b/security/tf_daemon/smc_properties_parser.c
@@ -0,0 +1,556 @@
+/**
+ * Copyright(c) 2011 Trusted Logic.   All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *  * Neither the name Trusted Logic nor the names of its
+ *    contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <stdlib.h>
+#include <assert.h>
+#include <stdio.h>
+#include <ctype.h>
+#include <string.h>
+
+#if defined(_WIN32_WCE)
+#include "os_wm.h"
+#else
+#include <errno.h>
+#endif
+
+#include "smc_properties_parser.h"
+#include "lib_manifest2.h"
+#include "s_error.h"
+
+/* ---------------------------------------------------------------------------------
+   Defines
+   ---------------------------------------------------------------------------------*/
+
+#define STRUE                             "true"
+#define SFALSE                            "false"
+
+#if defined(_WIN32_WCE)
+#define GET_LAST_ERR GetLastError()
+#else
+#define GET_LAST_ERR  errno
+#endif
+
+#if defined (LINUX) || defined (__SYMBIAN32__) || defined (__ANDROID32__)
+#define STRICMP strcasecmp
+#elif defined(_WIN32_WCE)
+#define STRICMP _stricmp
+#else
+#define STRICMP stricmp
+#endif
+
+
+/* ---------------------------------------------------------------------------------
+   Logs and Traces.
+   ---------------------------------------------------------------------------------*/
+#ifdef __SYMBIAN32__
+#include "os_symbian.h"
+#elif NDEBUG
+/* Compile-out the traces */
+#define TRACE_ERROR(...)
+#define TRACE_WARNING(...)
+#define TRACE_INFO(...)
+#else
+#include <stdarg.h>
+static void TRACE_ERROR(const char* format, ...)
+{
+   va_list ap;
+   va_start(ap, format);
+   fprintf(stderr, "TRACE: ERROR: ");
+   vfprintf(stderr, format, ap);
+   fprintf(stderr, "\n");
+   va_end(ap);
+}
+
+static void TRACE_WARNING(const char* format, ...)
+{
+   va_list ap;
+   va_start(ap, format);
+   fprintf(stderr, "TRACE: WARNING: ");
+   vfprintf(stderr, format, ap);
+   fprintf(stderr, "\n");
+   va_end(ap);
+}
+
+static void TRACE_INFO(const char* format, ...)
+{
+   va_list ap;
+   va_start(ap, format);
+   fprintf(stderr, "TRACE: ");
+   vfprintf(stderr, format, ap);
+   fprintf(stderr, "\n");
+   va_end(ap);
+}
+#endif /* NDEBUG */
+
+/* ---------------------------------------------------------------------------------
+   private functions.
+   ---------------------------------------------------------------------------------*/
+
+static NODE* static_listFindNodeElement(NODE* pList,char* pName,bool bIsCaseSensitive)
+{
+   int32_t nCmp;
+
+   assert(pName!=NULL);
+
+   while (pList!=NULL)
+   {
+      if (bIsCaseSensitive)
+      {
+         nCmp=strcmp(pName,pList->pName);
+      }
+      else
+      {
+         nCmp=STRICMP(pName,pList->pName);
+      }
+      if (nCmp>0)
+      {
+         pList=pList->pRight;
+      }
+      else if (nCmp<0)
+      {
+         pList=pList->pLeft;
+      }
+      else
+      {
+         break;
+      }
+   }
+   return pList;
+}
+
+
+static S_RESULT static_listSortedAddNode(NODE* pList,NODE* pNode)
+{
+   int32_t nCmp;
+
+   do {
+      nCmp=strcmp(pNode->pName,pList->pName);
+      if (nCmp>0)
+      {
+         if (pList->pRight!=NULL)
+         {
+            pList=pList->pRight;
+         }
+         else
+         {
+            pList->pRight=pNode;
+            /* update linked list */
+            pNode->pPrevious=pList;
+            pNode->pNext=pList->pNext;
+            if (pList->pNext!=NULL)
+            {
+               pList->pNext->pPrevious=pNode;
+            }
+            pList->pNext=pNode;
+            return S_SUCCESS;
+         }
+      }
+      else if (nCmp<0)
+      {
+         if (pList->pLeft!=NULL)
+         {
+            pList=pList->pLeft;
+         }
+         else
+         {
+            pList->pLeft=pNode;
+            /* update linked list */
+            pNode->pNext=pList;
+            pNode->pPrevious=pList->pPrevious;
+            if (pList->pPrevious!=NULL)
+            {
+               pList->pPrevious->pNext=pNode;
+            }
+            pList->pPrevious=pNode;
+            return S_SUCCESS;
+         }
+      }
+   } while (nCmp!=0);
+
+   TRACE_ERROR("%s already exist !\n",pNode->pName);
+   return S_ERROR_ITEM_EXISTS;
+}
+
+
+static S_RESULT SMCPropListSortedAdd(LIST* pList,NODE* pNode)
+{
+   S_RESULT nResult;
+
+   assert(pList!=NULL && pNode!=NULL);
+
+   if (pNode->pName==NULL)
+   {
+	   TRACE_ERROR("Trying to insert a NULL node name !\n");
+      return S_ERROR_BAD_PARAMETERS;
+   }
+
+   if (pList->pRoot==NULL)
+   {
+      pList->pRoot=pNode;
+      pList->pFirst=pNode;
+      return S_SUCCESS;
+   }
+   else
+   {
+      nResult=static_listSortedAddNode(pList->pRoot,pNode);
+      /* update the first node of the linked list */
+      if (nResult==S_SUCCESS && pNode->pPrevious==NULL)
+      {
+         pList->pFirst=pNode;
+      }
+   }
+   return nResult;
+}
+
+
+static NODE* SMCPropListFindElement(LIST* pList,char* pName,bool bIsCaseSensitive)
+{
+   if (pList->pRoot!=NULL)
+   {
+      return static_listFindNodeElement(pList->pRoot,pName,bIsCaseSensitive);
+   }
+   return NULL;
+}
+
+
+static S_RESULT SMCPropYacc(uint8_t* pBuffer, uint32_t nBufferLength,
+                     CONF_FILE* pConfFile)
+{
+   S_RESULT nError=S_SUCCESS;
+   LIST *pPublicPropertyList=NULL;
+   LIST *pPrivatePropertyList=NULL;
+   PROPERTY* pProperty=NULL;
+   SERVICE_SECTION* pServSection;
+   SERVICE_SECTION* pPreviousService=NULL;
+
+   uint8_t* pName;
+   uint32_t nNameLength;
+   uint8_t* pValue;
+   uint32_t nValueLength;
+   char* pNameZ = NULL;
+   char* pValueZ = NULL;
+   LIB_MANIFEST2_CONTEXT sParserContext;
+   char serviceManifestName[1024];
+
+   sParserContext.pManifestName = "Configuration File";
+   sParserContext.pManifestContent = pBuffer;
+   sParserContext.nManifestLength = nBufferLength;
+   sParserContext.nType = LIB_MANIFEST2_TYPE_SOURCE_WITH_SECTIONS;
+
+   libManifest2InitContext(&sParserContext);
+
+   while (true)
+   {
+      nError = libManifest2GetNextItem(
+         &sParserContext,
+         &pName,
+         &nNameLength,
+         &pValue,
+         &nValueLength);
+      if (nError == S_ERROR_ITEM_NOT_FOUND)
+      {
+         /* End of parsing */
+         nError = S_SUCCESS;
+         break;
+      }
+      else if (nError != S_SUCCESS)
+      {
+         /* Error */
+         goto error;
+      }
+
+      /* Duplicate name and value in as zero-terminated strings */
+      /* Unclean: those strings are not going to be deallocated
+         This is not a problem because this code is run in a tool
+      */
+      pNameZ = malloc(nNameLength+1);
+      if (pNameZ == NULL)
+      {
+         nError = S_ERROR_OUT_OF_MEMORY;
+         goto error;
+      }
+      memcpy(pNameZ, pName, nNameLength);
+      pNameZ[nNameLength] = 0;
+
+      if (pValue == NULL)
+      {
+         /* It's a section */
+         if (STRICMP(pNameZ, SYSTEM_SECTION_NAME) == 0)
+         {
+            free(pNameZ);
+            pPublicPropertyList=&pConfFile->sSystemSectionPropertyList;
+         }
+         else
+         {
+            pServSection=(SERVICE_SECTION*)SMCPropListFindElement(
+               &pConfFile->sDriverSectionList,
+               pNameZ,
+               false);
+            if (pServSection==NULL)
+            {
+               pServSection=(SERVICE_SECTION*)SMCPropListFindElement(
+                     &pConfFile->sPreinstalledSectionList,
+                     pNameZ,
+                     false);
+            }
+            if (pServSection==NULL)
+            {
+               pServSection=(SERVICE_SECTION*)SMCPropListFindElement(
+                  &pConfFile->sSectionList,
+                  pNameZ,
+                  false);
+               if (pServSection==NULL)
+               {
+                  nError=S_ERROR_ITEM_NOT_FOUND;
+                  goto error;
+               }
+            }
+            free(pNameZ);
+
+            pServSection->inSCF=true;
+            if (pPreviousService!=NULL)
+            {
+               pPreviousService->pNextInSCF=pServSection;
+            }
+            else
+            {
+               pConfFile->pFirstSectionInSCF=pServSection;
+            }
+            pPreviousService=pServSection;
+
+            pPublicPropertyList=&pServSection->sPublicPropertyList;
+            pPrivatePropertyList=&pServSection->sPrivatePropertyList;
+         }
+      }
+      else
+      {
+         /* It's a property definition */
+         pValueZ = malloc(nValueLength+1);
+         if (pValueZ == NULL)
+         {
+            nError = S_ERROR_OUT_OF_MEMORY;
+            goto error;
+         }
+         memcpy(pValueZ, pValue, nValueLength);
+         pValueZ[nValueLength] = 0;
+
+         pProperty=(PROPERTY*)malloc(sizeof(PROPERTY));
+         if (pProperty==NULL)
+         {
+            nError=S_ERROR_OUT_OF_MEMORY;
+            goto error;
+         }
+         memset(pProperty, 0x00, sizeof(PROPERTY));
+         pProperty->sNode.pName=pNameZ;
+
+         pProperty->pValue=pValueZ;
+
+         if (pPrivatePropertyList==NULL)
+         {
+            nError=SMCPropListSortedAdd(pPublicPropertyList,(NODE*)pProperty);
+            if (nError!=S_SUCCESS)
+            {
+               goto error;
+            }
+         }
+         else
+         {
+            if ((nValueLength > strlen(CONFIG_PROPERTY_NAME)) &&
+                (memcmp(pProperty->sNode.pName, CONFIG_PROPERTY_NAME, strlen(CONFIG_PROPERTY_NAME)) == 0))
+            {
+               nError=SMCPropListSortedAdd(pPrivatePropertyList,(NODE*)pProperty);
+            }
+            else
+            {
+               nError=SMCPropListSortedAdd(pPublicPropertyList,(NODE*)pProperty);
+            }
+            if (nError!=S_SUCCESS)
+            {
+               goto error;
+            }
+         }
+      }
+   }
+
+error:
+   if (nError!=S_SUCCESS)
+   {
+      switch (nError)
+      {
+      case S_ERROR_BAD_FORMAT:
+         /* Error message already output */
+         break;
+      case S_ERROR_WRONG_SIGNATURE:
+         TRACE_ERROR("Configuration file: wrong service UUID: %s\n", pValueZ);
+         break;
+      case S_ERROR_OUT_OF_MEMORY:
+	  TRACE_ERROR("Out of memory\n");
+         break;
+      case S_ERROR_ITEM_NOT_FOUND:
+	  TRACE_ERROR("Configuration file: service \"%s\" not found\n", pNameZ);
+         break;
+      }
+   }
+   return nError;
+}
+
+
+S_RESULT static_readFile(const char* pFilename, void** ppFile, uint32_t* pnFileLength)
+{
+   S_RESULT nResult = S_SUCCESS;
+   long nFilesize;
+   FILE* pFile = NULL;
+   void *pBuff = NULL;
+
+   // open file and get its size...
+   if ((pFile = fopen(pFilename, "rb")) == NULL)
+   {
+      TRACE_ERROR("static_readFile: fopen(%s) failed [%d]", pFilename, GET_LAST_ERR);
+	   nResult = S_ERROR_ITEM_NOT_FOUND;
+	   return nResult;
+   }
+   if (fseek(pFile, 0, SEEK_END) != 0)
+   {
+      TRACE_ERROR("static_readFile: fseek(%s) failed [%d]", pFilename, GET_LAST_ERR);
+	   nResult = S_ERROR_UNDERLYING_OS;
+	   goto error;
+   }
+   nFilesize = ftell(pFile);
+   if (nFilesize < 0)
+   {
+      TRACE_ERROR("static_readFile: ftell(%s) failed [%d]", pFilename, GET_LAST_ERR);
+	   nResult = S_ERROR_UNDERLYING_OS;
+	   goto error;
+   }
+   rewind(pFile);
+
+   // allocate the buffer
+   pBuff = malloc(nFilesize + 1);
+   if (pBuff == NULL)
+   {
+      TRACE_ERROR("static_readFile: out of memory");
+      nResult = S_ERROR_OUT_OF_MEMORY;
+      goto error;
+   }
+
+   // read the file
+   if (fread(pBuff, sizeof(uint8_t), (size_t)nFilesize, pFile) != (size_t)nFilesize)
+   {
+      TRACE_ERROR("static_readFile: fread failed [%d]", GET_LAST_ERR);
+      nResult = S_ERROR_UNDERLYING_OS;
+      goto error;
+   }
+   ((char*)pBuff)[nFilesize] = 0;
+
+   *ppFile = pBuff;
+   *pnFileLength = nFilesize;
+   return S_SUCCESS;
+
+error:
+   if (pBuff != NULL)
+      free(pBuff);
+   fclose(pFile);
+
+   *ppFile = NULL;
+   *pnFileLength = 0;
+   return nResult;
+}
+
+
+
+
+
+/* ---------------------------------------------------------------------------------
+   API functions.
+   ---------------------------------------------------------------------------------*/
+
+char* SMCPropGetSystemProperty(CONF_FILE* pConfFile, char* pPropertyName)
+{
+   PROPERTY* pProperty;
+
+   pProperty=(PROPERTY*)SMCPropListFindElement(
+      &pConfFile->sSystemSectionPropertyList,
+      pPropertyName,
+      true);
+   if (pProperty!=NULL)
+   {
+      return pProperty->pValue;
+   }
+   return NULL;
+}
+
+uint32_t SMCPropGetSystemPropertyAsInt(CONF_FILE* pConfFile, char* pPropertyName)
+{
+   uint32_t nValue;
+   char* pValue=SMCPropGetSystemProperty(pConfFile,pPropertyName);
+
+   if (libString2GetStringAsInt(pValue, &nValue) == S_SUCCESS)
+   {
+      return nValue;
+   }
+   return 0;
+}
+
+
+S_RESULT SMCPropParseConfigFile(char* pConfigFilename,CONF_FILE* pConfFile)
+{
+   S_RESULT nError=S_SUCCESS;
+   void* pFile;
+   uint32_t nFileLength;
+   bool bReuseManifest;
+
+   assert(pConfFile!=NULL);
+
+   TRACE_INFO("Processing configuration file '%s'", pConfigFilename);
+
+   if(pConfigFilename != NULL)
+   {
+      nError=static_readFile(pConfigFilename,&pFile,&nFileLength);
+      if (nError!=S_SUCCESS)
+      {
+         goto error;
+      }
+      bReuseManifest = true;
+   }
+   else
+   {
+      assert(0);
+   }
+
+   nError=SMCPropYacc(pFile,nFileLength,pConfFile);
+
+   if(pConfigFilename != NULL)
+   {
+      free(pFile);
+   }
+
+error:
+   return nError;
+}
diff --git a/security/tf_daemon/smc_properties_parser.h b/security/tf_daemon/smc_properties_parser.h
new file mode 100644
index 0000000..eebd1d6
--- /dev/null
+++ b/security/tf_daemon/smc_properties_parser.h
@@ -0,0 +1,125 @@
+/**
+ * Copyright(c) 2011 Trusted Logic.   All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *  * Neither the name Trusted Logic nor the names of its
+ *    contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+#ifndef __SMC_PROPERTIES_PARSER_H__
+#define __SMC_PROPERTIES_PARSER_H__
+
+
+
+#include "s_type.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/* ---------------------------------------------------------------------------------
+   Defines
+   ---------------------------------------------------------------------------------*/
+
+#define SYSTEM_SECTION_NAME               "Global"
+#define CONFIG_SERVICE_ID_PROPERTY_NAME   "config.s.serviceID"
+#define CONFIG_PROPERTY_NAME              "config."
+
+
+
+/* ---------------------------------------------------------------------------------
+   types definition
+   ---------------------------------------------------------------------------------*/
+
+typedef struct NODE
+{
+   struct NODE* pLeft;
+   struct NODE* pRight;
+   struct NODE* pNext;
+   struct NODE* pPrevious;
+   char* pName;
+} NODE;
+
+typedef struct
+{
+   NODE* pRoot;
+   NODE* pFirst;
+} LIST;
+
+typedef struct
+{
+   NODE sNode;
+   char* pValue;
+   bool bChecked; /* Whether it has been checked that this property is allowed */
+} PROPERTY;
+
+typedef struct
+{
+   NODE sNode;
+   struct S_PROPERTY* pProperty;
+} S_PROPERTY_NODE;
+
+typedef struct SERVICE_SECTION
+{
+   NODE sNode;
+   bool inSCF;
+   struct SERVICE_SECTION* pNextInSCF; /* next section defined in config file */
+   S_UUID sUUID;
+   uint32_t nFlags;
+   char* pComment;
+   void* pFileInfo;     /* used to retreive filename and MD5 hash (optional) */
+   LIST sPublicPropertyList;
+   LIST sPrivatePropertyList;
+} SERVICE_SECTION;
+
+typedef struct
+{
+   char* pComment;
+   LIST sSystemSectionPropertyList;
+   SERVICE_SECTION* pFirstSectionInSCF; /* first section defined in config file */
+   LIST sDriverSectionList;
+   LIST sPreinstalledSectionList;
+   LIST sSectionList;
+} CONF_FILE;
+
+
+
+/* ---------------------------------------------------------------------------------
+   Prototypes
+   ---------------------------------------------------------------------------------*/
+
+uint32_t SMCPropStringToInt           (char* pValue);
+char*    SMCPropGetSystemProperty     (CONF_FILE* pConfFile, char* pPropertyName);
+uint32_t SMCPropGetSystemPropertyAsInt(CONF_FILE* pConfFile, char* pPropertyName);
+S_RESULT SMCPropParseConfigFile       (char* pConfigFilename,CONF_FILE* pConfFile);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __SMC_PROPERTIES_PARSER_H__ */
diff --git a/security/tf_sdk/include/cryptoki.h b/security/tf_sdk/include/cryptoki.h
new file mode 100644
index 0000000..41a66ec
--- /dev/null
+++ b/security/tf_sdk/include/cryptoki.h
@@ -0,0 +1,54 @@
+/**

+ * Copyright(c) 2011 Trusted Logic.   All rights reserved.

+ * 

+ * Redistribution and use in source and binary forms, with or without

+ * modification, are permitted provided that the following conditions

+ * are met:

+ *

+ *  * Redistributions of source code must retain the above copyright

+ *    notice, this list of conditions and the following disclaimer.

+ *  * Redistributions in binary form must reproduce the above copyright

+ *    notice, this list of conditions and the following disclaimer in

+ *    the documentation and/or other materials provided with the

+ *    distribution.

+ *  * Neither the name Trusted Logic nor the names of its

+ *    contributors may be used to endorse or promote products derived

+ *    from this software without specific prior written permission.

+ *

+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS

+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT

+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR

+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT

+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,

+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT

+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,

+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY

+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT

+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE

+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

+ */

+#ifndef __CRYPTOKI_H__

+#define __CRYPTOKI_H__

+

+#include "s_type.h"

+

+/* Define CRYPTOKI_EXPORTS during the build of cryptoki libraries. Do

+ * not define it in applications.

+ */

+#ifdef CRYPTOKI_EXPORTS

+#define PKCS11_EXPORT S_DLL_EXPORT

+#else

+#define PKCS11_EXPORT S_DLL_IMPORT

+#endif

+

+#define CKV_TOKEN_SYSTEM                           0x00000001

+#define CKV_TOKEN_SYSTEM_SHARED                    0x00000000

+#define CKV_TOKEN_USER                             0x00004004

+#define CKV_TOKEN_USER_SHARED                      0x00004012

+

+#define CKV_TOKEN_SYSTEM_GROUP(gid)                (0x00010000 | (gid))

+#define CKV_TOKEN_USER_GROUP(gid)                  (0x00020000 | (gid))

+

+#include "pkcs11.h"

+

+#endif /* __CRYPTOKI_H__ */

diff --git a/security/tf_sdk/include/mtc.h b/security/tf_sdk/include/mtc.h
new file mode 100644
index 0000000..ed828b3
--- /dev/null
+++ b/security/tf_sdk/include/mtc.h
@@ -0,0 +1,97 @@
+/**

+ * Copyright(c) 2011 Trusted Logic.   All rights reserved.

+ *

+ * Redistribution and use in source and binary forms, with or without

+ * modification, are permitted provided that the following conditions

+ * are met:

+ *

+ *  * Redistributions of source code must retain the above copyright

+ *    notice, this list of conditions and the following disclaimer.

+ *  * Redistributions in binary form must reproduce the above copyright

+ *    notice, this list of conditions and the following disclaimer in

+ *    the documentation and/or other materials provided with the

+ *    distribution.

+ *  * Neither the name Trusted Logic nor the names of its

+ *    contributors may be used to endorse or promote products derived

+ *    from this software without specific prior written permission.

+ *

+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS

+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT

+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR

+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT

+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,

+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT

+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,

+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY

+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT

+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE

+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

+ */

+

+#ifndef ___MTC_H_INC___

+#define ___MTC_H_INC___

+

+#ifdef __cplusplus

+extern "C" {

+#endif

+

+/*------------------------------------------------------------------------------

+   includes

+------------------------------------------------------------------------------*/

+#include "s_type.h"

+#include "s_error.h"

+

+/* Define MTC_EXPORTS during the build of mtc libraries. Do

+ * not define it in applications.

+ */

+

+#ifdef MTC_EXPORTS

+#define MTC_EXPORT S_DLL_EXPORT

+#else

+#define MTC_EXPORT S_DLL_IMPORT

+#endif

+

+/*------------------------------------------------------------------------------

+   typedefs

+------------------------------------------------------------------------------*/

+

+typedef struct

+{

+   uint32_t nLow;

+   uint32_t nHigh;

+}

+S_MONOTONIC_COUNTER_VALUE;

+

+/*------------------------------------------------------------------------------

+   defines

+------------------------------------------------------------------------------*/

+

+#define S_MONOTONIC_COUNTER_GLOBAL        0x00000000

+

+/*------------------------------------------------------------------------------

+   API

+------------------------------------------------------------------------------*/

+

+S_RESULT MTC_EXPORT SMonotonicCounterInit(void);

+

+void MTC_EXPORT SMonotonicCounterTerminate(void);

+

+S_RESULT MTC_EXPORT SMonotonicCounterOpen(

+                 uint32_t nCounterIdentifier,

+                 S_HANDLE* phCounter);

+

+void MTC_EXPORT SMonotonicCounterClose(S_HANDLE hCounter);

+

+S_RESULT MTC_EXPORT SMonotonicCounterGet(

+                 S_HANDLE hCounter,

+                 S_MONOTONIC_COUNTER_VALUE* psCurrentValue);

+

+S_RESULT MTC_EXPORT SMonotonicCounterIncrement(

+                 S_HANDLE hCounter,

+                 S_MONOTONIC_COUNTER_VALUE* psNewValue);

+

+#ifdef __cplusplus

+}

+#endif

+

+#endif /*___MTC_H_INC___*/

diff --git a/security/tf_sdk/include/pkcs11.h b/security/tf_sdk/include/pkcs11.h
new file mode 100644
index 0000000..8f28917
--- /dev/null
+++ b/security/tf_sdk/include/pkcs11.h
@@ -0,0 +1,595 @@
+/**

+ * Copyright(c) 2011 Trusted Logic.   All rights reserved.

+ *

+ * Redistribution and use in source and binary forms, with or without

+ * modification, are permitted provided that the following conditions

+ * are met:

+ *

+ *  * Redistributions of source code must retain the above copyright

+ *    notice, this list of conditions and the following disclaimer.

+ *  * Redistributions in binary form must reproduce the above copyright

+ *    notice, this list of conditions and the following disclaimer in

+ *    the documentation and/or other materials provided with the

+ *    distribution.

+ *  * Neither the name Trusted Logic nor the names of its

+ *    contributors may be used to endorse or promote products derived

+ *    from this software without specific prior written permission.

+ *

+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS

+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT

+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR

+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT

+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,

+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT

+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,

+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY

+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT

+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE

+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

+ */
+
+/*
+ * This header file contains the definition of the PKCS#11 types and functions
+ * supported by the Trusted Foundations Software. This header file is
+ * derived from the RSA Security Inc. PKCS #11 Cryptographic Token Interface
+ * (Cryptoki)
+ */
+#ifndef __PKCS11_H__
+#define __PKCS11_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*------------------------------------------
+* Types and constants
+*------------------------------------------*/
+
+#include "s_type.h"
+
+#define CK_TRUE true
+#define CK_FALSE false
+
+#ifndef FALSE
+#define FALSE CK_FALSE
+#endif
+
+#ifndef TRUE
+#define TRUE CK_TRUE
+#endif
+
+#define NULL_PTR NULL
+
+typedef uint8_t      CK_BYTE, *CK_BYTE_PTR;
+typedef CK_BYTE      CK_CHAR, *CK_CHAR_PTR;
+typedef CK_BYTE      CK_UTF8CHAR, *CK_UTF8CHAR_PTR;
+typedef bool         CK_BBOOL;
+typedef uint32_t     CK_ULONG, *CK_ULONG_PTR;
+typedef int32_t      CK_LONG;
+typedef CK_ULONG     CK_FLAGS;
+typedef void*        CK_VOID_PTR, *CK_VOID_PTR_PTR;
+
+#define CK_INVALID_HANDLE 0
+
+typedef struct CK_VERSION
+{
+   CK_BYTE       major;
+   CK_BYTE       minor;
+}
+CK_VERSION, *CK_VERSION_PTR;
+
+typedef struct CK_INFO
+{
+   CK_VERSION    cryptokiVersion;
+   CK_UTF8CHAR   manufacturerID[32];
+   CK_FLAGS      flags;
+   CK_UTF8CHAR   libraryDescription[32];
+   CK_VERSION    libraryVersion;
+}
+CK_INFO, *CK_INFO_PTR;
+
+typedef CK_ULONG   CK_NOTIFICATION;
+typedef CK_ULONG   CK_SLOT_ID, *CK_SLOT_ID_PTR;
+typedef CK_ULONG   CK_SESSION_HANDLE, *CK_SESSION_HANDLE_PTR;
+
+typedef CK_ULONG          CK_USER_TYPE;
+#define CKU_SO                 0
+#define CKU_USER               1
+#define CKU_CONTEXT_SPECIFIC   2
+
+typedef CK_ULONG          CK_STATE;
+#define CKS_RO_PUBLIC_SESSION  0
+#define CKS_RO_USER_FUNCTIONS  1
+#define CKS_RW_PUBLIC_SESSION  2
+#define CKS_RW_USER_FUNCTIONS  3
+#define CKS_RW_SO_FUNCTIONS    4
+
+typedef struct CK_SESSION_INFO
+{
+   CK_SLOT_ID    slotID;
+   CK_STATE      state;
+   CK_FLAGS      flags;
+   CK_ULONG      ulDeviceError;
+}
+CK_SESSION_INFO, *CK_SESSION_INFO_PTR;
+
+#define CKF_RW_SESSION          0x00000002
+#define CKF_SERIAL_SESSION      0x00000004
+#define CKVF_OPEN_SUB_SESSION   0x00000008
+
+typedef CK_ULONG          CK_OBJECT_HANDLE, *CK_OBJECT_HANDLE_PTR;
+
+typedef CK_ULONG          CK_OBJECT_CLASS, *CK_OBJECT_CLASS_PTR;
+
+#define CKO_DATA              0x00000000
+#define CKO_PUBLIC_KEY        0x00000002
+#define CKO_PRIVATE_KEY       0x00000003
+#define CKO_SECRET_KEY        0x00000004
+
+typedef CK_ULONG          CK_KEY_TYPE;
+
+#define CKK_RSA             0x00000000
+#define CKK_DSA             0x00000001
+#define CKK_DH              0x00000002
+#define CKK_EC              0x00000003
+
+#define CKK_GENERIC_SECRET  0x00000010
+
+#define CKK_RC4             0x00000012
+#define CKK_DES             0x00000013
+#define CKK_DES2            0x00000014
+#define CKK_DES3            0x00000015
+
+#define CKK_AES             0x0000001F
+
+#define CKK_VENDOR_DEFINED  0x80000000
+
+typedef CK_ULONG          CK_ATTRIBUTE_TYPE;
+
+#define CKF_ARRAY_ATTRIBUTE    0x40000000
+
+#define CKA_CLASS              0x00000000
+#define CKA_TOKEN              0x00000001
+#define CKA_PRIVATE            0x00000002
+#define CKA_VALUE              0x00000011
+
+#define CKA_OBJECT_ID          0x00000012
+
+#define CKA_KEY_TYPE           0x00000100
+#define CKA_ID                 0x00000102
+#define CKA_SENSITIVE          0x00000103
+#define CKA_ENCRYPT            0x00000104
+#define CKA_DECRYPT            0x00000105
+#define CKA_WRAP               0x00000106
+#define CKA_UNWRAP             0x00000107
+#define CKA_SIGN               0x00000108
+#define CKA_VERIFY             0x0000010A
+#define CKA_DERIVE             0x0000010C
+#define CKA_MODULUS            0x00000120
+#define CKA_MODULUS_BITS       0x00000121
+#define CKA_PUBLIC_EXPONENT    0x00000122
+#define CKA_PRIVATE_EXPONENT   0x00000123
+#define CKA_PRIME_1            0x00000124
+#define CKA_PRIME_2            0x00000125
+#define CKA_EXPONENT_1         0x00000126
+#define CKA_EXPONENT_2         0x00000127
+#define CKA_COEFFICIENT        0x00000128
+#define CKA_PRIME              0x00000130
+#define CKA_SUBPRIME           0x00000131
+#define CKA_BASE               0x00000132
+
+#define CKA_VALUE_BITS         0x00000160
+#define CKA_VALUE_LEN          0x00000161
+
+#define CKA_EXTRACTABLE        0x00000162
+
+#define CKA_MODIFIABLE         0x00000170
+#define CKA_COPYABLE           0x00000171
+#define CKA_ALWAYS_AUTHENTICATE  0x00000202
+
+#define CKA_VENDOR_DEFINED     0x80000000
+
+#define CKAV_ALLOW_NON_SENSITIVE_DERIVED_KEY 0x80000001
+
+typedef struct CK_ATTRIBUTE
+{
+   CK_ATTRIBUTE_TYPE type;
+   void*             pValue;
+   CK_ULONG          ulValueLen;
+}
+CK_ATTRIBUTE, *CK_ATTRIBUTE_PTR;
+
+typedef CK_ULONG          CK_MECHANISM_TYPE, *CK_MECHANISM_TYPE_PTR;
+
+#define CKM_RSA_PKCS_KEY_PAIR_GEN      0x00000000
+#define CKM_RSA_PKCS                   0x00000001
+#define CKM_RSA_X_509                  0x00000003
+#define CKM_MD5_RSA_PKCS               0x00000005
+#define CKM_SHA1_RSA_PKCS              0x00000006
+#define CKM_RSA_PKCS_OAEP              0x00000009
+#define CKM_RSA_PKCS_PSS               0x0000000D
+#define CKM_SHA1_RSA_PKCS_PSS          0x0000000E
+#define CKM_DSA_KEY_PAIR_GEN           0x00000010
+#define CKM_DSA                        0x00000011
+#define CKM_DSA_SHA1                   0x00000012
+#define CKM_DH_PKCS_KEY_PAIR_GEN       0x00000020
+#define CKM_DH_PKCS_DERIVE             0x00000021
+#define CKM_SHA256_RSA_PKCS            0x00000040
+#define CKM_SHA384_RSA_PKCS            0x00000041
+#define CKM_SHA512_RSA_PKCS            0x00000042
+#define CKM_SHA256_RSA_PKCS_PSS        0x00000043
+#define CKM_SHA384_RSA_PKCS_PSS        0x00000044
+#define CKM_SHA512_RSA_PKCS_PSS        0x00000045
+#define CKM_SHA224_RSA_PKCS            0x00000046
+#define CKM_SHA224_RSA_PKCS_PSS        0x00000047
+#define CKM_RC4_KEY_GEN                0x00000110
+#define CKM_RC4                        0x00000111
+#define CKM_DES_KEY_GEN                0x00000120
+#define CKM_DES_ECB                    0x00000121
+#define CKM_DES_CBC                    0x00000122
+#define CKM_DES_MAC                    0x00000123
+#define CKM_DES2_KEY_GEN               0x00000130
+#define CKM_DES3_KEY_GEN               0x00000131
+#define CKM_DES3_ECB                   0x00000132
+#define CKM_DES3_CBC                   0x00000133
+#define CKM_DES3_MAC                   0x00000134
+#define CKM_MD5                        0x00000210
+#define CKM_MD5_HMAC                   0x00000211
+#define CKM_SHA_1                      0x00000220
+#define CKM_SHA_1_HMAC                 0x00000221
+#define CKM_SHA256                     0x00000250
+#define CKM_SHA256_HMAC                0x00000251
+#define CKM_SHA224                     0x00000255
+#define CKM_SHA224_HMAC                0x00000256
+#define CKM_SHA384                     0x00000260
+#define CKM_SHA384_HMAC                0x00000261
+#define CKM_SHA512                     0x00000270
+#define CKM_SHA512_HMAC                0x00000271
+#define CKM_GENERIC_SECRET_KEY_GEN     0x00000350
+#define CKM_AES_KEY_GEN                0x00001080
+#define CKM_AES_ECB                    0x00001081
+#define CKM_AES_CBC                    0x00001082
+#define CKM_AES_MAC                    0x00001083
+#define CKM_AES_CTR                    0x00001086
+#define CKM_VENDOR_DEFINED             0x80000000
+#define CKMV_AES_CTR                   0x80000001
+
+#define CKMV_IMPLEMENTATION_DEFINED_0   0xC0000000
+#define CKMV_IMPLEMENTATION_DEFINED_1   0xC0000001
+#define CKMV_IMPLEMENTATION_DEFINED_2   0xC0000002
+#define CKMV_IMPLEMENTATION_DEFINED_3   0xC0000003
+#define CKMV_IMPLEMENTATION_DEFINED_4   0xC0000004
+#define CKMV_IMPLEMENTATION_DEFINED_5   0xC0000005
+#define CKMV_IMPLEMENTATION_DEFINED_6   0xC0000006
+#define CKMV_IMPLEMENTATION_DEFINED_7   0xC0000007
+#define CKMV_IMPLEMENTATION_DEFINED_8   0xC0000008
+#define CKMV_IMPLEMENTATION_DEFINED_9   0xC0000009
+#define CKMV_IMPLEMENTATION_DEFINED_10  0xC000000A
+#define CKMV_IMPLEMENTATION_DEFINED_11  0xC000000B
+#define CKMV_IMPLEMENTATION_DEFINED_12  0xC000000C
+#define CKMV_IMPLEMENTATION_DEFINED_13  0xC000000D
+#define CKMV_IMPLEMENTATION_DEFINED_14  0xC000000E
+#define CKMV_IMPLEMENTATION_DEFINED_15  0xC000000F
+
+typedef struct CK_MECHANISM
+{
+   CK_MECHANISM_TYPE mechanism;
+   void*             pParameter;
+   CK_ULONG          ulParameterLen;  /* in bytes */
+}
+CK_MECHANISM, *CK_MECHANISM_PTR;
+
+typedef CK_ULONG          CK_RV;
+
+#define CKR_OK                                0x00000000
+#define CKR_CANCEL                            0x00000001
+#define CKR_HOST_MEMORY                       0x00000002
+#define CKR_SLOT_ID_INVALID                   0x00000003
+#define CKR_GENERAL_ERROR                     0x00000005
+#define CKR_ARGUMENTS_BAD                     0x00000007
+#define CKR_ATTRIBUTE_SENSITIVE               0x00000011
+#define CKR_ATTRIBUTE_TYPE_INVALID            0x00000012
+#define CKR_ATTRIBUTE_VALUE_INVALID           0x00000013
+#define CKR_COPY_PROHIBITED                   0x0000001A
+#define CKR_DATA_INVALID                      0x00000020
+#define CKR_DATA_LEN_RANGE                    0x00000021
+#define CKR_DEVICE_ERROR                      0x00000030
+#define CKR_DEVICE_MEMORY                     0x00000031
+#define CKR_ENCRYPTED_DATA_INVALID            0x00000040
+#define CKR_ENCRYPTED_DATA_LEN_RANGE          0x00000041
+#define CKR_KEY_HANDLE_INVALID                0x00000060
+#define CKR_KEY_SIZE_RANGE                    0x00000062
+#define CKR_KEY_TYPE_INCONSISTENT             0x00000063
+#define CKR_KEY_FUNCTION_NOT_PERMITTED        0x00000068
+#define CKR_KEY_NOT_WRAPPABLE                 0x00000069
+#define CKR_MECHANISM_INVALID                 0x00000070
+#define CKR_MECHANISM_PARAM_INVALID           0x00000071
+#define CKR_OBJECT_HANDLE_INVALID             0x00000082
+#define CKR_OPERATION_ACTIVE                  0x00000090
+#define CKR_OPERATION_NOT_INITIALIZED         0x00000091
+#define CKR_PIN_INCORRECT                     0x000000A0
+#define CKR_SESSION_COUNT                     0x000000B1
+#define CKR_SESSION_HANDLE_INVALID            0x000000B3
+#define CKR_SESSION_PARALLEL_NOT_SUPPORTED    0x000000B4
+#define CKR_SESSION_READ_ONLY                 0x000000B5
+#define CKR_SIGNATURE_INVALID                 0x000000C0
+#define CKR_SIGNATURE_LEN_RANGE               0x000000C1
+#define CKR_TEMPLATE_INCOMPLETE               0x000000D0
+#define CKR_TEMPLATE_INCONSISTENT             0x000000D1
+#define CKR_TOKEN_NOT_PRESENT                 0x000000E0
+#define CKR_USER_ALREADY_LOGGED_IN            0x00000100
+#define CKR_USER_NOT_LOGGED_IN                0x00000101
+#define CKR_USER_TYPE_INVALID                 0x00000103
+#define CKR_WRAPPED_KEY_LEN_RANGE             0x00000112
+#define CKR_WRAPPING_KEY_HANDLE_INVALID       0x00000113
+#define CKR_RANDOM_SEED_NOT_SUPPORTED         0x00000120
+#define CKR_RANDOM_NO_RNG                     0x00000121
+#define CKR_BUFFER_TOO_SMALL                  0x00000150
+#define CKR_CRYPTOKI_NOT_INITIALIZED          0x00000190
+#define CKR_CRYPTOKI_ALREADY_INITIALIZED      0x00000191
+#define CKR_VENDOR_DEFINED                    0x80000000
+
+typedef CK_RV (*CK_NOTIFY)(
+   CK_SESSION_HANDLE hSession,
+   CK_NOTIFICATION   event,
+   void*       pApplication
+);
+
+typedef CK_ULONG CK_RSA_PKCS_MGF_TYPE, *CK_RSA_PKCS_MGF_TYPE_PTR;
+
+#define CKG_MGF1_SHA1         0x00000001
+#define CKG_MGF1_SHA256       0x00000002
+#define CKG_MGF1_SHA384       0x00000003
+#define CKG_MGF1_SHA512       0x00000004
+#define CKG_MGF1_SHA224       0x00000005
+
+typedef CK_ULONG CK_RSA_PKCS_OAEP_SOURCE_TYPE, *CK_RSA_PKCS_OAEP_SOURCE_TYPE_PTR;
+
+#define CKZ_DATA_SPECIFIED    0x00000001
+typedef struct CK_RSA_PKCS_OAEP_PARAMS
+{
+   CK_MECHANISM_TYPE hashAlg;
+   CK_RSA_PKCS_MGF_TYPE mgf;
+   CK_RSA_PKCS_OAEP_SOURCE_TYPE source;
+   void*    pSourceData;
+   CK_ULONG ulSourceDataLen;
+}
+CK_RSA_PKCS_OAEP_PARAMS, *CK_RSA_PKCS_OAEP_PARAMS_PTR;
+
+typedef struct CK_RSA_PKCS_PSS_PARAMS
+{
+   CK_MECHANISM_TYPE    hashAlg;
+   CK_RSA_PKCS_MGF_TYPE mgf;
+   CK_ULONG             sLen;
+}
+CK_RSA_PKCS_PSS_PARAMS, *CK_RSA_PKCS_PSS_PARAMS_PTR;
+
+typedef struct CK_AES_CTR_PARAMS
+{
+   CK_ULONG ulCounterBits;
+   CK_BYTE cb[16];
+}
+CK_AES_CTR_PARAMS, *CK_AES_CTR_PARAMS_PTR;
+
+/*------------------------------------------
+* Functions
+*------------------------------------------*/
+CK_RV PKCS11_EXPORT C_Initialize(void* pInitArgs);
+
+CK_RV PKCS11_EXPORT C_Finalize(void* pReserved);
+
+CK_RV PKCS11_EXPORT C_GetInfo(CK_INFO* pInfo);
+
+CK_RV PKCS11_EXPORT C_OpenSession(
+   CK_SLOT_ID            slotID,
+   CK_FLAGS              flags,
+   void*                 pApplication,
+   CK_NOTIFY             Notify,
+   CK_SESSION_HANDLE*    phSession);
+
+CK_RV PKCS11_EXPORT C_CloseSession(
+   CK_SESSION_HANDLE hSession);
+
+CK_RV PKCS11_EXPORT C_Login(
+   CK_SESSION_HANDLE   hSession,
+   CK_USER_TYPE        userType,
+   const CK_UTF8CHAR*  pPin,
+   CK_ULONG            ulPinLen);
+
+CK_RV PKCS11_EXPORT C_Logout(
+   CK_SESSION_HANDLE hSession);
+
+CK_RV PKCS11_EXPORT C_CreateObject(
+   CK_SESSION_HANDLE   hSession,
+   const CK_ATTRIBUTE* pTemplate,
+   CK_ULONG            ulCount,
+   CK_OBJECT_HANDLE*   phObject);
+
+CK_RV PKCS11_EXPORT C_DestroyObject(
+   CK_SESSION_HANDLE   hSession,
+   CK_OBJECT_HANDLE    hObject);
+
+CK_RV PKCS11_EXPORT C_GetAttributeValue(
+   CK_SESSION_HANDLE   hSession,
+   CK_OBJECT_HANDLE    hObject,
+   CK_ATTRIBUTE*       pTemplate,
+   CK_ULONG            ulCount);
+
+CK_RV PKCS11_EXPORT C_FindObjectsInit(
+   CK_SESSION_HANDLE   hSession,
+   const CK_ATTRIBUTE* pTemplate,
+   CK_ULONG            ulCount);
+
+CK_RV PKCS11_EXPORT C_FindObjects(
+   CK_SESSION_HANDLE   hSession,
+   CK_OBJECT_HANDLE*   phObject,
+   CK_ULONG            ulMaxObjectCount,
+   CK_ULONG*           pulObjectCount);
+
+CK_RV PKCS11_EXPORT C_FindObjectsFinal(
+   CK_SESSION_HANDLE hSession);
+
+CK_RV PKCS11_EXPORT C_EncryptInit(
+   CK_SESSION_HANDLE   hSession,
+   const CK_MECHANISM* pMechanism,
+   CK_OBJECT_HANDLE    hKey);
+
+CK_RV PKCS11_EXPORT C_Encrypt(
+   CK_SESSION_HANDLE hSession,
+   const CK_BYTE*    pData,
+   CK_ULONG          ulDataLen,
+   CK_BYTE*          pEncryptedData,
+   CK_ULONG*         pulEncryptedDataLen);
+
+CK_RV PKCS11_EXPORT C_EncryptUpdate(
+   CK_SESSION_HANDLE hSession,
+   const CK_BYTE*    pPart,
+   CK_ULONG          ulPartLen,
+   CK_BYTE*          pEncryptedPart,
+   CK_ULONG*         pulEncryptedPartLen);
+
+CK_RV PKCS11_EXPORT C_EncryptFinal(
+   CK_SESSION_HANDLE hSession,
+   CK_BYTE*          pLastEncryptedPart,
+   CK_ULONG*         pulLastEncryptedPartLen);
+
+CK_RV PKCS11_EXPORT C_DecryptInit(
+   CK_SESSION_HANDLE   hSession,
+   const CK_MECHANISM* pMechanism,
+   CK_OBJECT_HANDLE    hKey);
+
+CK_RV PKCS11_EXPORT C_Decrypt(
+   CK_SESSION_HANDLE hSession,
+   const CK_BYTE*    pEncryptedData,
+   CK_ULONG          ulEncryptedDataLen,
+   CK_BYTE*          pData,
+   CK_ULONG*         pulDataLen);
+
+CK_RV PKCS11_EXPORT C_DecryptUpdate(
+   CK_SESSION_HANDLE hSession,
+   const CK_BYTE*    pEncryptedPart,
+   CK_ULONG          ulEncryptedPartLen,
+   CK_BYTE*          pPart,
+   CK_ULONG*         pulPartLen);
+
+CK_RV PKCS11_EXPORT C_DecryptFinal(
+   CK_SESSION_HANDLE hSession,
+   CK_BYTE*          pLastPart,
+   CK_ULONG*         pulLastPartLen);
+
+CK_RV PKCS11_EXPORT C_DigestInit(
+   CK_SESSION_HANDLE   hSession,
+   const CK_MECHANISM* pMechanism);
+
+CK_RV PKCS11_EXPORT C_Digest(
+   CK_SESSION_HANDLE hSession,
+   const CK_BYTE*    pData,
+   CK_ULONG          ulDataLen,
+   CK_BYTE*          pDigest,
+   CK_ULONG*         pulDigestLen);
+
+CK_RV PKCS11_EXPORT C_DigestUpdate(
+   CK_SESSION_HANDLE hSession,
+   const CK_BYTE*    pPart,
+   CK_ULONG          ulPartLen);
+
+CK_RV PKCS11_EXPORT C_DigestFinal(
+   CK_SESSION_HANDLE hSession,
+   CK_BYTE*          pDigest,
+   CK_ULONG*         pulDigestLen);
+
+CK_RV PKCS11_EXPORT C_SignInit(
+   CK_SESSION_HANDLE   hSession,
+   const CK_MECHANISM* pMechanism,
+   CK_OBJECT_HANDLE    hKey);
+
+CK_RV PKCS11_EXPORT C_Sign(
+   CK_SESSION_HANDLE  hSession,
+   const CK_BYTE*     pData,
+   CK_ULONG           ulDataLen,
+   CK_BYTE*           pSignature,
+   CK_ULONG*          pulSignatureLen);
+
+CK_RV PKCS11_EXPORT C_SignUpdate(
+   CK_SESSION_HANDLE hSession,
+   const CK_BYTE*    pPart,
+   CK_ULONG          ulPartLen);
+
+CK_RV PKCS11_EXPORT C_SignFinal(
+   CK_SESSION_HANDLE hSession,
+   CK_BYTE*          pSignature,
+   CK_ULONG*         pulSignatureLen);
+
+CK_RV PKCS11_EXPORT C_VerifyInit(
+   CK_SESSION_HANDLE   hSession,
+   const CK_MECHANISM* pMechanism,
+   CK_OBJECT_HANDLE    hKey);
+
+CK_RV PKCS11_EXPORT C_Verify(
+   CK_SESSION_HANDLE hSession,
+   const CK_BYTE*    pData,
+   CK_ULONG          ulDataLen,
+   CK_BYTE*          pSignature,
+   CK_ULONG          ulSignatureLen);
+
+CK_RV PKCS11_EXPORT C_VerifyUpdate(
+   CK_SESSION_HANDLE hSession,
+   const CK_BYTE*    pPart,
+   CK_ULONG          ulPartLen);
+
+CK_RV PKCS11_EXPORT C_VerifyFinal(
+   CK_SESSION_HANDLE hSession,
+   const CK_BYTE*          pSignature,
+   CK_ULONG          ulSignatureLen);
+
+CK_RV PKCS11_EXPORT C_GenerateKey(
+   CK_SESSION_HANDLE   hSession,
+   const CK_MECHANISM* pMechanism,
+   const CK_ATTRIBUTE* pTemplate,
+   CK_ULONG            ulCount,
+   CK_OBJECT_HANDLE*   phKey);
+
+CK_RV PKCS11_EXPORT C_GenerateKeyPair(
+   CK_SESSION_HANDLE    hSession,
+   const CK_MECHANISM*  pMechanism,
+   const CK_ATTRIBUTE*  pPublicKeyTemplate,
+   CK_ULONG             ulPublicKeyAttributeCount,
+   const CK_ATTRIBUTE*  pPrivateKeyTemplate,
+   CK_ULONG             ulPrivateKeyAttributeCount,
+   CK_OBJECT_HANDLE*    phPublicKey,
+   CK_OBJECT_HANDLE*    phPrivateKey);
+
+CK_RV PKCS11_EXPORT C_DeriveKey(
+   CK_SESSION_HANDLE    hSession,
+   const CK_MECHANISM*  pMechanism,
+   CK_OBJECT_HANDLE     hBaseKey,
+   const CK_ATTRIBUTE*  pTemplate,
+   CK_ULONG             ulAttributeCount,
+   CK_OBJECT_HANDLE*    phKey);
+
+CK_RV PKCS11_EXPORT C_SeedRandom(
+   CK_SESSION_HANDLE hSession,
+   const CK_BYTE*    pSeed,
+   CK_ULONG          ulSeedLen);
+
+CK_RV PKCS11_EXPORT C_GenerateRandom(
+   CK_SESSION_HANDLE hSession,
+   CK_BYTE*          pRandomData,
+   CK_ULONG          ulRandomLen);
+
+CK_RV PKCS11_EXPORT C_CloseObjectHandle(
+   CK_SESSION_HANDLE hSession,
+   CK_OBJECT_HANDLE    hObject);
+
+CK_RV PKCS11_EXPORT C_CopyObject(
+   CK_SESSION_HANDLE    hSession,
+   CK_OBJECT_HANDLE     hObject,
+   const CK_ATTRIBUTE*  pTemplate,
+   CK_ULONG             ulAttributeCount,
+   CK_OBJECT_HANDLE*    phNewObject);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __PKCS11_H__ */
diff --git a/security/tf_sdk/include/s_error.h b/security/tf_sdk/include/s_error.h
new file mode 100644
index 0000000..d77d3dd
--- /dev/null
+++ b/security/tf_sdk/include/s_error.h
@@ -0,0 +1,321 @@
+/**

+ * Copyright(c) 2011 Trusted Logic.   All rights reserved.

+ *

+ * Redistribution and use in source and binary forms, with or without

+ * modification, are permitted provided that the following conditions

+ * are met:

+ *

+ *  * Redistributions of source code must retain the above copyright

+ *    notice, this list of conditions and the following disclaimer.

+ *  * Redistributions in binary form must reproduce the above copyright

+ *    notice, this list of conditions and the following disclaimer in

+ *    the documentation and/or other materials provided with the

+ *    distribution.

+ *  * Neither the name Trusted Logic nor the names of its

+ *    contributors may be used to endorse or promote products derived

+ *    from this software without specific prior written permission.

+ *

+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS

+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT

+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR

+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT

+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,

+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT

+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,

+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY

+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT

+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE

+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

+ */
+#ifndef __S_ERROR_H__
+#define __S_ERROR_H__
+
+#define S_SUCCESS                      ((S_RESULT)0x00000000)
+#define SM_SUCCESS                     S_SUCCESS
+#define TEEC_SUCCESS                   S_SUCCESS
+#define SST_SUCCESS                    S_SUCCESS
+
+/**
+ * Generic error code : Generic error
+ **/
+#define S_ERROR_GENERIC                ((S_RESULT)0xFFFF0000)
+#define SM_ERROR_GENERIC               S_ERROR_GENERIC
+#define TEEC_ERROR_GENERIC             S_ERROR_GENERIC
+#define SST_ERROR_GENERIC              S_ERROR_GENERIC
+
+/**
+ * Generic error code : The underlying security system denies the access to the
+ * object
+ **/
+#define S_ERROR_ACCESS_DENIED          ((S_RESULT)0xFFFF0001)
+#define SM_ERROR_ACCESS_DENIED         S_ERROR_ACCESS_DENIED
+#define TEEC_ERROR_ACCESS_DENIED       S_ERROR_ACCESS_DENIED
+#define SST_ERROR_ACCESS_DENIED        S_ERROR_ACCESS_DENIED
+
+/**
+ * Generic error code : The pending operation is cancelled.
+ **/
+#define S_ERROR_CANCEL                 ((S_RESULT)0xFFFF0002)
+#define SM_ERROR_CANCEL                S_ERROR_CANCEL
+#define TEEC_ERROR_CANCEL              S_ERROR_CANCEL
+
+/**
+ * Generic error code : The underlying system detects a conflict
+ **/
+#define S_ERROR_ACCESS_CONFLICT        ((S_RESULT)0xFFFF0003)
+#define SM_ERROR_EXCLUSIVE_ACCESS      S_ERROR_ACCESS_CONFLICT
+#define TEEC_ERROR_ACCESS_CONFLICT     S_ERROR_ACCESS_CONFLICT
+#define SST_ERROR_ACCESS_CONFLICT      S_ERROR_ACCESS_CONFLICT
+
+/**
+ * Generic error code : Too much data for the operation or some data remain
+ * unprocessed by the operation.
+ **/
+#define S_ERROR_EXCESS_DATA            ((S_RESULT)0xFFFF0004)
+#define SM_ERROR_EXCESS_DATA           S_ERROR_EXCESS_DATA
+#define TEEC_ERROR_EXCESS_DATA         S_ERROR_EXCESS_DATA
+
+
+/**
+ * Generic error code : Error of data format
+ **/
+#define S_ERROR_BAD_FORMAT             ((S_RESULT)0xFFFF0005)
+#define SM_ERROR_FORMAT                S_ERROR_BAD_FORMAT
+#define TEEC_ERROR_BAD_FORMAT          S_ERROR_BAD_FORMAT
+
+/**
+ * Generic error code : The specified parameters are invalid
+ **/
+#define S_ERROR_BAD_PARAMETERS         ((S_RESULT)0xFFFF0006)
+#define SM_ERROR_ILLEGAL_ARGUMENT      S_ERROR_BAD_PARAMETERS
+#define TEEC_ERROR_BAD_PARAMETERS      S_ERROR_BAD_PARAMETERS
+#define SST_ERROR_BAD_PARAMETERS       S_ERROR_BAD_PARAMETERS
+
+
+/**
+ * Generic error code : Illegal state for the operation.
+ **/
+#define S_ERROR_BAD_STATE              ((S_RESULT)0xFFFF0007)
+#define SM_ERROR_ILLEGAL_STATE         S_ERROR_BAD_STATE
+#define TEEC_ERROR_BAD_STATE           S_ERROR_BAD_STATE
+
+/**
+ * Generic error code : The item is not found
+ **/
+#define S_ERROR_ITEM_NOT_FOUND         ((S_RESULT)0xFFFF0008)
+#define SM_ERROR_ITEM_NOT_FOUND        S_ERROR_ITEM_NOT_FOUND
+#define TEEC_ERROR_ITEM_NOT_FOUND      S_ERROR_ITEM_NOT_FOUND
+#define SST_ERROR_ITEM_NOT_FOUND       S_ERROR_ITEM_NOT_FOUND
+
+/**
+ * Generic error code : The specified operation is not implemented
+ **/
+#define S_ERROR_NOT_IMPLEMENTED        ((S_RESULT)0xFFFF0009)
+#define SM_ERROR_NOT_IMPLEMENTED       S_ERROR_NOT_IMPLEMENTED
+#define TEEC_ERROR_NOT_IMPLEMENTED     S_ERROR_NOT_IMPLEMENTED
+
+/**
+ * Generic error code : The specified operation is not supported
+ **/
+#define S_ERROR_NOT_SUPPORTED          ((S_RESULT)0xFFFF000A)
+#define SM_ERROR_NOT_SUPPORTED         S_ERROR_NOT_SUPPORTED
+#define TEEC_ERROR_NOT_SUPPORTED       S_ERROR_NOT_SUPPORTED
+
+/**
+ * Generic error code : Insufficient data is available for the operation.
+ **/
+#define S_ERROR_NO_DATA                ((S_RESULT)0xFFFF000B)
+#define SM_ERROR_NO_DATA               S_ERROR_NO_DATA
+#define TEEC_ERROR_NO_DATA             S_ERROR_NO_DATA
+
+/**
+ * Generic error code : Not enough memory to perform the operation
+ **/
+#define S_ERROR_OUT_OF_MEMORY          ((S_RESULT)0xFFFF000C)
+#define SM_ERROR_OUT_OF_MEMORY         S_ERROR_OUT_OF_MEMORY
+#define TEEC_ERROR_OUT_OF_MEMORY       S_ERROR_OUT_OF_MEMORY
+#define SST_ERROR_OUT_OF_MEMORY        S_ERROR_OUT_OF_MEMORY
+
+/**
+ * Generic error code : The service is currently unable to handle the request;
+ * try later
+ **/
+#define S_ERROR_BUSY                   ((S_RESULT)0xFFFF000D)
+#define SM_ERROR_BUSY                  S_ERROR_BUSY
+#define TEEC_ERROR_BUSY                S_ERROR_BUSY
+
+/**
+ * Generic error code : security violation
+ **/
+#define S_ERROR_SECURITY               ((S_RESULT)0xFFFF000F)
+#define SM_ERROR_SECURITY              S_ERROR_SECURITY
+#define TEEC_ERROR_SECURITY            S_ERROR_SECURITY
+
+/**
+ * Generic error code : the buffer is too short
+ **/
+#define S_ERROR_SHORT_BUFFER           ((S_RESULT)0xFFFF0010)
+#define SM_ERROR_SHORT_BUFFER          S_ERROR_SHORT_BUFFER
+#define TEEC_ERROR_SHORT_BUFFER        S_ERROR_SHORT_BUFFER
+
+
+/**
+ * Generic error code : SControl Asynchronous Operations are not supported.
+ */
+#define S_ERROR_ASYNC_OPERATIONS_NOT_SUPPORTED ((S_RESULT)0xFFFF0011)
+#define SM_ERROR_ASYNC_OPERATIONS_NOT_SUPPORTED  S_ERROR_ASYNC_OPERATIONS_NOT_SUPPORTED
+
+/**
+ * Generic error code : the number of handles currently created
+ * for a specific resource has reached the maximum amount.
+ **/
+#define S_ERROR_NO_MORE_HANDLES           ((S_RESULT)0xFFFF0013)
+
+/**
+ * Generic error code : the monotonic counter is corrupted
+ **/
+#define S_ERROR_CORRUPTED           ((S_RESULT)0xFFFF0014)
+
+/**
+ * Generic error code : the operation is not terminated
+ **/
+#define S_PENDING                      ((S_RESULT)0xFFFF2000)
+
+/**
+ * Generic error code : A timeout occurred
+ **/
+#define S_ERROR_TIMEOUT                ((S_RESULT)0xFFFF3001)
+
+/**
+ * Error code: Error of the underlying OS.
+ **/
+#define S_ERROR_UNDERLYING_OS          ((S_RESULT)0xFFFF3002)
+#define TEEC_ERROR_OS                  S_ERROR_UNDERLYING_OS
+
+
+/**
+ * Error code: The operation is cancelled by a signal.
+ **/
+#define S_ERROR_CANCELLED_BY_SIGNAL    ((S_RESULT)0xFFFF3003)
+
+/**
+ * Generic error code : Overflow
+ **/
+#define S_ERROR_OVERFLOW               ((S_RESULT)0xFFFF300F)
+#define SST_ERROR_OVERFLOW             S_ERROR_OVERFLOW
+
+/**
+ * Generic error code : The item already exists
+ **/
+#define S_ERROR_ITEM_EXISTS            ((S_RESULT)0xFFFF3012)
+
+/**
+ * Generic error code : The application reported an error.  The code of the
+ * applicative error is encoded in the message data.
+ */
+#define S_ERROR_SERVICE                ((S_RESULT)0xFFFF1000)
+#define SM_ERROR_SERVICE               S_ERROR_SERVICE
+
+#define S_PENDING                      ((S_RESULT)0xFFFF2000)
+#define SM_PENDING                     S_PENDING
+
+/**
+ * Generic error code : Critical error causing the platform to shutdown.
+ */
+#define S_ERROR_CRITICAL                ((S_RESULT)0xFFFF3010)
+
+/**
+ * Generic error code : the underlying peripheral is unreachable.
+ */
+#define S_ERROR_UNREACHABLE             ((S_RESULT)0xFFFF3013)
+
+/*------------------------------------------------------------------------------
+   Communication Error Codes
+------------------------------------------------------------------------------*/
+/**
+ * Generic communication error
+ **/
+#define S_ERROR_COMMUNICATION          ((S_RESULT)0xFFFF000E)
+#define SM_ERROR_COMMUNICATION         S_ERROR_COMMUNICATION
+#define TEEC_ERROR_COMMUNICATION       S_ERROR_COMMUNICATION
+
+/**
+ * Error of communication : Error of protocol
+ **/
+#define S_ERROR_CONNECTION_PROTOCOL    ((S_RESULT)0xFFFF3020)
+
+/**
+ * Error of communication : The connection is broken.
+ **/
+#define S_ERROR_CONNECTION_BROKEN      ((S_RESULT)0xFFFF3021)
+
+/**
+ * Error of communication : Error during the connection setup.
+ **/
+#define S_ERROR_CONNECTION_SETUP       ((S_RESULT)0xFFFF3022)
+
+/**
+ * Error of communication : The connection is refused by the distant target.
+ **/
+#define S_ERROR_CONNECTION_REFUSED     ((S_RESULT)0xFFFF3023)
+
+/**
+ * Error of communication: The target of the connection is dead
+ **/
+#define S_ERROR_TARGET_DEAD            ((S_RESULT)0xFFFF3024)
+#define SM_ERROR_TARGET_DEAD           S_ERROR_TARGET_DEAD
+#define TEEC_ERROR_TARGET_DEAD         S_ERROR_TARGET_DEAD
+
+
+/*------------------------------------------------------------------------------
+   Storage Error Codes
+------------------------------------------------------------------------------*/
+
+/** File system error code: not enough space to complete the operation. */
+#define S_ERROR_STORAGE_NO_SPACE       ((S_RESULT)0xFFFF3041)
+#define SST_ERROR_NO_SPACE          0xFFFF3041
+
+/**
+ * File system error code: The file system is corrupted.
+ */
+#define S_ERROR_STORAGE_CORRUPTED      ((S_RESULT)0xFFFF3045)
+#define SST_ERROR_CORRUPTED            S_ERROR_STORAGE_CORRUPTED
+
+/**
+ * File system error code: The file system is unreachable.
+ */
+#define S_ERROR_STORAGE_UNREACHABLE    ((S_RESULT)0xFFFF3046)
+
+/*------------------------------------------------------------------------------
+   Authentication / X509 error codes
+------------------------------------------------------------------------------*/
+#define S_ERROR_AUTHENTICATION_FAILED  ((S_RESULT)0xFFFF3060)
+#define S_ERROR_WRONG_SIGNATURE        ((S_RESULT)0xFFFF3061)
+#define S_ERROR_BAD_CERTIFICATE        ((S_RESULT)0xFFFF3062)
+#define S_ERROR_WRONG_ISSUER           ((S_RESULT)0xFFFF3063)
+#define S_ERROR_CERTIFICATE_EXPIRED    ((S_RESULT)0xFFFF3064)
+
+/*------------------------------------------------------------------------------
+   Crypto error codes
+------------------------------------------------------------------------------*/
+#define S_ERROR_BAD_KEY                ((S_RESULT)0xFFFF3070)
+
+/*------------------------------------------------------------------------------
+   Indicates the physical memory is in TCM
+------------------------------------------------------------------------------*/
+#define S_ERROR_ARM_MEMORY_IS_TCM      ((S_RESULT)0xFFFF3100)
+
+/*------------------------------------------------------------------------------
+   VM-specific Error Codes
+------------------------------------------------------------------------------*/
+#define S_ERROR_UNCAUGHT_EXCEPTION     ((S_RESULT)0xFFFF3080)
+#define S_ERROR_TRUSTED_INTERPRETER    ((S_RESULT)0xFFFF3081)
+
+
+/*------------------------------------------------------------------------------
+   Range [0xFFFF3200:0xFFFF35FF] is reserved for internal use
+------------------------------------------------------------------------------*/
+
+#endif /* __S_ERROR_H__ */
+
+
diff --git a/security/tf_sdk/include/s_type.h b/security/tf_sdk/include/s_type.h
new file mode 100644
index 0000000..72f2a8a
--- /dev/null
+++ b/security/tf_sdk/include/s_type.h
@@ -0,0 +1,146 @@
+/**

+ * Copyright(c) 2011 Trusted Logic.   All rights reserved.

+ *

+ * Redistribution and use in source and binary forms, with or without

+ * modification, are permitted provided that the following conditions

+ * are met:

+ *

+ *  * Redistributions of source code must retain the above copyright

+ *    notice, this list of conditions and the following disclaimer.

+ *  * Redistributions in binary form must reproduce the above copyright

+ *    notice, this list of conditions and the following disclaimer in

+ *    the documentation and/or other materials provided with the

+ *    distribution.

+ *  * Neither the name Trusted Logic nor the names of its

+ *    contributors may be used to endorse or promote products derived

+ *    from this software without specific prior written permission.

+ *

+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS

+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT

+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR

+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT

+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,

+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT

+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,

+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY

+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT

+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE

+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

+ */
+
+/**
+ * Definition of the machine-specific integer types
+ **/
+#ifndef __S_TYPE_H__
+#define __S_TYPE_H__
+
+/* C99 integer types */
+#if (!defined(__STDC_VERSION__) || __STDC_VERSION__ < 199901L) &&(!defined(__ANDROID32__))
+
+#include <limits.h>
+
+/* Figure out if a 64-bit integer types is available */
+#if \
+    defined(_MSC_VER) || \
+    defined(__SYMBIAN32__) || \
+    defined(_WIN32_WCE) || \
+    (defined(ULLONG_MAX) && ULLONG_MAX == 0xFFFFFFFFFFFFFFFFULL) || \
+    (defined(ULONG_LONG_MAX) && ULONG_LONG_MAX == 0xFFFFFFFFFFFFFFFFULL)
+typedef unsigned long long uint64_t;
+typedef long long int64_t;
+#else
+#define __S_TYPE_INT64_UNDEFINED
+#endif
+
+#if UINT_MAX == 0xFFFFFFFF
+typedef unsigned int uint32_t;
+typedef int int32_t;
+#elif ULONG_MAX == 0xFFFFFFFF
+typedef unsigned long uint32_t;
+typedef long int32_t;
+#else
+#error This compiler is not supported.
+#endif
+
+#if USHRT_MAX == 0xFFFF
+typedef unsigned short uint16_t;
+typedef short  int16_t;
+#else
+#error This compiler is not supported.
+#endif
+
+#if UCHAR_MAX == 0xFF
+typedef unsigned char uint8_t;
+typedef signed char   int8_t;
+#else
+#error This compiler is not supported.
+#endif
+
+#if !defined(__cplusplus)
+typedef unsigned char bool;
+#define false ( (bool)0 )
+#define true  ( (bool)1 )
+#endif
+
+#else  /* !defined(__STDC_VERSION__) || __STDC_VERSION__ < 199901L */
+
+#include <stdbool.h>
+#include <stdint.h>
+
+#endif  /* !(!defined(__STDC_VERSION__) || __STDC_VERSION__ < 199901L) */
+
+#include <stddef.h>
+
+#ifndef NULL
+#  ifdef __cplusplus
+#     define NULL  0
+#  else
+#     define NULL  ((void *)0)
+#  endif
+#endif
+
+#define IN
+#define OUT
+
+/*
+ * Definition of other common types
+ */
+
+typedef uint32_t S_RESULT;
+typedef S_RESULT TEEC_Result;
+typedef S_RESULT SM_ERROR;
+
+typedef uint32_t S_HANDLE;
+typedef S_HANDLE SM_HANDLE;
+#define S_HANDLE_NULL ((S_HANDLE)0)
+#define SM_HANDLE_INVALID  S_HANDLE_NULL
+
+/** Definition of an UUID (from RFC 4122 http://www.ietf.org/rfc/rfc4122.txt) */
+typedef struct S_UUID
+{
+   uint32_t time_low;
+   uint16_t time_mid;
+   uint16_t time_hi_and_version;
+   uint8_t clock_seq_and_node[8];
+}S_UUID;
+typedef S_UUID TEEC_UUID;
+typedef S_UUID SM_UUID;
+
+/* DLL Import/Export directives */
+
+#if defined(WIN32) || defined(__ARMCC_VERSION) || defined(__WINSCW__) || defined(_WIN32_WCE)
+#  define S_DLL_EXPORT __declspec(dllexport)
+#  define S_DLL_IMPORT __declspec(dllimport)
+#  define S_NO_RETURN  __declspec(noreturn)
+#elif defined(__GNUC__)
+#  define S_DLL_EXPORT __attribute__ ((visibility ("default")))
+#  define S_DLL_IMPORT __attribute__ ((visibility ("default")))
+#  define S_NO_RETURN  __attribute__ ((noreturn))
+#else
+#  define S_DLL_EXPORT
+#  define S_DLL_IMPORT
+#  define S_NO_RETURN
+#endif
+
+#endif /* __S_TYPE_H__ */
+
diff --git a/security/tf_sdk/include/sst.h b/security/tf_sdk/include/sst.h
new file mode 100644
index 0000000..f84c25a
--- /dev/null
+++ b/security/tf_sdk/include/sst.h
@@ -0,0 +1,172 @@
+/**

+ * Copyright(c) 2011 Trusted Logic.   All rights reserved.

+ *

+ * Redistribution and use in source and binary forms, with or without

+ * modification, are permitted provided that the following conditions

+ * are met:

+ *

+ *  * Redistributions of source code must retain the above copyright

+ *    notice, this list of conditions and the following disclaimer.

+ *  * Redistributions in binary form must reproduce the above copyright

+ *    notice, this list of conditions and the following disclaimer in

+ *    the documentation and/or other materials provided with the

+ *    distribution.

+ *  * Neither the name Trusted Logic nor the names of its

+ *    contributors may be used to endorse or promote products derived

+ *    from this software without specific prior written permission.

+ *

+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS

+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT

+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR

+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT

+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,

+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT

+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,

+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY

+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT

+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE

+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

+ */

+

+#ifndef __SST_H__

+#define __SST_H__

+

+#ifdef __cplusplus

+extern "C" {

+#endif

+

+

+#include "s_type.h"

+#include "s_error.h"

+

+#ifdef SST_EXPORTS

+#define SST_EXPORT_API S_DLL_EXPORT

+#else

+#define SST_EXPORT_API S_DLL_IMPORT

+#endif

+

+/* -----------------------------------------------------------------------------

+                          Service SST Types

+----------------------------------------------------------------------------- */

+

+#ifndef EXCLUDE_SERVICE_SST_TYPES

+

+/** The SST_ERROR type */

+typedef uint32_t  SST_ERROR;

+

+/** The SST_HANDLE type */

+typedef uint32_t  SST_HANDLE;

+

+typedef struct SST_FILE_INFO

+{

+   char* pName;

+   uint32_t nSize;

+} SST_FILE_INFO;

+

+#endif /* EXCLUDE_SERVICE_SST_TYPES */

+

+typedef enum

+{

+   SST_SEEK_SET = 0,

+   SST_SEEK_CUR,

+   SST_SEEK_END

+} SST_WHENCE;

+

+

+/* -----------------------------------------------------------------------------

+                          Constants

+----------------------------------------------------------------------------- */

+

+#ifndef EXCLUDE_SERVICE_SST_CONSTANTS

+

+/** The Invalid SST_FILE_HANDLE */

+#define SST_NULL_HANDLE     0

+

+/* Legacy constant name */

+#define SST_HANDLE_INVALID    SST_NULL_HANDLE

+

+/** Max length for file names */

+#define SST_MAX_FILENAME 0x40

+

+/** Maximum pointer position in a file */

+#define SST_MAX_FILE_POSITION    0xFFFFFFFF

+

+/** File access modes */

+#define SST_O_READ               0x00000001

+#define SST_O_WRITE              0x00000002

+#define SST_O_WRITE_META         0x00000004

+#define SST_O_SHARE_READ         0x00000010

+#define SST_O_SHARE_WRITE        0x00000020

+#define SST_O_CREATE             0x00000200

+#define SST_O_EXCLUSIVE          0x00000400

+

+

+#endif /* EXCLUDE_SERVICE_SST_CONSTANTS */

+

+

+/* -----------------------------------------------------------------------------

+                        Functions

+----------------------------------------------------------------------------- */

+

+#ifndef EXCLUDE_SERVICE_SST_FUNCTIONS

+

+SST_ERROR SST_EXPORT_API SSTInit(void);

+

+SST_ERROR SST_EXPORT_API SSTTerminate(void);

+

+SST_ERROR SST_EXPORT_API SSTOpen(const char*       pFilename,

+                                 uint32_t    nFlags,

+                                 uint32_t    nReserved,

+                                 SST_HANDLE* phFile);

+

+SST_ERROR SST_EXPORT_API SSTCloseHandle(SST_HANDLE  hFile);

+

+SST_ERROR SST_EXPORT_API SSTWrite(SST_HANDLE hFile,

+                                  const uint8_t*   pBuffer,

+                                  uint32_t   nSize);

+

+SST_ERROR SST_EXPORT_API SSTRead(SST_HANDLE  hFile,

+                                 uint8_t*    pBuffer,

+                                 uint32_t    nSize,

+                                 uint32_t*   pnCount);

+

+SST_ERROR SST_EXPORT_API SSTSeek(SST_HANDLE  hFile,

+                                 int32_t     nOffset,

+                                 SST_WHENCE  eWhence);

+

+SST_ERROR SST_EXPORT_API SSTTell(SST_HANDLE  hFile,

+                                 uint32_t*   pnPos);

+

+SST_ERROR SST_EXPORT_API SSTGetSize(const char*        pFilename,

+                                    uint32_t*    pnSize);

+

+SST_ERROR SST_EXPORT_API SSTEof( SST_HANDLE   hFile,

+                                 bool*        pbEof);

+

+SST_ERROR SST_EXPORT_API SSTCloseAndDelete(SST_HANDLE hFile);

+

+SST_ERROR SST_EXPORT_API SSTTruncate(  SST_HANDLE  hFile,

+                                       uint32_t    nSize);

+

+SST_ERROR SST_EXPORT_API SSTRename(SST_HANDLE hFile,

+                                   const char* pNewFilename);

+

+SST_ERROR SST_EXPORT_API SSTEnumerationStart(const char*     pFilenamePattern,

+                                             uint32_t  nReserved1,

+                                             uint32_t  nReserved2,

+                                             SST_HANDLE* phFileEnumeration);

+

+SST_ERROR SST_EXPORT_API SSTEnumerationCloseHandle(SST_HANDLE hFileEnumeration);

+

+SST_ERROR SST_EXPORT_API SSTEnumerationGetNext(SST_HANDLE      hFileEnumeration,

+                                               SST_FILE_INFO** ppFileInfo);

+

+SST_ERROR SST_EXPORT_API SSTDestroyFileInfo(SST_FILE_INFO*   pFileInfo);

+

+#endif /* EXCLUDE_SERVICE_SST_FUNCTIONS */

+

+#ifdef __cplusplus

+}

+#endif

+

+#endif /* __SST_H__ */

diff --git a/security/tf_sdk/include/tee_client_api.h b/security/tf_sdk/include/tee_client_api.h
new file mode 100644
index 0000000..fb394f1
--- /dev/null
+++ b/security/tf_sdk/include/tee_client_api.h
@@ -0,0 +1,184 @@
+/**

+ * Copyright(c) 2011 Trusted Logic.   All rights reserved.

+ *

+ * Redistribution and use in source and binary forms, with or without

+ * modification, are permitted provided that the following conditions

+ * are met:

+ *

+ *  * Redistributions of source code must retain the above copyright

+ *    notice, this list of conditions and the following disclaimer.

+ *  * Redistributions in binary form must reproduce the above copyright

+ *    notice, this list of conditions and the following disclaimer in

+ *    the documentation and/or other materials provided with the

+ *    distribution.

+ *  * Neither the name Trusted Logic nor the names of its

+ *    contributors may be used to endorse or promote products derived

+ *    from this software without specific prior written permission.

+ *

+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS

+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT

+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR

+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT

+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,

+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT

+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,

+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY

+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT

+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE

+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

+ */

+

+/*

+ * This header file corresponds to V1.0 of the GlobalPlatform 

+ * TEE Client API Specification

+ */

+#ifndef   __TEE_CLIENT_API_H__

+#define   __TEE_CLIENT_API_H__

+

+#include "s_type.h"

+#include "s_error.h"

+

+#ifndef TEEC_EXPORT

+#define TEEC_EXPORT

+#endif

+

+/* The header tee_client_api_imp.h must define implementation-dependent

+   types, constants and macros.

+   

+   The implementation-dependent types are:

+     - TEEC_Context_IMP

+     - TEEC_Session_IMP

+     - TEEC_SharedMemory_IMP

+     - TEEC_Operation_IMP

+

+   The implementation-dependent constants are:

+     - TEEC_CONFIG_SHAREDMEM_MAX_SIZE  

+   The implementation-dependent macros are:

+     - TEEC_PARAM_TYPES

+*/

+#include "tee_client_api_imp.h"

+

+/* Type definitions */

+typedef struct TEEC_Context

+{

+   TEEC_Context_IMP imp;

+} TEEC_Context;

+

+typedef struct TEEC_Session

+{

+   TEEC_Session_IMP imp; 

+} TEEC_Session;

+

+typedef struct TEEC_SharedMemory

+{

+    void*    buffer;

+    size_t   size;

+    uint32_t flags;

+    TEEC_SharedMemory_IMP imp;

+} TEEC_SharedMemory;

+

+typedef struct

+{

+    void*     buffer;

+    size_t    size;

+} TEEC_TempMemoryReference;

+

+typedef struct

+{

+    TEEC_SharedMemory * parent;

+    size_t    size;

+    size_t    offset;

+} TEEC_RegisteredMemoryReference;

+

+typedef struct

+{

+    uint32_t   a;

+    uint32_t   b;

+} TEEC_Value;

+

+typedef union

+{

+   TEEC_TempMemoryReference        tmpref;

+   TEEC_RegisteredMemoryReference  memref;

+   TEEC_Value                      value;

+} TEEC_Parameter;

+

+typedef struct TEEC_Operation

+{

+    volatile uint32_t    started;

+    uint32_t             paramTypes;

+    TEEC_Parameter       params[4];   

+    

+    TEEC_Operation_IMP   imp;

+} TEEC_Operation;

+

+

+#define TEEC_ORIGIN_API                      0x00000001

+#define TEEC_ORIGIN_COMMS                    0x00000002

+#define TEEC_ORIGIN_TEE                      0x00000003

+#define TEEC_ORIGIN_TRUSTED_APP              0x00000004

+

+#define TEEC_MEM_INPUT                       0x00000001

+#define TEEC_MEM_OUTPUT                      0x00000002

+

+#define TEEC_NONE                     0x0

+#define TEEC_VALUE_INPUT              0x1

+#define TEEC_VALUE_OUTPUT             0x2

+#define TEEC_VALUE_INOUT              0x3

+#define TEEC_MEMREF_TEMP_INPUT        0x5

+#define TEEC_MEMREF_TEMP_OUTPUT       0x6

+#define TEEC_MEMREF_TEMP_INOUT        0x7

+#define TEEC_MEMREF_WHOLE             0xC

+#define TEEC_MEMREF_PARTIAL_INPUT     0xD

+#define TEEC_MEMREF_PARTIAL_OUTPUT    0xE

+#define TEEC_MEMREF_PARTIAL_INOUT     0xF

+

+#define TEEC_LOGIN_PUBLIC                    0x00000000

+#define TEEC_LOGIN_USER                      0x00000001

+#define TEEC_LOGIN_GROUP                     0x00000002

+#define TEEC_LOGIN_APPLICATION               0x00000004

+#define TEEC_LOGIN_USER_APPLICATION          0x00000005

+#define TEEC_LOGIN_GROUP_APPLICATION         0x00000006

+

+TEEC_Result TEEC_EXPORT TEEC_InitializeContext(

+    const char*   name,

+    TEEC_Context* context);

+

+void TEEC_EXPORT TEEC_FinalizeContext(

+    TEEC_Context* context);

+

+TEEC_Result TEEC_EXPORT TEEC_RegisterSharedMemory(

+    TEEC_Context*      context,

+    TEEC_SharedMemory* sharedMem);

+

+TEEC_Result TEEC_EXPORT TEEC_AllocateSharedMemory(

+    TEEC_Context*      context,

+    TEEC_SharedMemory* sharedMem);

+

+void TEEC_EXPORT TEEC_ReleaseSharedMemory (

+    TEEC_SharedMemory* sharedMem);

+

+TEEC_Result TEEC_EXPORT TEEC_OpenSession (

+    TEEC_Context*    context,

+    TEEC_Session*    session,

+    const TEEC_UUID* destination,

+    uint32_t         connectionMethod,

+    void*            connectionData,

+    TEEC_Operation*  operation,

+    uint32_t*        errorOrigin);

+

+void TEEC_EXPORT TEEC_CloseSession (

+    TEEC_Session* session);

+

+TEEC_Result TEEC_EXPORT TEEC_InvokeCommand(

+    TEEC_Session*     session,

+    uint32_t          commandID,

+    TEEC_Operation*   operation,

+    uint32_t*         errorOrigin);

+

+void TEEC_EXPORT TEEC_RequestCancellation(

+    TEEC_Operation* operation);

+

+#include "tee_client_api_ex.h"

+

+#endif /* __TEE_CLIENT_API_H__ */

diff --git a/security/tf_sdk/include/tee_client_api_ex.h b/security/tf_sdk/include/tee_client_api_ex.h
new file mode 100644
index 0000000..d0753ce
--- /dev/null
+++ b/security/tf_sdk/include/tee_client_api_ex.h
@@ -0,0 +1,105 @@
+/**

+ * Copyright(c) 2011 Trusted Logic.   All rights reserved.

+ *

+ * Redistribution and use in source and binary forms, with or without

+ * modification, are permitted provided that the following conditions

+ * are met:

+ *

+ *  * Redistributions of source code must retain the above copyright

+ *    notice, this list of conditions and the following disclaimer.

+ *  * Redistributions in binary form must reproduce the above copyright

+ *    notice, this list of conditions and the following disclaimer in

+ *    the documentation and/or other materials provided with the

+ *    distribution.

+ *  * Neither the name Trusted Logic nor the names of its

+ *    contributors may be used to endorse or promote products derived

+ *    from this software without specific prior written permission.

+ *

+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS

+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT

+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR

+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT

+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,

+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT

+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,

+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY

+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT

+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE

+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

+ */

+

+/*

+ * This header file contains extensions to the TEE Client API that are

+ * specific to the Trusted Foundations implementations

+ */

+#ifndef   __TEE_CLIENT_API_EX_H__

+#define   __TEE_CLIENT_API_EX_H__

+

+/* Implementation defined Login types  */

+#define TEEC_LOGIN_AUTHENTICATION      0x80000000

+#define TEEC_LOGIN_PRIVILEGED          0x80000002

+

+/* Type definitions */

+

+typedef struct

+{

+   uint32_t x;

+   uint32_t y;

+}

+TEEC_TimeLimit;

+

+typedef struct

+{

+   char apiDescription[65];

+   char commsDescription[65];

+   char TEEDescription[65];

+}

+TEEC_ImplementationInfo;

+

+typedef struct

+{

+   uint32_t pageSize;

+   uint32_t tmprefMaxSize;

+   uint32_t sharedMemMaxSize;

+   uint32_t nReserved3;

+   uint32_t nReserved4;

+   uint32_t nReserved5;

+   uint32_t nReserved6;

+   uint32_t nReserved7;

+} 

+TEEC_ImplementationLimits;

+

+void TEEC_EXPORT TEEC_GetImplementationInfo(

+   TEEC_Context*            context,

+   TEEC_ImplementationInfo* description);

+

+void TEEC_EXPORT TEEC_GetImplementationLimits(

+   TEEC_ImplementationLimits* limits);

+

+void TEEC_EXPORT TEEC_GetTimeLimit(

+    TEEC_Context*    context,

+    uint32_t         timeout,

+    TEEC_TimeLimit*  timeLimit);

+

+TEEC_Result TEEC_EXPORT TEEC_OpenSessionEx (

+    TEEC_Context*         context,

+    TEEC_Session*         session,

+    const TEEC_TimeLimit* timeLimit,

+    const TEEC_UUID*      destination,

+    uint32_t              connectionMethod,

+    void*                 connectionData,

+    TEEC_Operation*       operation,

+    uint32_t*             errorOrigin);

+

+TEEC_Result TEEC_EXPORT TEEC_InvokeCommandEx(

+    TEEC_Session*         session,

+    const TEEC_TimeLimit* timeLimit,

+    uint32_t              commandID,

+    TEEC_Operation*       operation,

+    uint32_t*             errorOrigin);

+

+TEEC_Result TEEC_EXPORT TEEC_ReadSignatureFile(

+   void**    ppSignatureFile,

+   uint32_t* pnSignatureFileLength);

+

+#endif /* __TEE_CLIENT_API_EX_H__ */

diff --git a/security/tf_sdk/include/tee_client_api_imp.h b/security/tf_sdk/include/tee_client_api_imp.h
new file mode 100644
index 0000000..caab1c5
--- /dev/null
+++ b/security/tf_sdk/include/tee_client_api_imp.h
@@ -0,0 +1,78 @@
+/**

+ * Copyright(c) 2011 Trusted Logic.   All rights reserved.

+ *

+ * Redistribution and use in source and binary forms, with or without

+ * modification, are permitted provided that the following conditions

+ * are met:

+ *

+ *  * Redistributions of source code must retain the above copyright

+ *    notice, this list of conditions and the following disclaimer.

+ *  * Redistributions in binary form must reproduce the above copyright

+ *    notice, this list of conditions and the following disclaimer in

+ *    the documentation and/or other materials provided with the

+ *    distribution.

+ *  * Neither the name Trusted Logic nor the names of its

+ *    contributors may be used to endorse or promote products derived

+ *    from this software without specific prior written permission.

+ *

+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS

+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT

+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR

+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT

+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,

+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT

+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,

+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY

+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT

+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE

+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

+ */

+

+/*

+ * This header file defines the implementation-dependent types,

+ * constants and macros for all the Trusted Foundations implementations

+ * of the TEE Client API

+ */

+#ifndef   __TEE_CLIENT_API_IMP_H__

+#define   __TEE_CLIENT_API_IMP_H__

+

+#include "s_type.h"

+#include "s_error.h"

+

+typedef struct

+{

+   uint32_t             _hConnection;

+}

+TEEC_Context_IMP;

+

+typedef struct

+{

+   struct TEEC_Context* _pContext;

+   S_HANDLE             _hClientSession;

+}

+TEEC_Session_IMP;

+

+typedef struct

+{

+   struct TEEC_Context* _pContext;

+   S_HANDLE             _hBlock;

+   bool                 _bAllocated;

+}

+TEEC_SharedMemory_IMP;

+

+typedef struct

+{

+   struct TEEC_Context* _pContext;

+    uint32_t            _hSession;

+}

+TEEC_Operation_IMP;

+

+/* There is no natural, compile-time limit on the shared memory, but a specific

+   implementation may introduce a limit (in particular on TrustZone) */

+#define TEEC_CONFIG_SHAREDMEM_MAX_SIZE ((size_t)0xFFFFFFFF)

+

+#define TEEC_PARAM_TYPES(entry0Type, entry1Type, entry2Type, entry3Type) \

+   ((entry0Type) | ((entry1Type) << 4) | ((entry2Type) << 8) | ((entry3Type) << 12))

+

+

+#endif /* __TEE_CLIENT_API_IMP_H__ */