12e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley/**
22e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley * Copyright(c) 2011 Trusted Logic.   All rights reserved.
32e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley *
42e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley * Redistribution and use in source and binary forms, with or without
52e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley * modification, are permitted provided that the following conditions
62e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley * are met:
72e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley *
82e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley *  * Redistributions of source code must retain the above copyright
92e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley *    notice, this list of conditions and the following disclaimer.
102e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley *  * Redistributions in binary form must reproduce the above copyright
112e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley *    notice, this list of conditions and the following disclaimer in
122e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley *    the documentation and/or other materials provided with the
132e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley *    distribution.
142e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley *  * Neither the name Trusted Logic nor the names of its
152e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley *    contributors may be used to endorse or promote products derived
162e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley *    from this software without specific prior written permission.
172e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley *
182e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
192e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
202e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
212e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
222e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
232e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
242e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
252e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
262e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
272e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
282e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
292e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley */
302e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley
312e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley#if defined(__ANDROID32__)
322e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley#include <stddef.h>
332e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley#endif
342e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley#include <stdio.h>
352e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley#include <stdlib.h>
362e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley#include <string.h>
372e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley
382e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley/*
392e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley * When porting to a new OS, insert here the appropriate include files
402e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley */
412e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley#include <sys/stat.h>
422e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley#include <errno.h>
432e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley#include <sys/types.h>
442e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley#include <fcntl.h>
452e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley
462e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley#if defined(LINUX) || defined(__ANDROID32__)
472e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley#include <unistd.h>
482e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley#include <sys/resource.h>
492e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley
502e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley
512e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley#if defined(__ANDROID32__)
522e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley/* fdatasync does not exist on Android */
532e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley#define fdatasync fsync
542e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley#else
552e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley/*
562e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley * http://linux.die.net/man/2/fsync
572e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley * The function fdatasync seems to be absent of the header file
582e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley * in some distributions
592e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley */
602e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckleyint fdatasync(int fd);
612e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley#endif /* __ANDROID32__ */
622e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley#include <syslog.h>
632e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley#include <sys/types.h>
642e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley#include <sys/stat.h>
652e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley#include <pthread.h>
662e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley#include <semaphore.h>
672e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley#define PATH_SEPARATOR '/'
682e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley#endif /* LINUX || __ANDROID32__ */
692e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley
702e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley#ifdef WIN32
712e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley#include <windows.h>
722e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley#include <io.h>
732e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley#define PATH_SEPARATOR '\\'
742e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley#endif
752e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley
762e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley#ifdef __SYMBIAN32__
772e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley#include <unistd.h>
782e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley#include "os_symbian.h"
792e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley#define PATH_SEPARATOR '\\'
802e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley#endif
812e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley
822e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley#include <stdarg.h>
832e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley#include <assert.h>
842e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley
852e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley#include "service_delegation_protocol.h"
862e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley
872e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley#include "s_version.h"
882e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley#include "s_error.h"
892e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley#include "tee_client_api.h"
902e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley
912e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley/* You can define the preprocessor constant SUPPORT_DELEGATION_EXTENSION
922e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   if you want to pass extended options in a configuration file (option '-c').
932e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   It is up to you to define the format of this configuration file and the
942e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   extended option in the source file delegation_client_extension.c. You can
952e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   use extended options, e.g., to control the name of each partition file. */
962e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley#ifdef SUPPORT_DELEGATION_EXTENSION
972e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley#include "delegation_client_extension.h"
982e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley#endif
992e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley
1002e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley/*----------------------------------------------------------------------------
1012e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley * Design notes
1022e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley * ============
1032e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley *
1042e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley * This implementation of the delegation daemon supports the protocol
1052e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley * specified in the Product Reference Manual ("Built-in Services Protocols Specification")
1062e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley *
1072e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley *----------------------------------------------------------------------------*/
1082e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley
1092e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley/*----------------------------------------------------------------------------
1102e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley * Defines and structures
1112e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley *----------------------------------------------------------------------------*/
1122e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley#define ECHANGE_BUFFER_INSTRUCTIONS_NB 100
1132e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley
1142e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley#define DEFAULT_WORKSPACE_SIZE (128*1024)
1152e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley
1162e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley/* A single shared memory block is used to contain the administrative data, the
1172e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   instruction buffer and the workspace. The size of the instruction buffer is
1182e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   fixed, but the size of workspace can be configured using the "-workspaceSize"
1192e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   command-line option. */
1202e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckleytypedef struct
1212e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley{
1222e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   DELEGATION_ADMINISTRATIVE_DATA sAdministrativeData;
1232e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   uint32_t                       sInstructions[ECHANGE_BUFFER_INSTRUCTIONS_NB];
1242e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   uint8_t                        sWorkspace[1/*g_nWorkspaceSize*/];
1252e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley} DELEGATION_EXCHANGE_BUFFER;
1262e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley
1272e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley#define MD_VAR_NOT_USED(variable)  do{(void)(variable);}while(0);
1282e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley
1292e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley#define MD_INLINE __inline
1302e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley
1312e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley/* ----------------------------------------------
1322e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   Traces and logs
1332e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley
1342e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   On Linux, traces and logs go either to the console (stderr) or to the syslog.
1352e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   When the daemon is started, the logs go to the console. Once and if the daemon
1362e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   is detached, the logs go to syslog.
1372e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley
1382e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   On other systems, traces and logs go systematically to stderr
1392e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley
1402e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   The difference between traces and logs is that traces are compiled out
1412e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   in release builds whereas logs are visible to the customer.
1422e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley
1432e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   -----------------------------------------------*/
1442e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley#if defined(LINUX) || (defined __ANDROID32__)
1452e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley
1462e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckleystatic bool bDetached = false;
1472e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley
1482e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckleystatic MD_INLINE void LogError(const char* format, ...)
1492e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley{
1502e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   va_list ap;
1512e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   va_start(ap, format);
1522e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   if (bDetached)
1532e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   {
1542e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      vsyslog(LOG_ERR, format, ap);
1552e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   }
1562e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   else
1572e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   {
1582e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      fprintf(stderr, "ERROR: ");
1592e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      vfprintf(stderr, format, ap);
1602e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      fprintf(stderr, "\n");
1612e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   }
1622e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   va_end(ap);
1632e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley}
1642e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley
1652e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckleystatic MD_INLINE void LogWarning(const char* format, ...)
1662e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley{
1672e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   va_list ap;
1682e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   va_start(ap, format);
1692e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   if (bDetached)
1702e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   {
1712e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      vsyslog(LOG_WARNING, format, ap);
1722e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   }
1732e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   else
1742e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   {
1752e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      fprintf(stderr, "WARNING: ");
1762e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      vfprintf(stderr, format, ap);
1772e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      fprintf(stderr, "\n");
1782e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   }
1792e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   va_end(ap);
1802e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley}
1812e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckleystatic MD_INLINE void LogInfo(const char* format, ...)
1822e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley{
1832e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   va_list ap;
1842e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   va_start(ap, format);
1852e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   if (bDetached)
1862e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   {
1872e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      vsyslog(LOG_INFO, format, ap);
1882e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   }
1892e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   else
1902e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   {
1912e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      vfprintf(stderr, format, ap);
1922e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      fprintf(stderr, "\n");
1932e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   }
1942e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   va_end(ap);
1952e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley}
1962e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley
1972e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckleystatic MD_INLINE void TRACE_ERROR(const char* format, ...)
1982e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley{
1992e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley#ifndef NDEBUG
2002e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   va_list ap;
2012e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   va_start(ap, format);
2022e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   if (bDetached)
2032e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   {
2042e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      vsyslog(LOG_ERR, format, ap);
2052e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   }
2062e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   else
2072e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   {
2082e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      fprintf(stderr, "TRACE: ERROR: ");
2092e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      vfprintf(stderr, format, ap);
2102e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      fprintf(stderr, "\n");
2112e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   }
2122e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   va_end(ap);
2132e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley#else
2142e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   MD_VAR_NOT_USED(format);
2152e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley#endif /* NDEBUG */
2162e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley}
2172e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley
2182e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckleystatic MD_INLINE void TRACE_WARNING(const char* format, ...)
2192e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley{
2202e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley#ifndef NDEBUG
2212e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   va_list ap;
2222e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   va_start(ap, format);
2232e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   if (bDetached)
2242e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   {
2252e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      vsyslog(LOG_WARNING, format, ap);
2262e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   }
2272e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   else
2282e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   {
2292e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      fprintf(stderr, "TRACE: WARNING: ");
2302e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      vfprintf(stderr, format, ap);
2312e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      fprintf(stderr, "\n");
2322e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   }
2332e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   va_end(ap);
2342e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley#else
2352e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   MD_VAR_NOT_USED(format);
2362e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley#endif /* NDEBUG */
2372e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley}
2382e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley
2392e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckleystatic MD_INLINE void TRACE_INFO(const char* format, ...)
2402e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley{
2412e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley#ifndef NDEBUG
2422e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   va_list ap;
2432e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   va_start(ap, format);
2442e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   if (bDetached)
2452e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   {
2462e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      vsyslog(LOG_DEBUG, format, ap);
2472e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   }
2482e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   else
2492e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   {
2502e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      fprintf(stderr, "TRACE: ");
2512e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      vfprintf(stderr, format, ap);
2522e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      fprintf(stderr, "\n");
2532e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   }
2542e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   va_end(ap);
2552e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley#else
2562e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   MD_VAR_NOT_USED(format);
2572e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley#endif /* NDEBUG */
2582e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley}
2592e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley#elif defined __SYMBIAN32__
2602e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley/* defined in os_symbian.h */
2612e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley
2622e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley#elif defined NO_LOG_NO_TRACE
2632e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckleystatic MD_INLINE void LogError(const char* format, ...)
2642e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley{
2652e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   MD_VAR_NOT_USED(format);
2662e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley}
2672e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckleystatic MD_INLINE void LogWarning(const char* format, ...)
2682e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley{
2692e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   MD_VAR_NOT_USED(format);
2702e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley}
2712e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckleystatic MD_INLINE void LogInfo(const char* format, ...)
2722e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley{
2732e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   MD_VAR_NOT_USED(format);
2742e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley}
2752e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley
2762e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckleystatic MD_INLINE void TRACE_ERROR(const char* format, ...)
2772e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley{
2782e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   MD_VAR_NOT_USED(format);
2792e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley}
2802e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley
2812e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckleystatic MD_INLINE void TRACE_WARNING(const char* format, ...)
2822e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley{
2832e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   MD_VAR_NOT_USED(format);
2842e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley}
2852e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley
2862e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckleystatic MD_INLINE void TRACE_INFO(const char* format, ...)
2872e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley{
2882e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   MD_VAR_NOT_USED(format);
2892e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley}
2902e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley
2912e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley#else
2922e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley/* !defined(LINUX) || !defined(__ANDROID32__) */
2932e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley
2942e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckleystatic MD_INLINE void LogError(const char* format, ...)
2952e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley{
2962e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   va_list ap;
2972e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   va_start(ap, format);
2982e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   fprintf(stderr, "ERROR: ");
2992e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   vfprintf(stderr, format, ap);
3002e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   fprintf(stderr, "\n");
3012e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   va_end(ap);
3022e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley}
3032e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckleystatic MD_INLINE void LogWarning(const char* format, ...)
3042e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley{
3052e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   va_list ap;
3062e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   va_start(ap, format);
3072e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   fprintf(stderr, "WARNING: ");
3082e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   vfprintf(stderr, format, ap);
3092e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   fprintf(stderr, "\n");
3102e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   va_end(ap);
3112e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley}
3122e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckleystatic MD_INLINE void LogInfo(const char* format, ...)
3132e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley{
3142e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   va_list ap;
3152e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   va_start(ap, format);
3162e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   vfprintf(stderr, format, ap);
3172e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   fprintf(stderr, "\n");
3182e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   va_end(ap);
3192e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley}
3202e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley
3212e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckleystatic MD_INLINE void TRACE_ERROR(const char* format, ...)
3222e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley{
3232e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley#ifndef NDEBUG
3242e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   va_list ap;
3252e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   va_start(ap, format);
3262e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   fprintf(stderr, "TRACE: ERROR: ");
3272e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   vfprintf(stderr, format, ap);
3282e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   fprintf(stderr, "\n");
3292e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   va_end(ap);
3302e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley#else
3312e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   MD_VAR_NOT_USED(format);
3322e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley#endif /* NDEBUG */
3332e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley}
3342e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley
3352e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckleystatic MD_INLINE void TRACE_WARNING(const char* format, ...)
3362e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley{
3372e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley#ifndef NDEBUG
3382e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   va_list ap;
3392e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   va_start(ap, format);
3402e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   fprintf(stderr, "TRACE: WARNING: ");
3412e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   vfprintf(stderr, format, ap);
3422e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   fprintf(stderr, "\n");
3432e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   va_end(ap);
3442e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley#else
3452e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   MD_VAR_NOT_USED(format);
3462e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley#endif /* NDEBUG */
3472e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley}
3482e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley
3492e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckleystatic MD_INLINE void TRACE_INFO(const char* format, ...)
3502e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley{
3512e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley#ifndef NDEBUG
3522e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   va_list ap;
3532e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   va_start(ap, format);
3542e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   fprintf(stderr, "TRACE: ");
3552e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   vfprintf(stderr, format, ap);
3562e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   fprintf(stderr, "\n");
3572e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   va_end(ap);
3582e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley#else
3592e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   MD_VAR_NOT_USED(format);
3602e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley#endif /* NDEBUG */
3612e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley}
3622e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley#endif /* defined(LINUX) || defined(__ANDROID32__) */
3632e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley
3642e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley/*----------------------------------------------------------------------------
3652e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley * Globals
3662e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley *----------------------------------------------------------------------------*/
3672e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley/* The sector size */
3682e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckleystatic uint32_t g_nSectorSize;
3692e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley
3702e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley/* The workspace size */
3712e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckleystatic uint32_t g_nWorkspaceSize = DEFAULT_WORKSPACE_SIZE;
3722e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley
3732e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley/* UUID of the delegation service */
3742e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckleystatic const TEEC_UUID g_sServiceId = SERVICE_DELEGATION_UUID;
3752e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley
3762e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley/* pWorkspaceBuffer points to the workspace buffer shared with the secure
3772e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   world to transfer the sectors in the READ and WRITE instructions  */
3782e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckleystatic uint8_t* g_pWorkspaceBuffer;
3792e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckleystatic DELEGATION_EXCHANGE_BUFFER * g_pExchangeBuffer;
3802e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan BuckleyTEEC_SharedMemory sExchangeSharedMem;
3812e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley/*
3822e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   The absolute path name for each of the 16 possible partitions.
3832e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley */
3842e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckleystatic char* g_pPartitionNames[16];
3852e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley
3862e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley/* The file context for each of the 16 possible partitions. An entry
3872e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   in this array is NULL if the corresponding partition is currently not opened
3882e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley */
3892e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckleystatic FILE* g_pPartitionFiles[16];
3902e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley
3912e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley/*----------------------------------------------------------------------------
3922e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley * Utilities functions
3932e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley *----------------------------------------------------------------------------*/
3942e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckleystatic void printUsage(void)
3952e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley{
3962e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   LogInfo("usage : tf_daemon [options]");
3972e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   LogInfo("where [options] are:");
3982e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   LogInfo("-h --help  Display help.");
3992e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley#ifdef SUPPORT_DELEGATION_EXTENSION
4002e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   LogInfo("-c <conf>  Configuration file path.");
4012e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley#else
4022e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   /* If the compilation parameter SUPPORT_DELEGATION_EXTENSION is not set, each
4032e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      partition is stored as a file within the base dir */
4042e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   LogInfo("-storageDir <baseDir>  Set the directory where the data will be stored; this directory");
4052e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   LogInfo("           must be writable and executable (this parameter is mandatory)");
4062e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley#endif
4072e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   LogInfo("-d         Turns on debug mode.  If not specified, the daemon will fork itself");
4082e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   LogInfo("           and get detached from the console.");
4092e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley#ifndef SUPPORT_DELEGATION_EXTENSION
4102e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   LogInfo("-workspaceSize <integer>  Set the size in bytes of the workspace. Must be greater or equal to 8 sectors.");
4112e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   LogInfo("           (default is 128KB)");
4122e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley#endif
4132e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley}
4142e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley
4152e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckleystatic TEEC_Result errno2serror(void)
4162e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley{
4172e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   switch (errno)
4182e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   {
4192e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   case EINVAL:
4202e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      return S_ERROR_BAD_PARAMETERS;
4212e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   case EMFILE:
4222e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      return S_ERROR_NO_MORE_HANDLES;
4232e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   case ENOENT:
4242e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      return S_ERROR_ITEM_NOT_FOUND;
4252e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   case EEXIST:
4262e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      return S_ERROR_ITEM_EXISTS;
4272e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   case ENOSPC:
4282e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      return S_ERROR_STORAGE_NO_SPACE;
4292e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   case ENOMEM:
4302e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      return S_ERROR_OUT_OF_MEMORY;
4312e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   case EBADF:
4322e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   case EACCES:
4332e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   default:
4342e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      return S_ERROR_STORAGE_UNREACHABLE;
4352e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   }
4362e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley}
4372e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley
4382e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley/*
4392e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley * Check if the directory in parameter exists with Read/Write access
4402e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley * Return 0 in case of success and 1 otherwise.
4412e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley */
4422e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckleyint static_checkStorageDirAndAccessRights(char * directoryName)
4432e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley{
4442e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley#ifdef __SYMBIAN32__
4452e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   /* it looks like stat is not working properly on Symbian
4462e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      Create and remove dummy file to check access rights */
4472e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   FILE *stream;
4482e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   char *checkAccess = NULL;
4492e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley
4502e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   if (directoryName == NULL)
4512e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   {
4522e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      LogError("Directory Name is NULL");
4532e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      return 1;
4542e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   }
4552e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley
4562e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   checkAccess = malloc(strlen(directoryName)+1/* \ */ +1 /* a */ + 1 /* 0 */);
4572e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   if (!checkAccess)
4582e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   {
4592e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      LogError("storageDir '%s' allocation error", directoryName);
4602e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      return 1;
4612e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   }
4622e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   sprintf(checkAccess,"%s\\a",directoryName);
4632e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   stream = fopen(checkAccess, "w+b");
4642e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   if (!stream)
4652e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   {
4662e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      LogError("storageDir '%s' is incorrect or cannot be reached", directoryName);
4672e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      return 1;
4682e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   }
4692e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   fclose(stream);
4702e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   unlink(checkAccess);
4712e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley#else
4722e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   /* Non-Symbian OS: use stat */
4732e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   struct stat buf;
4742e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   int result = 0;
4752e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley
4762e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   if (directoryName == NULL)
4772e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   {
4782e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      LogError("Directory Name is NULL");
4792e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      return 1;
4802e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   }
4812e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley
4822e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   result = stat(directoryName, &buf);
4832e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   if (result == 0)
4842e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   {
4852e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      /* Storage dir exists. Check access rights */
4862e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley#if defined(LINUX) || (defined __ANDROID32__)
4872e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      if ((buf.st_mode & (S_IXUSR | S_IWUSR)) != (S_IXUSR | S_IWUSR))
4882e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      {
4892e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         LogError("storageDir '%s' does not have read-write access", directoryName);
4902e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         return 1;
4912e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      }
4922e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley#endif
4932e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   }
4942e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   else if (errno == ENOENT)
4952e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   {
4962e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      LogError("storageDir '%s' does not exist", directoryName);
4972e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      return 1;
4982e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   }
4992e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   else
5002e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   {
5012e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      /* Another error */
5022e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      LogError("storageDir '%s' is incorrect or cannot be reached", directoryName);
5032e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      return 1;
5042e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   }
5052e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley#endif
5062e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   return 0;
5072e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley}
5082e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley
5092e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley
5102e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley
5112e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley/*----------------------------------------------------------------------------
5122e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley * Instructions
5132e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley *----------------------------------------------------------------------------*/
5142e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley
5152e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley/**
5162e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley * This function executes the DESTROY_PARTITION instruction
5172e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley *
5182e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley * @param nPartitionID: the partition identifier
5192e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley **/
5202e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckleystatic TEEC_Result partitionDestroy(uint32_t nPartitionID)
5212e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley{
5222e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   TEEC_Result  nError = S_SUCCESS;
5232e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley
5242e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   if (g_pPartitionFiles[nPartitionID] != NULL)
5252e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   {
5262e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      /* The partition must not be currently opened */
5272e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      LogError("g_pPartitionFiles not NULL");
5282e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      return S_ERROR_BAD_STATE;
5292e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   }
5302e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley
5312e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   /* Try to erase the file */
5322e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley#if defined(LINUX) || (defined __ANDROID32__) || defined (__SYMBIAN32__)
5332e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   if (unlink(g_pPartitionNames[nPartitionID]) != 0)
5342e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley#endif
5352e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley#ifdef WIN32
5362e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   if (_unlink(g_pPartitionNames[nPartitionID]) != 0)
5372e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley#endif
5382e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   {
5392e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      /* File in use or OS didn't allow the operation */
5402e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      nError = errno2serror();
5412e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   }
5422e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley
5432e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   return nError;
5442e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley}
5452e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley
5462e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley/**
5472e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley * This function executes the CREATE_PARTITION instruction. When successful,
5482e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley * it fills the g_pPartitionFiles[nPartitionID] slot.
5492e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley *
5502e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley * @param nPartitionID: the partition identifier
5512e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley **/
5522e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckleystatic TEEC_Result partitionCreate(uint32_t nPartitionID)
5532e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley{
5542e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   uint32_t nError = S_SUCCESS;
5552e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley
5562e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   if (g_pPartitionFiles[nPartitionID] != NULL)
5572e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   {
5582e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      /* The partition is already opened */
5592e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      LogError("g_pPartitionFiles not NULL");
5602e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      return S_ERROR_BAD_STATE;
5612e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   }
5622e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley
5632e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   /* Create the file unconditionnally */
5642e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   LogInfo("Create storage file \"%s\"", g_pPartitionNames[nPartitionID]);
5652e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   g_pPartitionFiles[nPartitionID] = fopen(g_pPartitionNames[nPartitionID], "w+b");
5662e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley
5672e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   if (g_pPartitionFiles[nPartitionID] == NULL)
5682e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   {
5692e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      LogError("Cannot create storage file \"%s\"", g_pPartitionNames[nPartitionID]);
5702e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      nError = errno2serror();
5712e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      return nError;
5722e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   }
5732e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley
5742e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   return nError;
5752e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley}
5762e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley
5772e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley/**
5782e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley * This function executes the OPEN_PARTITION instruction. When successful,
5792e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley * it fills the g_pPartitionFiles[nPartitionID] slot and writes the partition
5802e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley * size in hResultEncoder
5812e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley *
5822e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley * @param nPartitionID: the partition identifier
5832e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley * @param pnPartitionSize: filled with the number of sectors in the partition
5842e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley **/
5852e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckleystatic TEEC_Result partitionOpen(uint32_t nPartitionID, uint32_t* pnPartitionSize)
5862e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley{
5872e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   uint32_t nError = S_SUCCESS;
5882e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley
5892e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   if (g_pPartitionFiles[nPartitionID] != NULL)
5902e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   {
5912e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      /* No partition must be currently opened in the session */
5922e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      LogError("g_pPartitionFiles not NULL");
5932e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      return S_ERROR_BAD_STATE;
5942e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   }
5952e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley
5962e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   /* Open the file */
5972e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   g_pPartitionFiles[nPartitionID] = fopen(g_pPartitionNames[nPartitionID], "r+b");
5982e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   if (g_pPartitionFiles[nPartitionID] == NULL)
5992e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   {
6002e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      if (errno == ENOENT)
6012e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      {
6022e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         /* File does not exist */
6032e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         LogError("Storage file \"%s\" does not exist", g_pPartitionNames[nPartitionID]);
6042e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         nError = S_ERROR_ITEM_NOT_FOUND;
6052e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         return nError;
6062e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      }
6072e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      else
6082e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      {
6092e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         LogError("cannot open storage file \"%s\"", g_pPartitionNames[nPartitionID]);
6102e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         nError = errno2serror();
6112e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         return nError;
6122e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      }
6132e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   }
6142e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   /* Determine the current number of sectors */
6152e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   fseek(g_pPartitionFiles[nPartitionID], 0L, SEEK_END);
6162e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   *pnPartitionSize = ftell(g_pPartitionFiles[nPartitionID]) / g_nSectorSize;
6172e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley
6182e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   LogInfo("storage file \"%s\" successfully opened (size = %d KB (%d bytes))",
6192e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      g_pPartitionNames[nPartitionID],
6202e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      ((*pnPartitionSize) * g_nSectorSize) / 1024,
6212e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      ((*pnPartitionSize) * g_nSectorSize));
6222e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley
6232e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   return nError;
6242e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley}
6252e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley
6262e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley
6272e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley/**
6282e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley * This function executes the CLOSE_PARTITION instruction.
6292e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley * It closes the partition file.
6302e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley *
6312e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley * @param nPartitionID: the partition identifier
6322e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley **/
6332e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckleystatic TEEC_Result partitionClose(uint32_t nPartitionID)
6342e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley{
6352e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   if (g_pPartitionFiles[nPartitionID] == NULL)
6362e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   {
6372e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      /* The partition is currently not opened */
6382e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      return S_ERROR_BAD_STATE;
6392e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   }
6402e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   fclose(g_pPartitionFiles[nPartitionID]);
6412e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   g_pPartitionFiles[nPartitionID] = NULL;
6422e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   return S_SUCCESS;
6432e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley}
6442e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley
6452e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley/**
6462e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley * This function executes the READ instruction.
6472e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley *
6482e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley * @param nPartitionID: the partition identifier
6492e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley * @param nSectorIndex: the index of the sector to read
6502e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley * @param nWorkspaceOffset: the offset in the workspace where the sector must be written
6512e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley **/
6522e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckleystatic TEEC_Result partitionRead(uint32_t nPartitionID, uint32_t nSectorIndex, uint32_t nWorkspaceOffset)
6532e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley{
6542e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   FILE* pFile;
6552e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley
6562e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   TRACE_INFO(">Partition %1X: read sector 0x%08X into workspace at offset 0x%08X",
6572e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      nPartitionID, nSectorIndex, nWorkspaceOffset);
6582e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley
6592e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   pFile = g_pPartitionFiles[nPartitionID];
6602e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley
6612e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   if (pFile == NULL)
6622e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   {
6632e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      /* The partition is not opened */
6642e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      return S_ERROR_BAD_STATE;
6652e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   }
6662e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley
6672e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   if (fseek(pFile, nSectorIndex*g_nSectorSize, SEEK_SET) != 0)
6682e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   {
6692e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      LogError("fseek error: %s", strerror(errno));
6702e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      return errno2serror();
6712e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   }
6722e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley
6732e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   if (fread(g_pWorkspaceBuffer + nWorkspaceOffset,
6742e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley             g_nSectorSize, 1,
6752e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley             pFile) != 1)
6762e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   {
6772e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      if (feof(pFile))
6782e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      {
6792e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         LogError("fread error: End-Of-File detected");
6802e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         return S_ERROR_ITEM_NOT_FOUND;
6812e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      }
6822e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      LogError("fread error: %s", strerror(errno));
6832e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      return errno2serror();
6842e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   }
6852e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley
6862e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   return S_SUCCESS;
6872e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley}
6882e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley
6892e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley/**
6902e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley * This function executes the WRITE instruction.
6912e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley *
6922e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley * @param nPartitionID: the partition identifier
6932e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley * @param nSectorIndex: the index of the sector to read
6942e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley * @param nWorkspaceOffset: the offset in the workspace where the sector must be read
6952e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley **/
6962e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckleystatic TEEC_Result partitionWrite(uint32_t nPartitionID, uint32_t nSectorIndex, uint32_t nWorkspaceOffset)
6972e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley{
6982e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   FILE* pFile;
6992e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley
7002e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   TRACE_INFO(">Partition %1X: write sector 0x%X from workspace at offset 0x%X",
7012e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      nPartitionID, nSectorIndex, nWorkspaceOffset);
7022e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley
7032e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   pFile = g_pPartitionFiles[nPartitionID];
7042e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley
7052e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   if (pFile == NULL)
7062e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   {
7072e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      /* The partition is not opened */
7082e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      return S_ERROR_BAD_STATE;
7092e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   }
7102e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley
7112e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   if (fseek(pFile, nSectorIndex*g_nSectorSize, SEEK_SET) != 0)
7122e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   {
7132e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      LogError("fseek error: %s", strerror(errno));
7142e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      return errno2serror();
7152e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   }
7162e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley
7172e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   if (fwrite(g_pWorkspaceBuffer + nWorkspaceOffset,
7182e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley              g_nSectorSize, 1,
7192e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley              pFile) != 1)
7202e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   {
7212e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      LogError("fread error: %s", strerror(errno));
7222e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      return errno2serror();
7232e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   }
7242e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   return S_SUCCESS;
7252e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley}
7262e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley
7272e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley
7282e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley/**
7292e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley * This function executes the SET_SIZE instruction.
7302e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley *
7312e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley * @param nPartitionID: the partition identifier
7322e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley * @param nNewSectorCount: the new sector count
7332e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley **/
7342e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckleystatic TEEC_Result partitionSetSize(uint32_t nPartitionID, uint32_t nNewSectorCount)
7352e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley{
7362e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   FILE* pFile;
7372e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   uint32_t nCurrentSectorCount;
7382e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley
7392e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   pFile = g_pPartitionFiles[nPartitionID];
7402e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley
7412e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   if (pFile==NULL)
7422e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   {
7432e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      /* The partition is not opened */
7442e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      return S_ERROR_BAD_STATE;
7452e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   }
7462e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley
7472e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   /* Determine the current size of the partition */
7482e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   if (fseek(pFile, 0, SEEK_END) != 0)
7492e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   {
7502e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      LogError("fseek error: %s", strerror(errno));
7512e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      return errno2serror();
7522e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   }
7532e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   nCurrentSectorCount = ftell(pFile) / g_nSectorSize;
7542e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley
7552e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   if (nNewSectorCount > nCurrentSectorCount)
7562e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   {
7572e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      uint32_t nAddedBytesCount;
7582e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      /* Enlarge the partition file. Make sure we actually write
7592e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         some non-zero data into the new sectors. Otherwise, some file-system
7602e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         might not really reserve the storage space but use a
7612e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         sparse representation. In this case, a subsequent write instruction
7622e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         could fail due to out-of-space, which we want to avoid. */
7632e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      nAddedBytesCount = (nNewSectorCount-nCurrentSectorCount)*g_nSectorSize;
7642e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      while (nAddedBytesCount)
7652e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      {
7662e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         if (fputc(0xA5, pFile)!=0xA5)
7672e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         {
7682e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley            return errno2serror();
7692e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         }
7702e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         nAddedBytesCount--;
7712e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      }
7722e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   }
7732e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   else if (nNewSectorCount < nCurrentSectorCount)
7742e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   {
7752e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      int result = 0;
7762e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      /* Truncate the partition file */
7772e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley#if defined(LINUX) || (defined __ANDROID32__)
7782e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      result = ftruncate(fileno(pFile),nNewSectorCount * g_nSectorSize);
7792e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley#endif
7802e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley#if defined (__SYMBIAN32__)
7812e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley	  LogError("No truncate available in Symbian C API");
7822e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley#endif
7832e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley#ifdef WIN32
7842e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      result = _chsize(_fileno(pFile),nNewSectorCount * g_nSectorSize);
7852e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley#endif
7862e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      if (result)
7872e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      {
7882e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         return errno2serror();
7892e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      }
7902e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   }
7912e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   return S_SUCCESS;
7922e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley}
7932e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley
7942e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley/**
7952e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley * This function executes the SYNC instruction.
7962e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley *
7972e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley * @param pPartitionID: the partition identifier
7982e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley **/
7992e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckleystatic TEEC_Result partitionSync(uint32_t nPartitionID)
8002e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley{
8012e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   TEEC_Result nError = S_SUCCESS;
8022e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   int result;
8032e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley
8042e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   FILE* pFile = g_pPartitionFiles[nPartitionID];
8052e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley
8062e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   if (pFile == NULL)
8072e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   {
8082e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      /* The partition is not currently opened */
8092e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      return S_ERROR_BAD_STATE;
8102e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   }
8112e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley
8122e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   /* First make sure that the data in the stdio buffers
8132e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      is flushed to the file descriptor */
8142e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   result=fflush(pFile);
8152e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   if (result)
8162e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   {
8172e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      nError=errno2serror();
8182e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      goto end;
8192e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   }
8202e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   /* Then synchronize the file descriptor with the file-system */
8212e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley
8222e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley#if defined(LINUX) || (defined __ANDROID32__)
8232e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   result=fdatasync(fileno(pFile));
8242e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley#endif
8252e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley#if defined (__SYMBIAN32__)
8262e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   result=fsync(fileno(pFile));
8272e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley#endif
8282e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley#ifdef WIN32
8292e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   result=_commit(_fileno(pFile));
8302e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley#endif
8312e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   if (result)
8322e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   {
8332e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      nError=errno2serror();
8342e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   }
8352e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley
8362e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckleyend:
8372e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   return nError;
8382e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley}
8392e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley
8402e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley/**
8412e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley * This function executes the NOTIFY instruction.
8422e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley *
8432e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley * @param pMessage the message string
8442e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley * @param nMessageType the type of messages
8452e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley **/
8462e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckleystatic void notify(const wchar_t* pMessage, uint32_t nMessageType)
8472e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley{
8482e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   switch (nMessageType)
8492e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   {
8502e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   case DELEGATION_NOTIFY_TYPE_ERROR:
8512e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      LogError("%ls", pMessage);
8522e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      break;
8532e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   case DELEGATION_NOTIFY_TYPE_WARNING:
8542e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      LogWarning("%ls", pMessage);
8552e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      break;
8562e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   case DELEGATION_NOTIFY_TYPE_DEBUG:
8572e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      LogInfo("DEBUG: %ls", pMessage);
8582e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      break;
8592e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   case DELEGATION_NOTIFY_TYPE_INFO:
8602e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   default:
8612e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      LogInfo("%ls", pMessage);
8622e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      break;
8632e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   }
8642e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley}
8652e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley
8662e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley/*----------------------------------------------------------------------------
8672e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley * Session main function
8682e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley *----------------------------------------------------------------------------*/
8692e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley
8702e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley/*
8712e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley * This function runs a session opened on the delegation service. It fetches
8722e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley * instructions and execute them in a loop. It never returns, but may call
8732e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley * exit when instructed to shutdown by the service
8742e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley */
8752e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckleystatic int runSession(TEEC_Context* pContext, TEEC_Session* pSession, TEEC_Operation* pOperation)
8762e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley{
8772e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   memset(&g_pExchangeBuffer->sAdministrativeData, 0x00, sizeof(g_pExchangeBuffer->sAdministrativeData));
8782e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley
8792e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   while (true)
8802e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   {
8812e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      S_RESULT    nError;
8822e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      TEEC_Result                      nTeeError;
8832e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      uint32_t                         nInstructionsIndex;
8842e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      uint32_t                         nInstructionsBufferSize = sizeof(g_pExchangeBuffer->sInstructions);
8852e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley
8862e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      pOperation->paramTypes = TEEC_PARAM_TYPES(
8872e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         TEEC_MEMREF_PARTIAL_INPUT,
8882e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         TEEC_MEMREF_PARTIAL_OUTPUT,
8892e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         TEEC_MEMREF_PARTIAL_INOUT,
8902e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         TEEC_NONE);
8912e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      pOperation->params[0].memref.parent = &sExchangeSharedMem;
8922e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      pOperation->params[0].memref.offset = offsetof(DELEGATION_EXCHANGE_BUFFER, sAdministrativeData);
8932e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      pOperation->params[0].memref.size   = sizeof(g_pExchangeBuffer->sAdministrativeData);
8942e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley
8952e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      pOperation->params[1].memref.parent = &sExchangeSharedMem;
8962e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      pOperation->params[1].memref.offset = offsetof(DELEGATION_EXCHANGE_BUFFER, sInstructions);
8972e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      pOperation->params[1].memref.size   = sizeof(g_pExchangeBuffer->sInstructions);
8982e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley
8992e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      pOperation->params[2].memref.parent = &sExchangeSharedMem;
9002e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      pOperation->params[2].memref.offset = offsetof(DELEGATION_EXCHANGE_BUFFER, sWorkspace);
9012e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      pOperation->params[2].memref.size   = g_nWorkspaceSize;
9022e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley
9032e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      nTeeError = TEEC_InvokeCommand(pSession,
9042e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley                                  SERVICE_DELEGATION_GET_INSTRUCTIONS,   /* commandID */
9052e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley                                  pOperation,     /* IN OUT operation */
9062e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley                                  NULL             /* OUT errorOrigin, optional */
9072e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley                                 );
9082e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley
9092e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      if (nTeeError != TEEC_SUCCESS)
9102e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      {
9112e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         LogError("TEEC_InvokeCommand error: 0x%08X", nTeeError);
9122e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         LogError("Daemon exits");
9132e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         exit(2);
9142e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      }
9152e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley
9162e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      if (pOperation->params[1].tmpref.size >  nInstructionsBufferSize)
9172e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      {
9182e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         /* Should not happen, probably an error from the service */
9192e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         pOperation->params[1].tmpref.size = 0;
9202e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      }
9212e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley
9222e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      /* Reset the operation results */
9232e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      nError = TEEC_SUCCESS;
9242e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      g_pExchangeBuffer->sAdministrativeData.nSyncExecuted = 0;
9252e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      memset(g_pExchangeBuffer->sAdministrativeData.nPartitionErrorStates, 0x00, sizeof(g_pExchangeBuffer->sAdministrativeData.nPartitionErrorStates));
9262e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      memset(g_pExchangeBuffer->sAdministrativeData.nPartitionOpenSizes, 0x00, sizeof(g_pExchangeBuffer->sAdministrativeData.nPartitionOpenSizes));
9272e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley
9282e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      /* Execute the instructions */
9292e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      nInstructionsIndex = 0;
9302e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      nInstructionsBufferSize = pOperation->params[1].tmpref.size;
9312e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      while (true)
9322e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      {
9332e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         DELEGATION_INSTRUCTION * pInstruction;
9342e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         uint32_t nInstructionID;
9352e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         pInstruction = (DELEGATION_INSTRUCTION *)(&g_pExchangeBuffer->sInstructions[nInstructionsIndex/4]);
9362e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         if (nInstructionsIndex + 4 <= nInstructionsBufferSize)
9372e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         {
9382e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley            nInstructionID = pInstruction->sGeneric.nInstructionID;
9392e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley            nInstructionsIndex+=4;
9402e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         }
9412e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         else
9422e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         {
9432e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley            goto instruction_parse_end;
9442e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         }
9452e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         if ((nInstructionID & 0x0F) == 0)
9462e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         {
9472e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley            /* Partition-independent instruction */
9482e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley            switch (nInstructionID)
9492e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley            {
9502e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley            case DELEGATION_INSTRUCTION_SHUTDOWN:
9512e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley               {
9522e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley                  exit(0);
9532e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley                  /* The implementation of the TF Client API will automatically
9542e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley                     destroy the context and release any associated resource */
9552e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley               }
9562e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley            case DELEGATION_INSTRUCTION_NOTIFY:
9572e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley               {
9582e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley                  /* Parse the instruction parameters */
9592e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley                  wchar_t  pMessage[100];
9602e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley                  uint32_t nMessageType;
9612e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley                  uint32_t nMessageSize;
9622e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley                  memset(pMessage, 0, 100*sizeof(wchar_t));
9632e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley
9642e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley                  if (nInstructionsIndex + 8 <= nInstructionsBufferSize)
9652e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley                  {
9662e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley                     nMessageType = pInstruction->sNotify.nMessageType;
9672e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley                     nMessageSize = pInstruction->sNotify.nMessageSize;
9682e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley                     nInstructionsIndex+=8;
9692e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley                  }
9702e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley                  else
9712e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley                  {
9722e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley                     goto instruction_parse_end;
9732e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley                  }
9742e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley                  if (nMessageSize > (99)*sizeof(wchar_t))
9752e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley                  {
9762e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley                     /* How to handle the error correctly in this case ? */
9772e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley                     goto instruction_parse_end;
9782e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley                  }
9792e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley                  if (nInstructionsIndex + nMessageSize <= nInstructionsBufferSize)
9802e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley                  {
9812e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley                     memcpy(pMessage, &pInstruction->sNotify.nMessage[0], nMessageSize);
9822e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley                     nInstructionsIndex+=nMessageSize;
9832e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley                  }
9842e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley                  else
9852e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley                  {
9862e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley                     goto instruction_parse_end;
9872e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley                  }
9882e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley                  /* Align the pInstructionsIndex on 4 bytes */
9892e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley                  nInstructionsIndex = (nInstructionsIndex+3)&~3;
9902e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley                  notify(pMessage, nMessageType);
9912e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley                  break;
9922e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley               }
9932e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley            default:
9942e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley               LogError("Unknown instruction identifier: %02X", nInstructionID);
9952e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley               nError = S_ERROR_BAD_PARAMETERS;
9962e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley               break;
9972e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley            }
9982e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         }
9992e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         else
10002e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         {
10012e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley            /* Partition-specific instruction */
10022e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley            uint32_t nPartitionID = (nInstructionID & 0xF0) >> 4;
10032e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley            if (g_pExchangeBuffer->sAdministrativeData.nPartitionErrorStates[nPartitionID] == S_SUCCESS)
10042e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley            {
10052e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley               /* Execute the instruction only if there is currently no
10062e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley                  error on the partition */
10072e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley               switch (nInstructionID & 0x0F)
10082e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley               {
10092e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley               case DELEGATION_INSTRUCTION_PARTITION_CREATE:
10102e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley                  nError = partitionCreate(nPartitionID);
10112e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley                  TRACE_INFO("INSTRUCTION: ID=0x%x pid=%d err=%d", (nInstructionID & 0x0F), nPartitionID, nError);
10122e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley                  break;
10132e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley               case DELEGATION_INSTRUCTION_PARTITION_OPEN:
10142e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley                  {
10152e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley                     uint32_t nPartitionSize = 0;
10162e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley                     nError = partitionOpen(nPartitionID, &nPartitionSize);
10172e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley                     TRACE_INFO("INSTRUCTION: ID=0x%x pid=%d pSize=%d err=%d", (nInstructionID & 0x0F), nPartitionID, nPartitionSize, nError);
10182e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley                     if (nError == S_SUCCESS)
10192e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley                     {
10202e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley                        g_pExchangeBuffer->sAdministrativeData.nPartitionOpenSizes[nPartitionID] = nPartitionSize;
10212e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley                     }
10222e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley                     break;
10232e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley                  }
10242e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley               case DELEGATION_INSTRUCTION_PARTITION_READ:
10252e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley                  {
10262e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley                     /* Parse parameters */
10272e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley                     uint32_t nSectorID;
10282e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley                     uint32_t nWorkspaceOffset;
10292e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley                     if (nInstructionsIndex + 8 <= nInstructionsBufferSize)
10302e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley                     {
10312e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley                        nSectorID        = pInstruction->sReadWrite.nSectorID;
10322e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley                        nWorkspaceOffset = pInstruction->sReadWrite.nWorkspaceOffset;
10332e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley                        nInstructionsIndex+=8;
10342e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley                     }
10352e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley                     else
10362e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley                     {
10372e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley                        goto instruction_parse_end;
10382e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley                     }
10392e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley                     nError = partitionRead(nPartitionID, nSectorID, nWorkspaceOffset);
10402e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley                     TRACE_INFO("INSTRUCTION: ID=0x%x pid=%d sid=%d woff=%d err=%d", (nInstructionID & 0x0F), nPartitionID, nSectorID, nWorkspaceOffset, nError);
10412e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley                     break;
10422e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley                  }
10432e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley               case DELEGATION_INSTRUCTION_PARTITION_WRITE:
10442e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley                  {
10452e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley                     /* Parse parameters */
10462e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley                     uint32_t nSectorID;
10472e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley                     uint32_t nWorkspaceOffset;
10482e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley                     if (nInstructionsIndex + 8 <= nInstructionsBufferSize)
10492e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley                     {
10502e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley                        nSectorID        = pInstruction->sReadWrite.nSectorID;
10512e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley                        nWorkspaceOffset = pInstruction->sReadWrite.nWorkspaceOffset;
10522e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley                        nInstructionsIndex+=8;
10532e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley                     }
10542e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley                     else
10552e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley                     {
10562e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley                        goto instruction_parse_end;
10572e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley                     }
10582e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley                     nError = partitionWrite(nPartitionID, nSectorID, nWorkspaceOffset);
10592e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley                     TRACE_INFO("INSTRUCTION: ID=0x%x pid=%d sid=%d woff=%d err=%d", (nInstructionID & 0x0F), nPartitionID, nSectorID, nWorkspaceOffset, nError);
10602e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley                     break;
10612e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley                  }
10622e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley               case DELEGATION_INSTRUCTION_PARTITION_SYNC:
10632e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley                  nError = partitionSync(nPartitionID);
10642e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley                  TRACE_INFO("INSTRUCTION: ID=0x%x pid=%d err=%d", (nInstructionID & 0x0F), nPartitionID, nError);
10652e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley                  if (nError == S_SUCCESS)
10662e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley                  {
10672e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley                     g_pExchangeBuffer->sAdministrativeData.nSyncExecuted++;
10682e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley                  }
10692e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley                  break;
10702e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley               case DELEGATION_INSTRUCTION_PARTITION_SET_SIZE:
10712e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley                  {
10722e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley                     uint32_t nNewSize;
10732e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley                     if (nInstructionsIndex + 4 <= nInstructionsBufferSize)
10742e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley                     {
10752e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley                        nNewSize = pInstruction->sSetSize.nNewSize;
10762e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley                        nInstructionsIndex+=4;
10772e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley                     }
10782e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley                     else
10792e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley                     {
10802e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley                        goto instruction_parse_end;
10812e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley                     }
10822e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley                     nError = partitionSetSize(nPartitionID, nNewSize);
10832e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley                     TRACE_INFO("INSTRUCTION: ID=0x%x pid=%d nNewSize=%d err=%d", (nInstructionID & 0x0F), nPartitionID, nNewSize, nError);
10842e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley                     break;
10852e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley                  }
10862e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley               case DELEGATION_INSTRUCTION_PARTITION_CLOSE:
10872e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley                  nError = partitionClose(nPartitionID);
10882e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley                  TRACE_INFO("INSTRUCTION: ID=0x%x pid=%d err=%d", (nInstructionID & 0x0F), nPartitionID, nError);
10892e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley                  break;
10902e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley               case DELEGATION_INSTRUCTION_PARTITION_DESTROY:
10912e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley                  nError = partitionDestroy(nPartitionID);
10922e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley                  TRACE_INFO("INSTRUCTION: ID=0x%x pid=%d err=%d", (nInstructionID & 0x0F), nPartitionID, nError);
10932e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley                  break;
10942e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley               }
10952e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley               g_pExchangeBuffer->sAdministrativeData.nPartitionErrorStates[nPartitionID] = nError;
10962e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley            }
10972e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         }
10982e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      }
10992e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckleyinstruction_parse_end:
11002e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      memset(pOperation, 0, sizeof(TEEC_Operation));
11012e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   }
11022e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley}
11032e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley
11042e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley/**
11052e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley * This function opens a new session to the delegation service.
11062e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley **/
11072e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckleystatic int createSession(TEEC_Context* pContext, TEEC_Session* pSession, TEEC_Operation* pOperation)
11082e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley{
11092e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   TEEC_Result nError;
11102e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   uint32_t nExchangeBufferSize;
11112e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley
11122e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   memset(pOperation, 0, sizeof(TEEC_Operation));
11132e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   pOperation->paramTypes = TEEC_PARAM_TYPES(
11142e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      TEEC_VALUE_OUTPUT, TEEC_NONE, TEEC_NONE, TEEC_NONE);
11152e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   nError = TEEC_OpenSession(pContext,
11162e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley                             pSession,                /* OUT session */
11172e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley                             &g_sServiceId,           /* destination UUID */
11182e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley                             TEEC_LOGIN_PRIVILEGED,   /* connectionMethod */
11192e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley                             NULL,                    /* connectionData */
11202e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley                             pOperation,              /* IN OUT operation */
11212e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley                             NULL                     /* OUT errorOrigin, optional */
11222e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley                             );
11232e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   if (nError != TEEC_SUCCESS)
11242e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   {
11252e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      LogError("Error on TEEC_OpenSession : 0x%x", nError);
11262e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      exit(2);
11272e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   }
11282e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   /* Read sector size */
11292e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   g_nSectorSize = pOperation->params[0].value.a;
11302e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   LogInfo("Sector Size: %d bytes", g_nSectorSize);
11312e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley
11322e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   /* Check sector size */
11332e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   if (!(g_nSectorSize == 512 || g_nSectorSize == 1024 || g_nSectorSize == 2048 || g_nSectorSize == 4096))
11342e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   {
11352e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      LogError("Incorrect sector size: terminating...");
11362e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      exit(2);
11372e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   }
11382e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley
11392e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   /* Check workspace size */
11402e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   if (g_nWorkspaceSize < 8 * g_nSectorSize)
11412e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   {
11422e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      g_nWorkspaceSize = 8 * g_nSectorSize;
11432e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      LogWarning("Workspace size too small, automatically set to %d bytes", g_nWorkspaceSize);
11442e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   }
11452e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   /* Compute the size of the exchange buffer */
11462e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   nExchangeBufferSize = sizeof(DELEGATION_EXCHANGE_BUFFER)-1+g_nWorkspaceSize;
11472e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   g_pExchangeBuffer  = (DELEGATION_EXCHANGE_BUFFER*)malloc(nExchangeBufferSize);
11482e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley	 if (g_pExchangeBuffer == NULL)
11492e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   {
11502e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      LogError("Cannot allocate exchange buffer of %d bytes", nExchangeBufferSize);
11512e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      LogError("Now exiting...");
11522e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      exit(2);
11532e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   }
11542e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   g_pWorkspaceBuffer = (uint8_t*)g_pExchangeBuffer->sWorkspace;
11552e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   memset(g_pExchangeBuffer, 0x00, nExchangeBufferSize);
11562e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   memset(g_pPartitionFiles,0,16*sizeof(FILE*));
11572e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley
11582e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   /* Register the exchange buffer as a shared memory block */
11592e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   sExchangeSharedMem.buffer = g_pExchangeBuffer;
11602e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   sExchangeSharedMem.size   = nExchangeBufferSize;
11612e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   sExchangeSharedMem.flags  = TEEC_MEM_INPUT | TEEC_MEM_OUTPUT;
11622e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   nError = TEEC_RegisterSharedMemory(pContext, &sExchangeSharedMem);
11632e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   if (nError != TEEC_SUCCESS)
11642e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   {
11652e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      LogError("Error on TEEC_RegisterSharedMemory : 0x%x", nError);
11662e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      free(g_pExchangeBuffer);
11672e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      exit(2);
11682e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   }
11692e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   LogInfo("Daemon now connected");
11702e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   return 0;
11712e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley}
11722e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley
11732e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley
11742e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley/*----------------------------------------------------------------------------
11752e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley * Main
11762e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley *----------------------------------------------------------------------------*/
11772e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley
11782e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley#ifdef INCLUDE_CLIENT_DELEGATION
11792e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckleyint delegation_main(int argc, char* argv[])
11802e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley#else
11812e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckleyint main(int argc, char* argv[])
11822e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley#endif
11832e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley{
11842e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   TEEC_Result    nError;
11852e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   TEEC_Context   sContext;
11862e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   TEEC_Session   sSession;
11872e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   TEEC_Operation sOperation;
11882e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   bool        debug = false;
11892e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley
11902e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley#ifndef SUPPORT_DELEGATION_EXTENSION
11912e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   char * baseDir = NULL;
11922e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley
11932e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   LogInfo("TFSW Normal-World Daemon");
11942e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley#else
11952e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   LogInfo("TFSW Normal-World Ext Daemon");
11962e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley#endif
11972e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   LogInfo(S_VERSION_STRING);
11982e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   LogInfo("");
11992e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley
12002e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   /* Skip program name */
12012e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   argv++;
12022e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   argc--;
12032e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley
12042e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   while (argc != 0)
12052e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   {
12062e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      if (strcmp(argv[0], "-d") == 0)
12072e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      {
12082e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         debug = true;
12092e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      }
12102e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley#ifdef SUPPORT_DELEGATION_EXTENSION
12112e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      else if (strcmp(argv[0], "-c") == 0)
12122e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      {
12132e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         int error;
12142e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         argc--;
12152e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         argv++;
12162e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         if (argc == 0)
12172e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         {
12182e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley            printUsage();
12192e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley            return 1;
12202e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         }
12212e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         /* Note that the function parseCommandLineExtension can modify the
12222e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley            content of the g_partitionNames array */
12232e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         error = parseCommandLineExtension(argv[0], g_pPartitionNames);
12242e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         if ( error != 0 )
12252e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         {
12262e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley            printUsage();
12272e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley            return error;
12282e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         }
12292e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      }
12302e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley#else
12312e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      else if (strcmp(argv[0], "-storageDir") == 0)
12322e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      {
12332e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         uint32_t i = 0;
12342e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         argc--;
12352e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         argv++;
12362e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         if (argc == 0)
12372e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         {
12382e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley            printUsage();
12392e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley            return 1;
12402e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         }
12412e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         if (baseDir != NULL)
12422e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         {
12432e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley            LogError("Only one storage directory may be specified");
12442e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley            return 1;
12452e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         }
12462e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         baseDir = malloc(strlen(argv[0])+1); /* Zero-terminated string */
12472e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         if (baseDir == NULL)
12482e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         {
12492e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley             LogError("Out of memory");
12502e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley             return 2;
12512e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         }
12522e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley
12532e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         strcpy(baseDir, argv[0]);
12542e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley
12552e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         /* Set default names to the partitions */
12562e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         for ( i=0; i<16 ;i++ )
12572e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         {
12582e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley            g_pPartitionNames[i] = NULL;
12592e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley            g_pPartitionNames[i] = malloc(strlen(baseDir) + 1 /* separator */ + sizeof("Store_X.tf"));
12602e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley            if (g_pPartitionNames[i] != NULL)
12612e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley            {
12622e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley               sprintf(g_pPartitionNames[i], "%s%cStore_%1X.tf", baseDir, PATH_SEPARATOR, i);
12632e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley            }
12642e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley            else
12652e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley            {
12662e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley               free(baseDir);
12672e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley               i=0;
12682e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley               while(g_pPartitionNames[i] != NULL) free(g_pPartitionNames[i++]);
12692e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley               LogError("Out of memory");
12702e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley               return 2;
12712e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley            }
12722e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         }
12732e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      }
12742e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      else if (strcmp(argv[0], "-workspaceSize") == 0)
12752e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      {
12762e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         argc--;
12772e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         argv++;
12782e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         if (argc == 0)
12792e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         {
12802e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley            printUsage();
12812e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley            return 1;
12822e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         }
12832e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         g_nWorkspaceSize=atol(argv[0]);
12842e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      }
12852e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley#endif /* ! SUPPORT_DELEGATION_EXTENSION */
12862e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      /*****************************************/
12872e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      else if (strcmp(argv[0], "--help") == 0 || strcmp(argv[0], "-h") == 0)
12882e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      {
12892e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         printUsage();
12902e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         return 0;
12912e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      }
12922e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      else
12932e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      {
12942e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         printUsage();
12952e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         return 1;
12962e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      }
12972e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      argc--;
12982e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      argv++;
12992e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   }
13002e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley
13012e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley#ifndef SUPPORT_DELEGATION_EXTENSION
13022e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   if (baseDir == NULL)
13032e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   {
13042e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      LogError("-storageDir option is mandatory");
13052e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      return 1;
13062e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   }
13072e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   else
13082e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   {
13092e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      if (static_checkStorageDirAndAccessRights(baseDir) != 0)
13102e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      {
13112e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         return 1;
13122e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      }
13132e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   }
13142e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley#endif /* #ifndef SUPPORT_DELEGATION_EXTENSION */
13152e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley
13162e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   /*
13172e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley    * Detach the daemon from the console
13182e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley    */
13192e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley
13202e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley#if defined(LINUX) || (defined __ANDROID32__)
13212e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   {
13222e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      /*
13232e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley       * Turns this application into a daemon => fork off parent process, setup logging, ...
13242e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley       */
13252e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley
13262e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      /* Our process ID and Session ID */
13272e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      pid_t pid, sid;
13282e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley
13292e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      if (!debug)
13302e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      {
13312e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         LogInfo("tf_daemon is detaching from console... Further traces go to syslog");
13322e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         /* Fork off the parent process */
13332e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         pid = fork();
13342e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         if (pid < 0)
13352e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         {
13362e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley            LogError("daemon forking failed");
13372e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley            return 1;
13382e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         }
13392e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley
13402e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         if (pid > 0)
13412e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         {
13422e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley            /* parent */
13432e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley            return 0;
13442e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         }
13452e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         bDetached = true;
13462e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      }
13472e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley
13482e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      /* Change the file mode mask */
13492e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      umask(0077);
13502e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley
13512e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      if (!debug)
13522e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      {
13532e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         /* Open any logs here */
13542e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         openlog("tf_daemon", 0, LOG_DAEMON);
13552e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley
13562e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         /* Detach from the console */
13572e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         sid = setsid();
13582e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         if (sid < 0)
13592e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         {
13602e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley            /* Log the failure */
13612e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley            LogError("daemon group creation failed");
13622e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley            return 1;
13632e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         }
13642e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         /* Close out the standard file descriptors */
13652e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         close(STDIN_FILENO);
13662e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         close(STDOUT_FILENO);
13672e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         close(STDERR_FILENO);
13682e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      }
13692e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   }
13702e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   /* Change priority so that tf_driver.ko with no polling thread is faster */
13712e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   if (setpriority(PRIO_PROCESS, 0, 19)!=0)
13722e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   {
13732e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      LogError("Daemon cannot change priority");
13742e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      return 1;
13752e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   }
13762e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley
13772e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley#endif
13782e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley
13792e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   TRACE_INFO("Sector size is %d", g_nSectorSize);
13802e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley
13812e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   LogInfo("tf_daemon - started");
13822e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley
13832e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   nError = TEEC_InitializeContext(NULL,  /* const char * name */
13842e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley                                   &sContext);   /* TEEC_Context* context */
13852e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   if (nError != TEEC_SUCCESS)
13862e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   {
13872e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      LogError("TEEC_InitializeContext error: 0x%08X", nError);
13882e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      LogError("Now exiting...");
13892e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      exit(2);
13902e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   }
13912e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley
13922e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   /* Open a session */
13932e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   if(createSession(&sContext, &sSession, &sOperation) == 0)
13942e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   {
13952e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      /* Run the session. This should never return */
13962e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      runSession(&sContext, &sSession, &sOperation);
13972e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   }
13982e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   TEEC_FinalizeContext(&sContext);
13992e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley
14002e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   return 3;
14012e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley}
1402