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