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