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