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