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   ------------------------------------------------------------------------- */
static_SSTConvertErrorCode(TEEC_Result nError)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 
static_SSTGetSession(void)72 static TEEC_Session* static_SSTGetSession(void)
73 {
74    if (g_bSSTInitialized)
75    {
76       return &g_SSTSession;
77    }
78 
79    return NULL;
80 }
81 
SSTInit(void)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 
SSTTerminate(void)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 */
static_SSTCheckFileName(const char * pName)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 
static_SSTCheckPattern(const char * pFilenamePattern)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 
SSTOpen(const char * pFilename,uint32_t nFlags,uint32_t nReserved,SST_HANDLE * phFile)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 
SSTCloseHandle(SST_HANDLE hFile)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 
SSTWrite(SST_HANDLE hFile,const uint8_t * pBuffer,uint32_t nSize)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 
SSTRead(SST_HANDLE hFile,uint8_t * pBuffer,uint32_t nSize,uint32_t * pnCount)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 
SSTSeek(SST_HANDLE hFile,int32_t nOffset,SST_WHENCE whence)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 
SSTGetOffsetAndSize(SST_HANDLE hFile,uint32_t * pnOffset,uint32_t * pnSize)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 
SSTTell(SST_HANDLE hFile,uint32_t * pnPos)488 SST_ERROR SST_EXPORT_API SSTTell(SST_HANDLE   hFile,
489                                  uint32_t*    pnPos)
490 {
491    return SSTGetOffsetAndSize(hFile, pnPos, NULL);
492 }
493 
SSTGetSize(const char * pFilename,uint32_t * pnSize)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 
SSTEof(SST_HANDLE hFile,bool * pbEof)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 
SSTCloseAndDelete(SST_HANDLE hFile)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 
SSTTruncate(SST_HANDLE hFile,uint32_t nLength)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 
SSTRename(SST_HANDLE hFile,const char * pNewFilename)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 
SSTEnumerationStart(const char * pFilenamePattern,uint32_t nReserved1,uint32_t nReserved2,SST_HANDLE * phFileEnumeration)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 
SSTEnumerationCloseHandle(SST_HANDLE hFileEnumeration)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 
SSTEnumerationGetNext(SST_HANDLE hFileEnumeration,SST_FILE_INFO ** ppFileInfo)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 
SSTDestroyFileInfo(SST_FILE_INFO * pFileInfo)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