Home | History | Annotate | Download | only in tf_crypto_sst
      1 /**
      2  * Copyright(c) 2011 Trusted Logic.   All rights reserved.
      3  *
      4  * Redistribution and use in source and binary forms, with or without
      5  * modification, are permitted provided that the following conditions
      6  * are met:
      7  *
      8  *  * Redistributions of source code must retain the above copyright
      9  *    notice, this list of conditions and the following disclaimer.
     10  *  * Redistributions in binary form must reproduce the above copyright
     11  *    notice, this list of conditions and the following disclaimer in
     12  *    the documentation and/or other materials provided with the
     13  *    distribution.
     14  *  * Neither the name Trusted Logic nor the names of its
     15  *    contributors may be used to endorse or promote products derived
     16  *    from this software without specific prior written permission.
     17  *
     18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     19  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     20  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
     21  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     22  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     23  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
     24  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     25  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     26  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     27  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     28  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     29  */
     30 
     31 #ifdef __ANDROID32__
     32 #include <stddef.h>
     33 #endif
     34 
     35 #include <stdlib.h>
     36 #include <string.h>
     37 
     38 #define SST_EXPORTS
     39 #define EXCLUDE_SERVICE_SYSTEM_SST_BASIC_TYPES
     40 #include "sst.h"
     41 
     42 /* Included for the TEE management */
     43 #include "pkcs11_internal.h"
     44 
     45 
     46 static TEEC_Session g_SSTSession;
     47 static bool g_bSSTInitialized = false;
     48 
     49 
     50 /* ------------------------------------------------------------------------
     51             TEEC -> SST error code translation
     52   ------------------------------------------------------------------------- */
     53 static SST_ERROR static_SSTConvertErrorCode(TEEC_Result nError)
     54 {
     55    switch (nError)
     56    {
     57       case TEEC_SUCCESS:
     58          return SST_SUCCESS;
     59       case SST_ERROR_BAD_PARAMETERS:
     60       case SST_ERROR_ACCESS_DENIED:
     61       case SST_ERROR_ACCESS_CONFLICT:
     62       case SST_ERROR_CORRUPTED:
     63       case SST_ERROR_NO_SPACE:
     64       case SST_ERROR_ITEM_NOT_FOUND:
     65       case SST_ERROR_OUT_OF_MEMORY:
     66       case SST_ERROR_OVERFLOW:
     67          return nError;
     68       default:
     69          return SST_ERROR_GENERIC;
     70    }
     71 }
     72 
     73 static TEEC_Session* static_SSTGetSession(void)
     74 {
     75    if (g_bSSTInitialized)
     76    {
     77       return &g_SSTSession;
     78    }
     79 
     80    return NULL;
     81 }
     82 
     83 SST_ERROR SST_EXPORT_API SSTInit(void)
     84 {
     85    TEEC_Result          nTeeError = TEEC_SUCCESS;
     86    TEEC_Operation       sOperation;
     87    uint8_t              nParamType3 = TEEC_NONE;
     88    void*                pSignatureFile = NULL;
     89    uint32_t             nSignatureFileLen = 0;
     90    uint32_t             nLoginType;
     91 
     92    stubMutexLock();
     93    if (g_bSSTInitialized)
     94    {
     95       /* SST library already initialized */
     96       nTeeError = TEEC_SUCCESS;
     97       goto end;
     98    }
     99 
    100    nTeeError = stubInitializeContext();
    101    if (nTeeError != TEEC_SUCCESS)
    102    {
    103       goto end;
    104    }
    105 
    106    /* Check if there is a signature file.
    107     * If yes, send it in param3, otherwise use LOGIN_APPLICATION
    108     */
    109    nTeeError =  TEEC_ReadSignatureFile(&pSignatureFile, &nSignatureFileLen);
    110    if (nTeeError == TEEC_ERROR_ITEM_NOT_FOUND)
    111    {
    112       nLoginType = TEEC_LOGIN_USER_APPLICATION;
    113    }
    114    else
    115    {
    116        if (nTeeError != TEEC_SUCCESS)
    117        {
    118            goto end;
    119        }
    120        sOperation.params[3].tmpref.buffer = pSignatureFile;
    121        sOperation.params[3].tmpref.size   = nSignatureFileLen;
    122        nParamType3 = TEEC_MEMREF_TEMP_INPUT;
    123        nLoginType = TEEC_LOGIN_AUTHENTICATION;
    124    }
    125 
    126    sOperation.paramTypes = TEEC_PARAM_TYPES(TEEC_NONE, TEEC_NONE, TEEC_NONE, nParamType3);
    127    nTeeError = TEEC_OpenSession(&g_sContext,
    128                              &g_SSTSession,              /* OUT session */
    129                              &SERVICE_UUID,              /* destination UUID */
    130                              nLoginType,                 /* connectionMethod */
    131                              NULL,                       /* connectionData */
    132                              &sOperation,                /* IN OUT operation */
    133                              NULL                        /* OUT returnOrigin, optional */
    134                              );
    135    if (nTeeError != TEEC_SUCCESS)
    136    {
    137       goto end_finalize_context;
    138    }
    139 
    140    g_bSSTInitialized = true;
    141    stubMutexUnlock();
    142    return SST_SUCCESS;
    143 
    144 end_finalize_context:
    145    stubFinalizeContext();
    146 end:
    147    stubMutexUnlock();
    148    return static_SSTConvertErrorCode(nTeeError);
    149 }
    150 
    151 SST_ERROR SST_EXPORT_API SSTTerminate(void)
    152 {
    153    stubMutexLock();
    154    if (g_bSSTInitialized)
    155    {
    156       TEEC_CloseSession(&g_SSTSession);
    157       stubFinalizeContext();
    158       g_bSSTInitialized = false;
    159    }
    160    /* else if not intialized => success too */
    161    stubMutexUnlock();
    162    return SST_SUCCESS;
    163 }
    164 
    165 
    166 /* ------------------------------------------------------------------------
    167                            Other API Functions
    168 ------------------------------------------------------------------------- */
    169 
    170 
    171 /* Check that the input filename is well-formed */
    172 static SST_ERROR static_SSTCheckFileName(const char* pName)
    173 {
    174    uint32_t i;
    175    char     c;
    176 
    177    if (pName == NULL)
    178    {
    179       return SST_ERROR_BAD_PARAMETERS;
    180    }
    181 
    182    for (i = 0; i <= SST_MAX_FILENAME; i++)
    183    {
    184       c = pName[i];
    185       if (c == 0)
    186       {
    187          /* End of the string */
    188          return SST_SUCCESS;
    189       }
    190 
    191       if (c == '/' || c == '\\')
    192       {
    193          /* Invalid character */
    194          return SST_ERROR_BAD_PARAMETERS;
    195       }
    196 
    197       if (c < 0x20 || c >= 0x7F)
    198       {
    199          /* Filename contains illegal characters */
    200          return SST_ERROR_BAD_PARAMETERS;
    201       }
    202    }
    203    /* Filename is too long. Zero terminator not found */
    204    return SST_ERROR_BAD_PARAMETERS;
    205 }
    206 
    207 static SST_ERROR static_SSTCheckPattern(
    208       const char* pFilenamePattern)
    209 {
    210    uint32_t i;
    211    if(pFilenamePattern == NULL)
    212    {
    213       return S_SUCCESS;
    214    }
    215 
    216    /**
    217     * Check Forbidden characters.
    218     */
    219    for (i = 0; pFilenamePattern[i] != 0; i++)
    220    {
    221       if(pFilenamePattern[i] < 0x20 )
    222       {
    223          return S_ERROR_BAD_PARAMETERS;
    224       }
    225       else if(pFilenamePattern[i] == 0x2F ) /* '/' */
    226       {
    227          return S_ERROR_BAD_PARAMETERS;
    228       }
    229       else if(pFilenamePattern[i] == 0x5C ) /* '\' */
    230       {
    231          /**
    232           * Must be directly followed by asterisk character or question-mark
    233           * character.
    234           */
    235          if (! ((pFilenamePattern[i+1] == '*' ||
    236                    pFilenamePattern[i+1] == '?')))
    237          {
    238             return S_ERROR_BAD_PARAMETERS;
    239          }
    240       }
    241       else if(pFilenamePattern[i] >= 0x7F )
    242       {
    243          return S_ERROR_BAD_PARAMETERS;
    244       }
    245    }
    246 
    247    return S_SUCCESS;
    248 }
    249 
    250 
    251 
    252 SST_ERROR SST_EXPORT_API SSTOpen(const char* pFilename,
    253                                  uint32_t    nFlags,
    254                                  uint32_t    nReserved,
    255                                  SST_HANDLE* phFile)
    256 {
    257    TEEC_Session*     pSession;
    258    TEEC_Result       nError;
    259    TEEC_Operation    sOperation;
    260    uint32_t          nReturnOrigin;
    261    SST_ERROR         nErrorCode = SST_SUCCESS;
    262 
    263    if (phFile == NULL || nReserved != 0)
    264    {
    265       return SST_ERROR_BAD_PARAMETERS;
    266    }
    267 
    268    *phFile = SST_HANDLE_INVALID;
    269 
    270    nErrorCode = static_SSTCheckFileName(pFilename);
    271    if (nErrorCode != SST_SUCCESS)
    272    {
    273       return nErrorCode;
    274    }
    275 
    276    pSession = static_SSTGetSession();
    277    if (pSession == NULL)
    278    {
    279       return SST_ERROR_GENERIC;
    280    }
    281 
    282    sOperation.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INOUT, TEEC_MEMREF_TEMP_INPUT, TEEC_NONE, TEEC_NONE);
    283    sOperation.params[0].value.a = 1;      /* Private storage */
    284    sOperation.params[0].value.b = nFlags; /* Access flags */
    285    sOperation.params[1].tmpref.buffer = (void*)pFilename;
    286    sOperation.params[1].tmpref.size   = strlen(pFilename);
    287    nError = TEEC_InvokeCommand(pSession,
    288                                SERVICE_SYSTEM_SST_OPEN_COMMAND_ID,   /* commandID */
    289                                &sOperation,                 /* IN OUT operation */
    290                                &nReturnOrigin               /* OUT returnOrigin, optional */
    291                               );
    292    if (nError == TEEC_SUCCESS)
    293    {
    294       *phFile = (SST_HANDLE)sOperation.params[0].value.a;
    295    }
    296 
    297    return static_SSTConvertErrorCode(nError);
    298 }
    299 
    300 SST_ERROR SST_EXPORT_API SSTCloseHandle(SST_HANDLE  hFile)
    301 {
    302    TEEC_Session*     pSession;
    303    TEEC_Result        nError;
    304    TEEC_Operation    sOperation;
    305    uint32_t          nReturnOrigin;
    306 
    307    if (hFile == S_HANDLE_NULL)
    308    {
    309       return SST_SUCCESS;
    310    }
    311 
    312    pSession = static_SSTGetSession();
    313    if (pSession == NULL)
    314    {
    315       return SST_ERROR_GENERIC;
    316    }
    317 
    318    sOperation.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT, TEEC_NONE, TEEC_NONE, TEEC_NONE);
    319    sOperation.params[0].value.a = hFile;
    320    nError = TEEC_InvokeCommand(pSession,
    321                                SERVICE_SYSTEM_SST_CLOSE_COMMAND_ID, /* commandID */
    322                                &sOperation,                  /* IN OUT operation */
    323                                &nReturnOrigin            /* OUT returnOrigin, optional */
    324                               );
    325 
    326    return static_SSTConvertErrorCode(nError);
    327 }
    328 
    329 SST_ERROR SST_EXPORT_API SSTWrite(SST_HANDLE       hFile,
    330                                   const uint8_t*   pBuffer,
    331                                   uint32_t         nSize)
    332 {
    333    TEEC_Session*     pSession;
    334    TEEC_Result       nError;
    335    TEEC_Operation    sOperation;
    336    uint32_t          nReturnOrigin;
    337 
    338    if (pBuffer == NULL)
    339    {
    340       return SST_ERROR_BAD_PARAMETERS;
    341    }
    342 
    343    if (nSize == 0)
    344    {
    345       return SST_SUCCESS;
    346    }
    347 
    348    pSession = static_SSTGetSession();
    349    if (pSession == NULL)
    350    {
    351       return SST_ERROR_GENERIC;
    352    }
    353 
    354    sOperation.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT, TEEC_MEMREF_TEMP_INPUT, TEEC_NONE, TEEC_NONE);
    355    sOperation.params[0].value.a       = hFile;
    356    sOperation.params[1].tmpref.buffer = (void*)pBuffer;
    357    sOperation.params[1].tmpref.size   = nSize;
    358 
    359    nError = TEEC_InvokeCommand(pSession,
    360                                SERVICE_SYSTEM_SST_WRITE_COMMAND_ID, /* commandID */
    361                                &sOperation,                  /* IN OUT operation */
    362                                &nReturnOrigin            /* OUT returnOrigin, optional */
    363                               );
    364 
    365    return static_SSTConvertErrorCode(nError);
    366 }
    367 
    368 
    369 SST_ERROR SST_EXPORT_API SSTRead(SST_HANDLE   hFile,
    370                                  uint8_t*     pBuffer,
    371                                  uint32_t     nSize,
    372                                  uint32_t*    pnCount)
    373 {
    374    TEEC_Session*     pSession;
    375    TEEC_Result       nError;
    376    TEEC_Operation    sOperation;
    377    uint32_t          nReturnOrigin;
    378 
    379    if ((pBuffer == NULL) || (pnCount == NULL))
    380    {
    381       return SST_ERROR_BAD_PARAMETERS;
    382    }
    383    *pnCount = 0;
    384 
    385    pSession = static_SSTGetSession();
    386    if (pSession == NULL)
    387    {
    388       return SST_ERROR_GENERIC;
    389    }
    390 
    391    if (nSize == 0)
    392    {
    393       return SST_SUCCESS;
    394    }
    395 
    396    sOperation.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT, TEEC_MEMREF_TEMP_OUTPUT, TEEC_NONE, TEEC_NONE);
    397    sOperation.params[0].value.a       = hFile;
    398    sOperation.params[1].tmpref.buffer = pBuffer;
    399    sOperation.params[1].tmpref.size   = nSize;
    400 
    401    nError = TEEC_InvokeCommand(pSession,
    402                                SERVICE_SYSTEM_SST_READ_COMMAND_ID, /* commandID */
    403                                &sOperation,                  /* IN OUT operation */
    404                                &nReturnOrigin            /* OUT returnOrigin, optional */
    405                               );
    406 
    407    *pnCount = sOperation.params[1].tmpref.size; /* The returned buffer size */
    408    return static_SSTConvertErrorCode(nError);
    409 }
    410 
    411 SST_ERROR SST_EXPORT_API SSTSeek(SST_HANDLE   hFile,
    412                                  int32_t     nOffset,
    413                                  SST_WHENCE   whence)
    414 {
    415    TEEC_Session*     pSession;
    416    TEEC_Result       nError;
    417    TEEC_Operation    sOperation;
    418    uint32_t          nReturnOrigin;
    419 
    420    switch(whence)
    421    {
    422    case SST_SEEK_SET:
    423    case SST_SEEK_CUR:
    424    case SST_SEEK_END:
    425       break;
    426    default:
    427       return SST_ERROR_BAD_PARAMETERS;
    428    }
    429 
    430    pSession = static_SSTGetSession();
    431    if (pSession == NULL)
    432    {
    433       return SST_ERROR_GENERIC;
    434    }
    435 
    436    sOperation.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT, TEEC_VALUE_INPUT, TEEC_NONE, TEEC_NONE);
    437    sOperation.params[0].value.a = hFile;
    438    sOperation.params[1].value.a = nOffset;
    439    sOperation.params[1].value.b = (uint32_t)whence;
    440 
    441    nError = TEEC_InvokeCommand(pSession,
    442                                SERVICE_SYSTEM_SST_SEEK_COMMAND_ID, /* commandID */
    443                                &sOperation,                  /* IN OUT operation */
    444                                &nReturnOrigin            /* OUT returnOrigin, optional */
    445                               );
    446    return static_SSTConvertErrorCode(nError);
    447 
    448 }
    449 
    450 static SST_ERROR SSTGetOffsetAndSize(SST_HANDLE   hFile, uint32_t* pnOffset, uint32_t* pnSize)
    451 {
    452    TEEC_Session*     pSession;
    453    TEEC_Result       nError;
    454    TEEC_Operation    sOperation;
    455    uint32_t          nReturnOrigin;
    456 
    457    pSession = static_SSTGetSession();
    458    if (pSession == NULL)
    459    {
    460       return SST_ERROR_GENERIC;
    461    }
    462 
    463    if (pnOffset == NULL)
    464    {
    465       return SST_ERROR_BAD_PARAMETERS;
    466    }
    467 
    468    sOperation.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INOUT, TEEC_NONE, TEEC_NONE, TEEC_NONE);
    469    sOperation.params[0].value.a = (uint32_t)hFile;
    470 
    471    nError = TEEC_InvokeCommand(pSession,
    472                                SERVICE_SYSTEM_SST_GET_OFFSET_AND_SIZE_COMMAND_ID, /* commandID */
    473                                &sOperation,                  /* IN OUT operation */
    474                                &nReturnOrigin            /* OUT returnOrigin, optional */
    475                               );
    476 
    477    if (pnOffset != NULL)
    478    {
    479       *pnOffset = sOperation.params[0].value.a;
    480    }
    481    if (pnSize != NULL)
    482    {
    483       *pnSize = sOperation.params[0].value.b;
    484    }
    485    return static_SSTConvertErrorCode(nError);
    486 
    487 }
    488 
    489 SST_ERROR SST_EXPORT_API SSTTell(SST_HANDLE   hFile,
    490                                  uint32_t*    pnPos)
    491 {
    492    return SSTGetOffsetAndSize(hFile, pnPos, NULL);
    493 }
    494 
    495 SST_ERROR SST_EXPORT_API SSTGetSize(const char*  pFilename,
    496                                     uint32_t*    pnSize)
    497 {
    498    TEEC_Session*     pSession;
    499    TEEC_Result       nError;
    500    TEEC_Operation    sOperation;
    501    uint32_t          nReturnOrigin;
    502 
    503    if ((pFilename == NULL) || (pnSize == NULL))
    504    {
    505       return SST_ERROR_BAD_PARAMETERS;
    506    }
    507 
    508    nError = static_SSTCheckFileName(pFilename);
    509    if (nError != SST_SUCCESS)
    510    {
    511       return nError;
    512    }
    513 
    514    pSession = static_SSTGetSession();
    515    if (pSession == NULL)
    516    {
    517       return SST_ERROR_GENERIC;
    518    }
    519 
    520    sOperation.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INOUT, TEEC_MEMREF_TEMP_INPUT, TEEC_NONE, TEEC_NONE);
    521    sOperation.params[0].value.a = 1; /* private storage */
    522    sOperation.params[0].value.b = 0;
    523    sOperation.params[1].tmpref.buffer = (void*)pFilename;
    524    sOperation.params[1].tmpref.size   = strlen(pFilename);
    525 
    526    nError = TEEC_InvokeCommand(pSession,
    527                                SERVICE_SYSTEM_SST_GET_SIZE_COMMAND_ID, /* commandID */
    528                                &sOperation,                  /* IN OUT operation */
    529                                &nReturnOrigin            /* OUT returnOrigin, optional */
    530                               );
    531 
    532    *pnSize = sOperation.params[0].value.a;
    533    return static_SSTConvertErrorCode(nError);
    534 }
    535 
    536 
    537 SST_ERROR SST_EXPORT_API SSTEof( SST_HANDLE   hFile,
    538                                  bool*        pbEof)
    539 {
    540    uint32_t nOffset;
    541    uint32_t nSize;
    542    SST_ERROR nError;
    543    if (pbEof == NULL)
    544       return SST_ERROR_BAD_PARAMETERS;
    545    nError = SSTGetOffsetAndSize(hFile, &nOffset, &nSize);
    546    if (nError == SST_SUCCESS)
    547    {
    548       if (nOffset >= nSize)
    549       {
    550          *pbEof = true;
    551       }
    552       else
    553       {
    554          *pbEof = false;
    555       }
    556    }
    557    return nError;
    558 }
    559 
    560 SST_ERROR SST_EXPORT_API SSTCloseAndDelete(SST_HANDLE  hFile)
    561 {
    562    TEEC_Session*     pSession;
    563    TEEC_Result       nError;
    564    TEEC_Operation    sOperation;
    565    uint32_t          nReturnOrigin;
    566 
    567    pSession = static_SSTGetSession();
    568    if (pSession == NULL)
    569    {
    570       return SST_ERROR_GENERIC;
    571    }
    572 
    573    sOperation.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT, TEEC_NONE, TEEC_NONE, TEEC_NONE);
    574    sOperation.params[0].value.a = hFile;
    575 
    576    nError = TEEC_InvokeCommand(pSession,
    577                                SERVICE_SYSTEM_SST_CLOSE_DELETE_COMMAND_ID, /* commandID */
    578                                &sOperation,                  /* IN OUT operation */
    579                                &nReturnOrigin            /* OUT returnOrigin, optional */
    580                               );
    581    return static_SSTConvertErrorCode(nError);
    582 }
    583 
    584 SST_ERROR SST_EXPORT_API SSTTruncate(SST_HANDLE hFile, uint32_t nLength)
    585 {
    586    TEEC_Session*     pSession;
    587    TEEC_Result       nError;
    588    TEEC_Operation    sOperation;
    589    uint32_t          nReturnOrigin;
    590 
    591    pSession = static_SSTGetSession();
    592    if (pSession == NULL)
    593    {
    594       return SST_ERROR_GENERIC;
    595    }
    596 
    597    sOperation.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT, TEEC_NONE, TEEC_NONE, TEEC_NONE);
    598    sOperation.params[0].value.a = hFile;
    599    sOperation.params[0].value.b = nLength;
    600 
    601    nError = TEEC_InvokeCommand(pSession,
    602                                SERVICE_SYSTEM_SST_TRUNCATE_COMMAND_ID, /* commandID */
    603                                &sOperation,                  /* IN OUT operation */
    604                                &nReturnOrigin            /* OUT returnOrigin, optional */
    605                               );
    606    return static_SSTConvertErrorCode(nError);
    607 }
    608 
    609 SST_ERROR SST_EXPORT_API SSTRename(SST_HANDLE hFile,
    610                                    const char* pNewFilename)
    611 {
    612    TEEC_Session*     pSession;
    613    TEEC_Result       nError;
    614    TEEC_Operation    sOperation;
    615    uint32_t          nReturnOrigin;
    616 
    617    pSession = static_SSTGetSession();
    618    if (pSession == NULL)
    619    {
    620       return SST_ERROR_GENERIC;
    621    }
    622 
    623    if (pNewFilename == NULL)
    624    {
    625       return SST_ERROR_BAD_PARAMETERS;
    626    }
    627 
    628    nError = static_SSTCheckFileName(pNewFilename);
    629    if (nError != SST_SUCCESS)
    630    {
    631       return nError;
    632    }
    633 
    634    sOperation.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT, TEEC_MEMREF_TEMP_INPUT, TEEC_NONE, TEEC_NONE);
    635    sOperation.params[0].value.a = hFile;
    636    sOperation.params[1].tmpref.buffer = (void*)pNewFilename;
    637    sOperation.params[1].tmpref.size   = strlen(pNewFilename);
    638 
    639    nError = TEEC_InvokeCommand(pSession,
    640                                SERVICE_SYSTEM_SST_RENAME_COMMAND_ID, /* commandID */
    641                                &sOperation,                  /* IN OUT operation */
    642                                &nReturnOrigin            /* OUT returnOrigin, optional */
    643                               );
    644       return static_SSTConvertErrorCode(nError);
    645 }
    646 
    647 SST_ERROR SST_EXPORT_API SSTEnumerationStart(const char* pFilenamePattern,
    648                                              uint32_t  nReserved1,
    649                                              uint32_t  nReserved2,
    650                                              SST_HANDLE* phFileEnumeration)
    651 {
    652    TEEC_Session*     pSession;
    653    TEEC_Result       nError;
    654    TEEC_Operation    sOperation;
    655    uint32_t          nReturnOrigin;
    656 
    657    if (nReserved1!=0 || nReserved2!=0)
    658    {
    659       return SST_ERROR_BAD_PARAMETERS;
    660    }
    661    if (phFileEnumeration==NULL)
    662    {
    663       return SST_ERROR_BAD_PARAMETERS;
    664    }
    665    *phFileEnumeration = SST_HANDLE_INVALID;
    666 
    667    nError = static_SSTCheckPattern(pFilenamePattern);
    668    if (nError != SST_SUCCESS)
    669    {
    670       return nError;
    671    }
    672 
    673    pSession = static_SSTGetSession();
    674    if (pSession == NULL)
    675    {
    676       return SST_ERROR_GENERIC;
    677    }
    678 
    679    sOperation.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INOUT, TEEC_MEMREF_TEMP_INPUT, TEEC_NONE, TEEC_NONE);
    680    sOperation.params[0].value.a = 1;      /* Private storage */
    681    sOperation.params[1].tmpref.buffer = (void*)pFilenamePattern;
    682    if (pFilenamePattern != NULL)
    683    {
    684       sOperation.params[1].tmpref.size   = strlen(pFilenamePattern);
    685    }
    686    else
    687    {
    688       sOperation.params[1].tmpref.size   = 0;
    689    }
    690 
    691    nError = TEEC_InvokeCommand(pSession,
    692                                SERVICE_SYSTEM_SST_ENUM_START_COMMAND_ID, /* commandID */
    693                                &sOperation,                  /* IN OUT operation */
    694                                &nReturnOrigin            /* OUT returnOrigin, optional */
    695                               );
    696 
    697    *phFileEnumeration = (SST_HANDLE)sOperation.params[0].value.a;
    698    return static_SSTConvertErrorCode(nError);
    699 }
    700 
    701 SST_ERROR SST_EXPORT_API SSTEnumerationCloseHandle(SST_HANDLE hFileEnumeration)
    702 {
    703    TEEC_Session*     pSession;
    704    TEEC_Result       nError;
    705    TEEC_Operation    sOperation;
    706    uint32_t          nReturnOrigin;
    707 
    708    pSession = static_SSTGetSession();
    709    if (pSession == NULL)
    710    {
    711       return SST_ERROR_GENERIC;
    712    }
    713 
    714    sOperation.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT, TEEC_NONE, TEEC_NONE, TEEC_NONE);
    715    sOperation.params[0].value.a = hFileEnumeration;
    716 
    717    nError = TEEC_InvokeCommand(pSession,
    718                                SERVICE_SYSTEM_SST_ENUM_CLOSE_COMMAND_ID, /* commandID */
    719                                &sOperation,                  /* IN OUT operation */
    720                                &nReturnOrigin                /* OUT returnOrigin, optional */
    721                               );
    722 
    723    return static_SSTConvertErrorCode(nError);
    724 }
    725 
    726 SST_ERROR SST_EXPORT_API SSTEnumerationGetNext(SST_HANDLE      hFileEnumeration,
    727                                                SST_FILE_INFO**   ppFileInfo)
    728 
    729 {
    730    TEEC_Session*     pSession;
    731    TEEC_Result       nError;
    732    TEEC_Operation    sOperation;
    733    uint32_t          nReturnOrigin;
    734    SST_FILE_INFO*    pInfo = NULL;
    735    char              sFilename[SST_MAX_FILENAME];
    736 
    737    if (ppFileInfo==NULL)
    738    {
    739       return SST_ERROR_BAD_PARAMETERS;
    740    }
    741 
    742    pSession = static_SSTGetSession();
    743    if (pSession == NULL)
    744    {
    745       return SST_ERROR_GENERIC;
    746    }
    747 
    748    sOperation.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INOUT, TEEC_MEMREF_TEMP_OUTPUT, TEEC_NONE, TEEC_NONE);
    749    sOperation.params[0].value.a = hFileEnumeration;
    750    sOperation.params[1].tmpref.buffer = sFilename;
    751    sOperation.params[1].tmpref.size   = SST_MAX_FILENAME;
    752 
    753    nError = TEEC_InvokeCommand(pSession,
    754                                SERVICE_SYSTEM_SST_ENUM_GETNEXT_COMMAND_ID, /* commandID */
    755                                &sOperation,                  /* IN OUT operation */
    756                                &nReturnOrigin            /* OUT returnOrigin, optional */
    757                               );
    758 
    759    if (nError == TEEC_SUCCESS)
    760    {
    761       if (sOperation.params[1].tmpref.size <= SST_MAX_FILENAME)
    762       {
    763          pInfo = (SST_FILE_INFO*)malloc(sizeof(SST_FILE_INFO));
    764          if (pInfo == NULL)
    765          {
    766             return SST_ERROR_OUT_OF_MEMORY;
    767          }
    768          pInfo->pName = (char*)malloc(sOperation.params[1].tmpref.size+1);
    769          if (pInfo->pName == NULL)
    770          {
    771             free(pInfo);
    772             return SST_ERROR_OUT_OF_MEMORY;
    773          }
    774          memcpy(pInfo->pName, sFilename, sOperation.params[1].tmpref.size);
    775          /* Add zero terminator */
    776          pInfo->pName[sOperation.params[1].tmpref.size] = 0;
    777          pInfo->nSize = sOperation.params[0].value.b;
    778       }
    779    }
    780   *ppFileInfo = pInfo;
    781    return static_SSTConvertErrorCode(nError);
    782  }
    783 
    784 SST_ERROR SST_EXPORT_API SSTDestroyFileInfo(SST_FILE_INFO*   pFileInfo)
    785 {
    786    TEEC_Session*  pSession;
    787 
    788    pSession = static_SSTGetSession();
    789    if (pSession == NULL)
    790    {
    791       return SST_ERROR_GENERIC;
    792    }
    793 
    794    if (pFileInfo != NULL)
    795    {
    796       free(pFileInfo->pName);
    797       free(pFileInfo);
    798    }
    799    return SST_SUCCESS;
    800 }
    801