From 2e9e9eca83c3dee85b7815573a8cf1e6d1780741 Mon Sep 17 00:00:00 2001 From: Bryan Buckley Date: Wed, 19 Oct 2011 19:12:18 -0500 Subject: 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 ." Gerrit refuses to accept. Change-Id: Ie81604d3fee31abc319643401c3cc66888f9f848 Signed-off-by: Bryan Buckley Signed-off-by: Trusted Logic --- security/NOTICE | 31 + security/smc_pa_ctrl/Android.mk | 25 + security/smc_pa_ctrl/s_version.h | 114 ++ security/smc_pa_ctrl/smc_pa_ctrl.c | 219 +++ security/smc_pa_ctrl/smc_pa_ctrl_linux.c | 284 ++++ security/smc_pa_ctrl/smc_pa_ctrl_os.h | 61 + security/tee_client_api/Android.mk | 25 + security/tee_client_api/s_version.h | 113 ++ security/tee_client_api/schannel6_logins.h | 97 ++ security/tee_client_api/schannel6_protocol.h | 425 ++++++ .../tee_client_api/tee_client_api_linux_driver.c | 929 +++++++++++++ security/tf_daemon/Android.mk | 31 + security/tf_daemon/delegation_client.c | 1401 ++++++++++++++++++++ security/tf_daemon/delegation_client_extension.c | 138 ++ security/tf_daemon/delegation_client_extension.h | 55 + security/tf_daemon/lib_manifest2.c | 678 ++++++++++ security/tf_daemon/lib_manifest2.h | 111 ++ security/tf_daemon/s_version.h | 113 ++ security/tf_daemon/service_delegation_protocol.h | 114 ++ security/tf_daemon/smc_properties.c | 323 +++++ security/tf_daemon/smc_properties.h | 75 ++ security/tf_daemon/smc_properties_parser.c | 556 ++++++++ security/tf_daemon/smc_properties_parser.h | 125 ++ security/tf_sdk/include/cryptoki.h | 54 + security/tf_sdk/include/mtc.h | 97 ++ security/tf_sdk/include/pkcs11.h | 595 +++++++++ security/tf_sdk/include/s_error.h | 321 +++++ security/tf_sdk/include/s_type.h | 146 ++ security/tf_sdk/include/sst.h | 172 +++ security/tf_sdk/include/tee_client_api.h | 184 +++ security/tf_sdk/include/tee_client_api_ex.h | 105 ++ security/tf_sdk/include/tee_client_api_imp.h | 78 ++ 32 files changed, 7795 insertions(+) create mode 100755 security/NOTICE create mode 100644 security/smc_pa_ctrl/Android.mk create mode 100644 security/smc_pa_ctrl/s_version.h create mode 100644 security/smc_pa_ctrl/smc_pa_ctrl.c create mode 100644 security/smc_pa_ctrl/smc_pa_ctrl_linux.c create mode 100644 security/smc_pa_ctrl/smc_pa_ctrl_os.h create mode 100644 security/tee_client_api/Android.mk create mode 100644 security/tee_client_api/s_version.h create mode 100644 security/tee_client_api/schannel6_logins.h create mode 100644 security/tee_client_api/schannel6_protocol.h create mode 100644 security/tee_client_api/tee_client_api_linux_driver.c create mode 100644 security/tf_daemon/Android.mk create mode 100644 security/tf_daemon/delegation_client.c create mode 100644 security/tf_daemon/delegation_client_extension.c create mode 100644 security/tf_daemon/delegation_client_extension.h create mode 100644 security/tf_daemon/lib_manifest2.c create mode 100644 security/tf_daemon/lib_manifest2.h create mode 100644 security/tf_daemon/s_version.h create mode 100644 security/tf_daemon/service_delegation_protocol.h create mode 100644 security/tf_daemon/smc_properties.c create mode 100644 security/tf_daemon/smc_properties.h create mode 100644 security/tf_daemon/smc_properties_parser.c create mode 100644 security/tf_daemon/smc_properties_parser.h create mode 100644 security/tf_sdk/include/cryptoki.h create mode 100644 security/tf_sdk/include/mtc.h create mode 100644 security/tf_sdk/include/pkcs11.h create mode 100644 security/tf_sdk/include/s_error.h create mode 100644 security/tf_sdk/include/s_type.h create mode 100644 security/tf_sdk/include/sst.h create mode 100644 security/tf_sdk/include/tee_client_api.h create mode 100644 security/tf_sdk/include/tee_client_api_ex.h create mode 100644 security/tf_sdk/include/tee_client_api_imp.h (limited to 'security') 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 +#include +#include + +#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 [command]\n"); + printf(" Options:\n"); + printf(" -h, --help: Print this help\n"); + printf(" Commands:\n"); + printf(" -c : Configuration file path\n"); + printf(" start : load and start the SMC PA\n"); + printf("\n"); +#else + printf("usage : smc_pa_ctrl [command]\n"); + printf(" Options:\n"); + printf(" -h, --help: Print this help\n"); + printf(" Commands:\n"); + printf(" -c : Configuration file path\n"); + printf(" start : 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 +#include +#include +#include +#include +#ifndef WIN32 +#include +#include +#endif +#include +#include + +#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 +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * 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 +#endif +#include +#include +#include + +/* + * When porting to a new OS, insert here the appropriate include files + */ +#include +#include +#include +#include + +#if defined(LINUX) || defined(__ANDROID32__) +#include +#include + + +#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 +#include +#include +#include +#include +#define PATH_SEPARATOR '/' +#endif /* LINUX || __ANDROID32__ */ + +#ifdef WIN32 +#include +#include +#define PATH_SEPARATOR '\\' +#endif + +#ifdef __SYMBIAN32__ +#include +#include "os_symbian.h" +#define PATH_SEPARATOR '\\' +#endif + +#include +#include + +#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 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 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 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 +#include +#include +#include +#include + +#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 + +#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 +#include +#include +#include +#include +#include +#include + +#if defined(_WIN32_WCE) +#include "os_wm.h" +#else +#include +#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; ipValue; + + //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 +#include +#include +#include +#include + +#if defined(_WIN32_WCE) +#include "os_wm.h" +#else +#include +#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 +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 + +/* 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 +#include + +#endif /* !(!defined(__STDC_VERSION__) || __STDC_VERSION__ < 199901L) */ + +#include + +#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__ */ -- cgit v1.1