mobicore: allow loading trustlets from the vendor folder
[GitHub/LineageOS/android_hardware_samsung_slsi_exynos7580.git] / mobicore / daemon / Registry / PrivateRegistry.cpp
1 /** Mobicore Driver Registry.
2 *
3 * Implements the MobiCore driver registry which maintains trustlets.
4 *
5 * @file
6 * @ingroup MCD_MCDIMPL_DAEMON_REG
7 */
8
9 /*
10 * Copyright (c) 2013 TRUSTONIC LIMITED
11 * All rights reserved.
12 *
13 * Redistribution and use in source and binary forms, with or without
14 * modification, are permitted provided that the following conditions are met:
15 *
16 * 1. Redistributions of source code must retain the above copyright notice,
17 * this list of conditions and the following disclaimer.
18 *
19 * 2. Redistributions in binary form must reproduce the above copyright
20 * notice, this list of conditions and the following disclaimer in the
21 * documentation and/or other materials provided with the distribution.
22 *
23 * 3. Neither the name of the TRUSTONIC LIMITED nor the names of its
24 * contributors may be used to endorse or promote products derived from
25 * this software without specific prior written permission.
26 *
27 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
28 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
29 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
30 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
31 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
32 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
33 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
34 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
35 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
36 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
37 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
38 */
39
40 #include <stdlib.h>
41 #include <dirent.h>
42 #include <stdio.h>
43 #include <sys/stat.h>
44 #include <assert.h>
45 #include <string.h>
46 #include <string>
47 #include <cstring>
48 #include <cstddef>
49 #include <sys/mman.h>
50 #include <errno.h>
51 #include <fcntl.h>
52 #include <libgen.h>
53
54 #include "mcLoadFormat.h"
55 #include "mcSpid.h"
56 #include "mcVersionHelper.h"
57
58 #include "PrivateRegistry.h"
59 #include "MobiCoreRegistry.h"
60
61 #include "uuid_attestation.h"
62
63 #include "log.h"
64
65 /** Maximum size of a trustlet in bytes. */
66 #define MAX_TL_SIZE (1 * 1024 * 1024)
67 /** Maximum size of a shared object container in bytes. */
68 #define MAX_SO_CONT_SIZE (512)
69
70 // Asserts expression at compile-time (to be used within a function body).
71 #define ASSERT_STATIC(e) do { enum { assert_static__ = 1 / (e) }; } while (0)
72
73 #define MC_REGISTRY_CONTAINER_PATH "/data/app/mcRegistry"
74 #define MC_REGISTRY_DEFAULT_PATH "/system/app/mcRegistry"
75 #define MC_REGISTRY_VENDOR_PATH "/vendor/app/mcRegistry"
76 #define MC_REGISTRY_FALLBACK_PATH "/data/app/mcRegistry"
77 #define AUTH_TOKEN_FILE_NAME "00000000.authtokcont"
78 #define ENV_MC_AUTH_TOKEN_PATH "MC_AUTH_TOKEN_PATH"
79 #define ROOT_FILE_NAME "00000000.rootcont"
80 #define SP_CONT_FILE_EXT ".spcont"
81 #define TL_CONT_FILE_EXT ".tlcont"
82 #define DATA_CONT_FILE_EXT ".datacont"
83 #define TL_BIN_FILE_EXT ".tlbin"
84 #define GP_TA_BIN_FILE_EXT ".tabin"
85 #define GP_TA_SPID_FILE_EXT ".spid"
86
87 using namespace std;
88
89 //------------------------------------------------------------------------------
90 static string byteArrayToString(const void *bytes, size_t elems)
91 {
92 char hx[elems * 2 + 1];
93
94 for (size_t i = 0; i < elems; i++) {
95 sprintf(&hx[i * 2], "%02x", ((uint8_t *)bytes)[i]);
96 }
97 return string(hx);
98 }
99
100 //------------------------------------------------------------------------------
101 static string uint32ToString(uint32_t value)
102 {
103 char hx[8 + 1];
104 snprintf(hx, sizeof(hx), "%08X", value);
105 string str(hx);
106 return string(str.rbegin(), str.rend());
107 }
108
109 //------------------------------------------------------------------------------
110 static bool doesDirExist(const char *path)
111 {
112 struct stat ss;
113 if (path != NULL && stat(path, &ss) == 0 && S_ISDIR(ss.st_mode)) {
114 return true;
115 }
116 return false;
117 }
118
119 //------------------------------------------------------------------------------
120 static string getRegistryPath()
121 {
122 string registryPath;
123
124 // use the default registry path.
125 registryPath = MC_REGISTRY_CONTAINER_PATH;
126 LOG_I(" Using default registry path %s", registryPath.c_str());
127
128 assert(registryPath.length() != 0);
129
130 return registryPath;
131 }
132
133 //------------------------------------------------------------------------------
134 string getTlRegistryPath()
135 {
136 string registryPath;
137
138 // First, attempt to use regular registry environment variable.
139 if (doesDirExist(MC_REGISTRY_DEFAULT_PATH)) {
140 registryPath = MC_REGISTRY_DEFAULT_PATH;
141 LOG_I(" Using MC_REGISTRY_PATH %s", registryPath.c_str());
142 } else if (doesDirExist(MC_REGISTRY_VENDOR_PATH)) {
143 // Second, attempt to use regular registry environment variable.
144 registryPath = MC_REGISTRY_VENDOR_PATH;
145 LOG_I(" Using MC_REGISTRY_VENDOR_PATH %s", registryPath.c_str());
146 } else if (doesDirExist(MC_REGISTRY_FALLBACK_PATH)) {
147 // Third, attempt to use fallback registry environment variable.
148 registryPath = MC_REGISTRY_FALLBACK_PATH;
149 LOG_I(" Using MC_REGISTRY_FALLBACK_PATH %s", registryPath.c_str());
150 }
151
152 // As a last resort, use the default registry path.
153 if (registryPath.length() == 0) {
154 registryPath = MC_REGISTRY_CONTAINER_PATH;
155 LOG_I(" Using default registry path %s", registryPath.c_str());
156 }
157
158 assert(registryPath.length() != 0);
159
160 return registryPath;
161 }
162
163 //------------------------------------------------------------------------------
164 static string getAuthTokenFilePath()
165 {
166 const char *path;
167 string authTokenPath;
168
169 // First, attempt to use regular auth token path environment variable.
170 path = getenv(ENV_MC_AUTH_TOKEN_PATH);
171 if (doesDirExist(path)) {
172 LOG_I("getAuthTokenFilePath(): Using MC_AUTH_TOKEN_PATH %s", path);
173 authTokenPath = path;
174 } else {
175 authTokenPath = getRegistryPath();
176 LOG_I("getAuthTokenFilePath(): Using path %s", authTokenPath.c_str());
177 }
178
179 return authTokenPath + "/" + AUTH_TOKEN_FILE_NAME;
180 }
181
182 //------------------------------------------------------------------------------
183 static string getRootContFilePath()
184 {
185 return getRegistryPath() + "/" + ROOT_FILE_NAME;
186 }
187
188 //------------------------------------------------------------------------------
189 static string getSpDataPath(mcSpid_t spid)
190 {
191 return getRegistryPath() + "/" + uint32ToString(spid);
192 }
193
194 //------------------------------------------------------------------------------
195 static string getSpContFilePath(mcSpid_t spid)
196 {
197 return getRegistryPath() + "/" + uint32ToString(spid) + SP_CONT_FILE_EXT;
198 }
199
200 //------------------------------------------------------------------------------
201 static string getTlContFilePath(const mcUuid_t *uuid, const mcSpid_t spid)
202 {
203 return getRegistryPath() + "/" + byteArrayToString(uuid, sizeof(*uuid))
204 + "." + uint32ToString(spid) + TL_CONT_FILE_EXT;
205 }
206
207 //------------------------------------------------------------------------------
208 static string getTlDataPath(const mcUuid_t *uuid)
209 {
210 return getRegistryPath() + "/" + byteArrayToString(uuid, sizeof(*uuid));
211 }
212
213 //------------------------------------------------------------------------------
214 static string getTlDataFilePath(const mcUuid_t *uuid, mcPid_t pid)
215 {
216 return getTlDataPath(uuid) + "/" + uint32ToString(pid.data) + DATA_CONT_FILE_EXT;
217 }
218
219 //------------------------------------------------------------------------------
220 static string getTlBinFilePath(const mcUuid_t *uuid)
221 {
222 return getTlRegistryPath() + "/" + byteArrayToString(uuid, sizeof(*uuid)) + TL_BIN_FILE_EXT;
223 }
224
225 //------------------------------------------------------------------------------
226 static string getTABinFilePath(const mcUuid_t *uuid)
227 {
228 return getTlRegistryPath() + "/" + byteArrayToString(uuid, sizeof(*uuid)) + GP_TA_BIN_FILE_EXT;
229 }
230
231 //------------------------------------------------------------------------------
232 static string getTASpidFilePath(const mcUuid_t *uuid)
233 {
234 return getTlRegistryPath() + "/" + byteArrayToString(uuid, sizeof(*uuid)) + GP_TA_SPID_FILE_EXT;
235 }
236
237 //------------------------------------------------------------------------------
238 mcResult_t mcRegistryStoreAuthToken(void *so, uint32_t size)
239 {
240 if (so == NULL || size > 3 * MAX_SO_CONT_SIZE) {
241 LOG_E("mcRegistry store So.Soc failed: %d", MC_DRV_ERR_INVALID_PARAMETER);
242 return MC_DRV_ERR_INVALID_PARAMETER;
243 }
244 const string &authTokenFilePath = getAuthTokenFilePath();
245 LOG_I("store AuthToken: %s", authTokenFilePath.c_str());
246
247 FILE *fs = fopen(authTokenFilePath.c_str(), "wb");
248 if (!fs) {
249 LOG_E("mcRegistry store So.Soc failed: %d", MC_DRV_ERR_INVALID_DEVICE_FILE);
250 return MC_DRV_ERR_INVALID_DEVICE_FILE;
251 }
252 fseek(fs, 0, SEEK_SET);
253 fwrite((char *)so, 1, size, fs);
254 fflush(fs);
255 fclose(fs);
256
257 return MC_DRV_OK;
258 }
259
260
261 //------------------------------------------------------------------------------
262 mcResult_t mcRegistryReadAuthToken(mcSoAuthTokenCont_t *so)
263 {
264 if (NULL == so) {
265 LOG_E("mcRegistry read So.Soc failed: %d", MC_DRV_ERR_INVALID_PARAMETER);
266 return MC_DRV_ERR_INVALID_PARAMETER;
267 }
268 const string &authTokenFilePath = getAuthTokenFilePath();
269 LOG_I("read AuthToken: %s", authTokenFilePath.c_str());
270
271 FILE *fs = fopen(authTokenFilePath.c_str(), "rb");
272 if (!fs) {
273 LOG_W("mcRegistry read So.Soc failed: %d", MC_DRV_ERR_INVALID_DEVICE_FILE);
274 return MC_DRV_ERR_INVALID_DEVICE_FILE;
275 }
276 fseek(fs, 0, SEEK_END);
277 int32_t filesize = ftell(fs);
278 if (sizeof(mcSoAuthTokenCont_t) != filesize) {
279 fclose(fs);
280 LOG_W("mcRegistry read So.Soc failed: %d", MC_DRV_ERR_OUT_OF_RESOURCES);
281 return MC_DRV_ERR_OUT_OF_RESOURCES;
282 }
283 fseek(fs, 0, SEEK_SET);
284 if (fread((char *)so, 1, sizeof(mcSoAuthTokenCont_t), fs) !=
285 sizeof(mcSoAuthTokenCont_t))
286 {
287 fclose(fs);
288 LOG_W("mcRegistry read So.Soc failed: %d", MC_DRV_ERR_INVALID_PARAMETER);
289 return MC_DRV_ERR_INVALID_PARAMETER;
290 }
291 fclose(fs);
292
293 return MC_DRV_OK;
294 }
295
296 //------------------------------------------------------------------------------
297 mcResult_t mcRegistryDeleteAuthToken(void)
298 {
299 if (remove(getAuthTokenFilePath().c_str())) {
300 LOG_ERRNO("Delete Auth token file!");
301 return MC_DRV_ERR_UNKNOWN;
302 } else
303 return MC_DRV_OK;
304 }
305
306
307 //------------------------------------------------------------------------------
308 mcResult_t mcRegistryStoreRoot(void *so, uint32_t size)
309 {
310 if (so == NULL || size > 3 * MAX_SO_CONT_SIZE) {
311 LOG_E("mcRegistry store So.Root failed: %d", MC_DRV_ERR_INVALID_PARAMETER);
312 return MC_DRV_ERR_INVALID_PARAMETER;
313 }
314
315 const string &rootContFilePath = getRootContFilePath();
316 LOG_I("store Root: %s", rootContFilePath.c_str());
317
318 FILE *fs = fopen(rootContFilePath.c_str(), "wb");
319 if (!fs) {
320 LOG_E("mcRegistry store So.Root failed: %d", MC_DRV_ERR_INVALID_DEVICE_FILE);
321 return MC_DRV_ERR_INVALID_DEVICE_FILE;
322 }
323 fseek(fs, 0, SEEK_SET);
324 fwrite((char *)so, 1, size, fs);
325 fflush(fs);
326 fclose(fs);
327
328 return MC_DRV_OK;
329 }
330
331
332 //------------------------------------------------------------------------------
333 mcResult_t mcRegistryReadRoot(void *so, uint32_t *size)
334 {
335 const string &rootContFilePath = getRootContFilePath();
336 size_t readBytes;
337
338 if (so == NULL) {
339 LOG_E("mcRegistry read So.Root failed: %d", MC_DRV_ERR_INVALID_PARAMETER);
340 return MC_DRV_ERR_INVALID_PARAMETER;
341 }
342 LOG_I(" Opening %s", rootContFilePath.c_str());
343
344 FILE *fs = fopen(rootContFilePath.c_str(), "rb");
345 if (!fs) {
346 LOG_W("mcRegistry read So.Root failed: %d", MC_DRV_ERR_INVALID_DEVICE_FILE);
347 return MC_DRV_ERR_INVALID_DEVICE_FILE;
348 }
349 readBytes = fread((char *)so, 1, *size, fs);
350 fclose(fs);
351
352 if (readBytes > 0) {
353 *size = readBytes;
354 return MC_DRV_OK;
355 } else {
356 LOG_E("mcRegistry read So.Root failed: %d", MC_DRV_ERR_INVALID_DEVICE_FILE);
357 return MC_DRV_ERR_INVALID_DEVICE_FILE;
358 }
359 }
360
361
362 //------------------------------------------------------------------------------
363 mcResult_t mcRegistryStoreSp(mcSpid_t spid, void *so, uint32_t size)
364 {
365 if ((spid == 0) || (so == NULL) || size > 3 * MAX_SO_CONT_SIZE) {
366 LOG_E("mcRegistry store So.Sp(SpId) failed: %d", MC_DRV_ERR_INVALID_PARAMETER);
367 return MC_DRV_ERR_INVALID_PARAMETER;
368 }
369
370 const string &spContFilePath = getSpContFilePath(spid);
371 LOG_I("store SP: %s", spContFilePath.c_str());
372
373 FILE *fs = fopen(spContFilePath.c_str(), "wb");
374 if (!fs) {
375 LOG_E("mcRegistry store So.Sp(SpId) failed: %d", MC_DRV_ERR_INVALID_DEVICE_FILE);
376 return MC_DRV_ERR_INVALID_DEVICE_FILE;
377 }
378 fseek(fs, 0, SEEK_SET);
379 fwrite((char *)so, 1, size, fs);
380 fflush(fs);
381 fclose(fs);
382
383 return MC_DRV_OK;
384 }
385
386
387 //------------------------------------------------------------------------------
388 mcResult_t mcRegistryReadSp(mcSpid_t spid, void *so, uint32_t *size)
389 {
390 const string &spContFilePath = getSpContFilePath(spid);
391 size_t readBytes;
392 if ((spid == 0) || (so == NULL)) {
393 LOG_E("mcRegistry read So.Sp(SpId=0x%x) failed", spid);
394 return MC_DRV_ERR_INVALID_PARAMETER;
395 }
396 LOG_I(" Reading %s", spContFilePath.c_str());
397
398 FILE *fs = fopen(spContFilePath.c_str(), "rb");
399 if (!fs) {
400 LOG_E("mcRegistry read So.Sp(SpId) failed: %d", MC_DRV_ERR_INVALID_DEVICE_FILE);
401 return MC_DRV_ERR_INVALID_DEVICE_FILE;
402 }
403 readBytes = fread((char *)so, 1, *size, fs);
404 fclose(fs);
405
406 if (readBytes > 0) {
407 *size = readBytes;
408 return MC_DRV_OK;
409 } else {
410 LOG_E("mcRegistry read So.Sp(SpId) failed: %d", MC_DRV_ERR_INVALID_DEVICE_FILE);
411 return MC_DRV_ERR_INVALID_DEVICE_FILE;
412 }
413 }
414
415
416 //------------------------------------------------------------------------------
417 mcResult_t mcRegistryStoreTrustletCon(const mcUuid_t *uuid, const mcSpid_t spid, void *so, uint32_t size)
418 {
419 if ((uuid == NULL) || (so == NULL) || size > 3 * MAX_SO_CONT_SIZE) {
420 LOG_E("mcRegistry store So.TrustletCont(uuid) failed: %d", MC_DRV_ERR_INVALID_PARAMETER);
421 return MC_DRV_ERR_INVALID_PARAMETER;
422 }
423
424 const string &tlContFilePath = getTlContFilePath(uuid, spid);
425 LOG_I("store TLc: %s", tlContFilePath.c_str());
426
427 FILE *fs = fopen(tlContFilePath.c_str(), "wb");
428 if (!fs) {
429 LOG_E("mcRegistry store So.TrustletCont(uuid) failed: %d", MC_DRV_ERR_INVALID_DEVICE_FILE);
430 return MC_DRV_ERR_INVALID_DEVICE_FILE;
431 }
432 fseek(fs, 0, SEEK_SET);
433 fwrite((char *)so, 1, size, fs);
434 fflush(fs);
435 fclose(fs);
436
437 return MC_DRV_OK;
438 }
439
440 static uint32_t getAsUint32BE(
441 void *pValueUnaligned
442 )
443 {
444 uint8_t *p = (uint8_t *)pValueUnaligned;
445 uint32_t val = p[3] | (p[2] << 8) | (p[1] << 16) | (p[0] << 24);
446 return val;
447 }
448
449 mcResult_t mcRegistryStoreTABlob(mcSpid_t spid, void *blob, uint32_t size)
450 {
451
452 LOG_I("mcRegistryStoreTABlob started");
453
454 // Check blob size
455 if (size < sizeof(mclfHeaderV24_t)) {
456 LOG_E("RegistryStoreTABlob failed - TA blob length is less then header size");
457 return MC_DRV_ERR_INVALID_PARAMETER;
458 }
459
460 mclfHeaderV24_t *header24 = (mclfHeaderV24_t *)blob;
461 mclfHeaderV2_t *header20 = (mclfHeaderV2_t *)blob;
462
463 // Check header version
464 if (header20->intro.version < MC_MAKE_VERSION(2, 4)) {
465 LOG_E("RegistryStoreTABlob failed - TA blob header version is less than 2.4");
466 return MC_DRV_ERR_TA_HEADER_ERROR;
467 }
468
469 //Check GP version
470 if (header24->gp_level != 1) {
471 LOG_E("RegistryStoreTABlob failed - TA blob header gp_level is not equal to 1");
472 return MC_DRV_ERR_TA_HEADER_ERROR;
473 }
474
475 TEEC_UUID uuid;
476 switch (header20->serviceType) {
477 case SERVICE_TYPE_SYSTEM_TRUSTLET: {
478 // Check spid
479 if (spid != MC_SPID_SYSTEM) {
480 LOG_E("RegistryStoreTABlob failed - SPID is not equal to %d for System TA", spid);
481 return MC_DRV_ERR_INVALID_PARAMETER;
482 }
483 memcpy(&uuid, &header20->uuid, sizeof(mcUuid_t));
484 break;
485 }
486 case SERVICE_TYPE_SP_TRUSTLET: {
487 // Check spid
488 if (spid >= MC_SPID_SYSTEM) {
489 LOG_E("RegistryStoreTABlob failed - SPID is equal to %u ", spid);
490 return MC_DRV_ERR_INVALID_PARAMETER;
491 }
492
493 uuid_attestation *pUa = (uuid_attestation *) & ((uint8_t *)blob)[header24->attestationOffset];
494 // Check attestation size
495 if ((header24->attestationOffset > size) && (header24->attestationOffset + getAsUint32BE(&pUa->size) > size)) {
496 LOG_E("RegistryStoreTABlob failed - Attestation size is not correct");
497 return MC_DRV_ERR_TA_HEADER_ERROR;
498 }
499
500 // Check attestation size
501 if (getAsUint32BE(&pUa->size) < sizeof(uuid_attestation)) {
502 LOG_E("RegistryStoreTABlob failed - Attestation size is equal to %d and is less then %d", getAsUint32BE(&pUa->size), sizeof(uuid_attestation));
503 return MC_DRV_ERR_TA_ATTESTATION_ERROR;
504 }
505
506 // Check magic word
507 if (memcmp(pUa->magic, MAGIC, AT_MAGIC_SIZE)) {
508 LOG_E("RegistryStoreTABlob failed - Attestation magic word is not correct");
509 return MC_DRV_ERR_TA_ATTESTATION_ERROR;
510 }
511
512 // Check version
513 if (getAsUint32BE(&pUa->version) != AT_VERSION) {
514 LOG_E("RegistryStoreTABlob failed - Attestation version is equal to %08X. It has to be equal to %08X", getAsUint32BE(&pUa->version), AT_VERSION);
515 return MC_DRV_ERR_TA_ATTESTATION_ERROR;
516 }
517
518 memcpy(&uuid, &pUa->uuid, sizeof(mcUuid_t));
519 break;
520 }
521 default: {
522 return MC_DRV_ERR_INVALID_PARAMETER;
523 }
524 }
525 const string tlBinFilePath = getTABinFilePath((mcUuid_t *)&uuid);
526
527 LOG_I("Store TA blob at: %s", tlBinFilePath.c_str());
528
529 FILE *fs = fopen(tlBinFilePath.c_str(), "wb");
530 if (!fs) {
531 LOG_E("RegistryStoreTABlob failed - TA blob file open error: %d", MC_DRV_ERR_INVALID_DEVICE_FILE);
532 return MC_DRV_ERR_INVALID_DEVICE_FILE;
533 }
534 fseek(fs, 0, SEEK_SET);
535 fwrite(blob, 1, size, fs);
536 fflush(fs);
537 fclose(fs);
538
539 if (header20->serviceType == SERVICE_TYPE_SP_TRUSTLET) {
540 const string taspidFilePath = getTASpidFilePath((mcUuid_t *)&uuid);
541
542 LOG_I("Store spid file at: %s", taspidFilePath.c_str());
543
544 FILE *fs = fopen(taspidFilePath.c_str(), "wb");
545 if (!fs) {
546 //TODO: shouldn't we delete TA blob file ?
547 LOG_E("RegistryStoreTABlob failed - TA blob file open error: %d", MC_DRV_ERR_INVALID_DEVICE_FILE);
548 return MC_DRV_ERR_INVALID_DEVICE_FILE;
549 }
550 fseek(fs, 0, SEEK_SET);
551 fwrite(&spid, 1, sizeof(mcSpid_t), fs);
552 fflush(fs);
553 fclose(fs);
554 }
555 return MC_DRV_OK;
556 }
557
558 //------------------------------------------------------------------------------
559 mcResult_t mcRegistryReadTrustletCon(const mcUuid_t *uuid, const mcSpid_t spid, void *so, uint32_t *size)
560 {
561 if ((uuid == NULL) || (so == NULL)) {
562 LOG_E("mcRegistry read So.TrustletCont(uuid) failed: %d", MC_DRV_ERR_INVALID_PARAMETER);
563 return MC_DRV_ERR_INVALID_PARAMETER;
564 }
565 size_t readBytes;
566 const string &tlContFilePath = getTlContFilePath(uuid, spid);
567 LOG_I("read TLc: %s", tlContFilePath.c_str());
568
569 FILE *fs = fopen(tlContFilePath.c_str(), "rb");
570 if (!fs) {
571 LOG_E("mcRegistry read So.TrustletCont(uuid) failed: %d", MC_DRV_ERR_INVALID_DEVICE_FILE);
572 return MC_DRV_ERR_INVALID_DEVICE_FILE;
573 }
574 fseek(fs, 0, SEEK_SET);
575 readBytes = fread((char *)so, 1, *size, fs);
576 fclose(fs);
577
578 if (readBytes > 0) {
579 *size = readBytes;
580 return MC_DRV_OK;
581 } else {
582 LOG_E("mcRegistry read So.TrustletCont(uuid) failed: %d", MC_DRV_ERR_INVALID_DEVICE_FILE);
583 return MC_DRV_ERR_INVALID_DEVICE_FILE;
584 }
585 }
586
587
588 //------------------------------------------------------------------------------
589 mcResult_t mcRegistryStoreData(void *so, uint32_t size)
590 {
591 mcSoDataCont_t *dataCont = (mcSoDataCont_t *)so;
592
593 if (dataCont == NULL || size != sizeof(mcSoDataCont_t)) {
594 LOG_E("mcRegistry store So.Data failed: %d", MC_DRV_ERR_INVALID_PARAMETER);
595 return MC_DRV_ERR_INVALID_PARAMETER;
596 }
597 string pathname, filename;
598
599 switch (dataCont->cont.type) {
600 case CONT_TYPE_SPDATA:
601 LOG_E("SPDATA not supported");
602 return MC_DRV_ERR_INVALID_PARAMETER;
603 break;
604 case CONT_TYPE_TLDATA:
605 pathname = getTlDataPath(&dataCont->cont.uuid);
606 filename = getTlDataFilePath(&dataCont->cont.uuid, dataCont->cont.pid);
607 break;
608 default:
609 LOG_E("mcRegistry store So.Data(cid/pid) failed: %d", MC_DRV_ERR_INVALID_PARAMETER);
610 return MC_DRV_ERR_INVALID_PARAMETER;
611 }
612 if (mkdir(pathname.c_str(), 0777) < 0)
613 {
614 LOG_E("mcRegistry store So.Data(cid/pid) failed: %d", MC_DRV_ERR_INVALID_PARAMETER);
615 return MC_DRV_ERR_INVALID_PARAMETER;
616 }
617
618 LOG_I("store DT: %s", filename.c_str());
619
620 FILE *fs = fopen(filename.c_str(), "wb");
621 if (!fs) {
622 LOG_E("mcRegistry store So.Data(cid/pid) failed: %d", MC_DRV_ERR_INVALID_DEVICE_FILE);
623 return MC_DRV_ERR_INVALID_DEVICE_FILE;
624 }
625 fseek(fs, 0, SEEK_SET);
626 fwrite((char *)dataCont, 1, MC_SO_SIZE(dataCont->soHeader.plainLen, dataCont->soHeader.encryptedLen), fs);
627 fflush(fs);
628 fclose(fs);
629
630 return MC_DRV_OK;
631 }
632
633
634 //------------------------------------------------------------------------------
635 mcResult_t mcRegistryReadData(uint32_t context, const mcCid_t *cid, mcPid_t pid __unused,
636 mcSoDataCont_t *so, uint32_t maxLen)
637 {
638
639 if ((NULL == cid) || (NULL == so)) {
640 LOG_E("mcRegistry read So.Data failed: %d", MC_DRV_ERR_INVALID_PARAMETER);
641 return MC_DRV_ERR_INVALID_PARAMETER;
642 }
643 string filename;
644 switch (context) {
645 case 0:
646 LOG_E("SPDATA not supported");
647 return MC_DRV_ERR_INVALID_PARAMETER;
648 break;
649 case 1:
650 filename = getTlDataFilePath(&so->cont.uuid, so->cont.pid);
651 break;
652 default:
653 LOG_E("mcRegistry read So.Data(cid/pid) failed: %d", MC_DRV_ERR_INVALID_PARAMETER);
654 return MC_DRV_ERR_INVALID_PARAMETER;
655 }
656 LOG_I("read DT: %s", filename.c_str());
657
658 FILE *fs = fopen(filename.c_str(), "rb");
659 if (!fs) {
660 LOG_E("mcRegistry read So.Data(cid/pid) failed: %d", MC_DRV_ERR_INVALID_DEVICE_FILE);
661 return MC_DRV_ERR_INVALID_DEVICE_FILE;
662 }
663 fseek(fs, 0, SEEK_END);
664 uint32_t filesize = ftell(fs);
665 if (maxLen < filesize) {
666 fclose(fs);
667 LOG_E("mcRegistry read So.Data(cid/pid) failed: %d", MC_DRV_ERR_OUT_OF_RESOURCES);
668 return MC_DRV_ERR_OUT_OF_RESOURCES;
669 }
670 fseek(fs, 0, SEEK_SET);
671 char *p = (char *) so;
672 if (fread(p, 1, sizeof(mcSoHeader_t), fs) != sizeof(mcSoHeader_t))
673 {
674 fclose(fs);
675 LOG_E("mcRegistry read So.Data(cid/pid) failed: %d", MC_DRV_ERR_INVALID_PARAMETER);
676 return MC_DRV_ERR_INVALID_PARAMETER;
677 }
678 p += sizeof(mcSoHeader_t);
679 if (fread(p, 1, MC_SO_SIZE(so->soHeader.plainLen,
680 so->soHeader.encryptedLen)
681 - sizeof(mcSoHeader_t), fs) !=
682 MC_SO_SIZE(so->soHeader.plainLen, so->soHeader.encryptedLen)
683 - sizeof(mcSoHeader_t))
684 {
685 fclose(fs);
686 LOG_E("mcRegistry read So.Data(cid/pid) failed: %d", MC_DRV_ERR_INVALID_PARAMETER);
687 return MC_DRV_ERR_INVALID_PARAMETER;
688 }
689 fclose(fs);
690
691 return MC_DRV_OK;
692 }
693
694
695 //------------------------------------------------------------------------------
696 static size_t getFileContent(
697 const char *pPath,
698 uint8_t **ppContent)
699 {
700 FILE *pStream;
701 long filesize;
702 uint8_t *content = NULL;
703
704 /* Open the file */
705 pStream = fopen(pPath, "rb");
706 if (pStream == NULL) {
707 LOG_E("Error: Cannot open file: %s.", pPath);
708 return 0;
709 }
710
711 if (fseek(pStream, 0L, SEEK_END) != 0) {
712 LOG_E("Error: Cannot read file: %s.", pPath);
713 goto error;
714 }
715
716 filesize = ftell(pStream);
717 if (filesize < 0) {
718 LOG_E("Error: Cannot get the file size: %s.", pPath);
719 goto error;
720 }
721
722 if (filesize == 0) {
723 LOG_E("Error: Empty file: %s.", pPath);
724 goto error;
725 }
726
727 /* Set the file pointer at the beginning of the file */
728 if (fseek(pStream, 0L, SEEK_SET) != 0) {
729 LOG_E("Error: Cannot read file: %s.", pPath);
730 goto error;
731 }
732
733 /* Allocate a buffer for the content */
734 content = (uint8_t *)malloc(filesize);
735 if (content == NULL) {
736 LOG_E("Error: Cannot read file: Out of memory.");
737 goto error;
738 }
739
740 /* Read data from the file into the buffer */
741 if (fread(content, (size_t)filesize, 1, pStream) != 1) {
742 LOG_E("Error: Cannot read file: %s.", pPath);
743 goto error;
744 }
745
746 /* Close the file */
747 fclose(pStream);
748 *ppContent = content;
749
750 /* Return number of bytes read */
751 return (size_t)filesize;
752
753 error:
754 if (content != NULL) {
755 free(content);
756 }
757 fclose(pStream);
758 return 0;
759 }
760
761 //------------------------------------------------------------------------------
762 static bool mcCheckUuid(const mcUuid_t *uuid, const char *filename)
763 {
764 uint8_t *pTAData = NULL;
765 uint32_t nTASize;
766 bool res;
767
768 nTASize = getFileContent(filename, &pTAData);
769 if (nTASize == 0) {
770 LOG_E("err: Trusted Application not found.");
771 return false;
772 }
773
774 // Check blob size
775 if (nTASize < sizeof(mclfHeaderV24_t)) {
776 free(pTAData);
777 LOG_E("RegistryStoreTABlob failed - TA blob length is less then header size");
778 return false;
779 }
780
781 mclfHeaderV2_t *header20 = (mclfHeaderV2_t *)pTAData;
782
783 // Check header version
784 if (header20->intro.version < MC_MAKE_VERSION(2, 4)) {
785 free(pTAData);
786 LOG_E("RegistryStoreTABlob failed - TA blob header version is less than 2.4");
787 return false;
788 }
789
790 // Check blob size
791 if (memcmp(uuid, &header20->uuid, sizeof(mcUuid_t)) == 0) {
792 res = true;
793 } else {
794 res = false;
795 }
796
797 free(pTAData);
798
799 return res;
800 }
801
802 //this function deletes all the files owned by a GP TA and stored in the tbase secure storage dir.
803 //then it deletes GP TA folder.
804 static int CleanupGPTAStorage(const char *basename)
805 {
806 DIR *dp;
807 struct dirent *de;
808 int e;
809 string TAPath = getTlRegistryPath()+"/TbStorage/"+ basename;
810
811 if (NULL != (dp = opendir(TAPath.c_str()))) {
812 while (NULL != (de = readdir(dp))) {
813 if (de->d_name[0] != '.') {
814 string dname = TAPath + "/" + string (de->d_name);
815 LOG_I("delete DT: %s", dname.c_str());
816 if (0 != (e = remove(dname.c_str()))) {
817 LOG_E("remove UUID-files %s failed! error: %d", dname.c_str(), e);
818 }
819 }
820 }
821 if (dp) {
822 closedir(dp);
823 }
824 LOG_I("delete dir: %s", TAPath.c_str());
825 if (0 != (e = rmdir(TAPath.c_str()))) {
826 LOG_E("remove UUID-dir failed! errno: %d", e);
827 return e;
828 }
829 }
830 return MC_DRV_OK;
831 }
832
833 static void deleteSPTA(const mcUuid_t *uuid, const mcSpid_t spid, bool checkUuid)
834 {
835 DIR *dp;
836 struct dirent *de;
837 int e;
838
839 // Delete TABIN and SPID files - we loop searching required spid file
840 string pathname = getRegistryPath();
841 if (NULL != (dp = opendir(pathname.c_str()))) {
842 while (NULL != (de = readdir(dp))) {
843 string spidFile;
844 string tabinFile;
845 string tabinUuid;
846 size_t pch_dot, pch_slash;
847 spidFile = pathname + '/' + string(de->d_name);
848 pch_dot = spidFile.find_last_of('.');
849 if (pch_dot == string::npos) continue;
850 pch_slash = spidFile.find_last_of('/');
851 if ((pch_slash != string::npos) && (pch_slash > pch_dot)) continue;
852 if (spidFile.substr(pch_dot).compare(GP_TA_SPID_FILE_EXT) != 0) continue;
853
854 mcSpid_t curSpid = 0;
855
856 int fd = open(spidFile.c_str(), O_RDONLY);
857 if (fd != -1) {
858 if (read(fd, &curSpid, sizeof(mcSpid_t))!=sizeof(mcSpid_t)) {
859 curSpid = 0;
860 }
861 close(fd);
862 }
863 if (spid == curSpid) {
864 tabinFile = spidFile.substr(0, pch_dot) + GP_TA_BIN_FILE_EXT;
865 if ((!checkUuid)||(mcCheckUuid(uuid, tabinFile.c_str()))) {
866 tabinUuid = spidFile.substr(0, pch_dot);
867 if (0 != (e = CleanupGPTAStorage(tabinUuid.c_str()))){
868 LOG_E("cleanup TA Storage dir failed! errno: %d", e);
869 //return MC_DRV_ERR_UNKNOWN;
870 }
871 if (0 != (e = remove(tabinFile.c_str()))) {
872 LOG_E("remove TA file failed! errno: %d", e);
873 //return MC_DRV_ERR_UNKNOWN;
874 }
875 if (0 != (e = remove(spidFile.c_str()))) {
876 LOG_E("remove SPID file failed! errno: %d", e);
877 //return MC_DRV_ERR_UNKNOWN;
878 }
879 if (checkUuid) break;
880 }
881 }
882 }
883 if (dp) {
884 closedir(dp);
885 }
886
887 }
888 }
889
890 //------------------------------------------------------------------------------
891 mcResult_t mcRegistryCleanupTrustlet(const mcUuid_t *uuid, const mcSpid_t spid)
892 {
893 DIR *dp;
894 struct dirent *de;
895 int e;
896
897 if (NULL == uuid) {
898 LOG_E("mcRegistry cleanupTrustlet(uuid) failed: %d", MC_DRV_ERR_INVALID_PARAMETER);
899 return MC_DRV_ERR_INVALID_PARAMETER;
900 }
901
902 // Delete all TA related data
903 string pathname = getTlDataPath(uuid);
904 if (NULL != (dp = opendir(pathname.c_str()))) {
905 while (NULL != (de = readdir(dp))) {
906 if (de->d_name[0] != '.') {
907 string dname = pathname + "/" + string (de->d_name);
908 LOG_I("delete DT: %s", dname.c_str());
909 if (0 != (e = remove(dname.c_str()))) {
910 LOG_E("remove UUID-data %s failed! error: %d", dname.c_str(), e);
911 }
912 }
913 }
914 if (dp) {
915 closedir(dp);
916 }
917 LOG_I("delete dir: %s", pathname.c_str());
918 if (0 != (e = rmdir(pathname.c_str()))) {
919 LOG_E("remove UUID-dir failed! errno: %d", e);
920 return MC_DRV_ERR_UNKNOWN;
921 }
922 }
923
924 // Delete TA binary with the name uuid.tlbin
925 string tlBinFilePath = getTlBinFilePath(uuid);
926 LOG_I("delete Tlb: %s", tlBinFilePath.c_str());
927 if (0 != (e = remove(tlBinFilePath.c_str()))) {
928 LOG_E("remove Tlb failed! errno: %d", e);
929 // return MC_DRV_ERR_UNKNOWN; // a trustlet-binary must not be present ! (registered but not usable)
930 }
931
932 // Delete TABIN and SPID files - we loop searching required spid file
933 deleteSPTA(uuid,spid,true);
934
935 string tlContFilePath = getTlContFilePath(uuid, spid);
936 LOG_I("delete Tlc: %s", tlContFilePath.c_str());
937 if (0 != (e = remove(tlContFilePath.c_str()))) {
938 LOG_E("remove Tlc failed! errno: %d", e);
939 return MC_DRV_ERR_UNKNOWN;
940 }
941 return MC_DRV_OK;
942 }
943
944
945 //------------------------------------------------------------------------------
946 mcResult_t mcRegistryCleanupSp(mcSpid_t spid)
947 {
948 DIR *dp;
949 struct dirent *de;
950 mcResult_t ret;
951 mcSoSpCont_t data;
952 uint32_t i, len;
953 int e;
954
955 if (0 == spid) {
956 LOG_E("mcRegistry cleanupSP(SpId) failed: %d", MC_DRV_ERR_INVALID_PARAMETER);
957 return MC_DRV_ERR_INVALID_PARAMETER;
958 }
959 len = sizeof(mcSoSpCont_t);
960 ret = mcRegistryReadSp(spid, &data, &len);
961 if (MC_DRV_OK != ret || len != sizeof(mcSoSpCont_t)) {
962 LOG_E("read SP->UUID aborted! Return code: %d", ret);
963 return ret;
964 }
965 for (i = 0; (i < MC_CONT_CHILDREN_COUNT) && (ret == MC_DRV_OK); i++) {
966 if (0 != strncmp((const char *) & (data.cont.children[i]), (const char *)&MC_UUID_FREE, sizeof(mcUuid_t))) {
967 ret = mcRegistryCleanupTrustlet(&(data.cont.children[i]), spid);
968 }
969 }
970 if (MC_DRV_OK != ret) {
971 LOG_E("delete SP->UUID failed! Return code: %d", ret);
972 return ret;
973 }
974
975 // Delete remaining TABIN and SPID files
976 deleteSPTA(NULL,spid,false);
977
978 string pathname = getSpDataPath(spid);
979
980 if (NULL != (dp = opendir(pathname.c_str()))) {
981 while (NULL != (de = readdir(dp))) {
982 if (de->d_name[0] != '.') {
983 string dname = pathname + "/" + string (de->d_name);
984 LOG_I("delete DT: %s", dname.c_str());
985 if (0 != (e = remove(dname.c_str()))) {
986 LOG_E("remove SPID-data %s failed! error: %d", dname.c_str(), e);
987 }
988 }
989 }
990 if (dp) {
991 closedir(dp);
992 }
993 LOG_I("delete dir: %s", pathname.c_str());
994 if (0 != (e = rmdir(pathname.c_str()))) {
995 LOG_E("remove SPID-dir failed! error: %d", e);
996 return MC_DRV_ERR_UNKNOWN;
997 }
998 }
999 string spContFilePath = getSpContFilePath(spid);
1000 LOG_I("delete Sp: %s", spContFilePath.c_str());
1001 if (0 != (e = remove(spContFilePath.c_str()))) {
1002 LOG_E("remove SP failed! error: %d", e);
1003 return MC_DRV_ERR_UNKNOWN;
1004 }
1005 return MC_DRV_OK;
1006 }
1007
1008
1009 //------------------------------------------------------------------------------
1010 mcResult_t mcRegistryCleanupRoot(void)
1011 {
1012 mcResult_t ret;
1013 mcSoRootCont_t data;
1014 uint32_t i, len;
1015 int e;
1016 len = sizeof(mcSoRootCont_t);
1017 ret = mcRegistryReadRoot(&data, &len);
1018 if (MC_DRV_OK != ret || len != sizeof(mcSoRootCont_t)) {
1019 LOG_E("read Root aborted! Return code: %d", ret);
1020 return ret;
1021 }
1022 for (i = 0; (i < MC_CONT_CHILDREN_COUNT) && (ret == MC_DRV_OK); i++) {
1023 mcSpid_t spid = data.cont.children[i];
1024 if (spid != MC_SPID_FREE) {
1025 ret = mcRegistryCleanupSp(spid);
1026 if (MC_DRV_OK != ret) {
1027 LOG_E("Cleanup SP failed! Return code: %d", ret);
1028 return ret;
1029 }
1030 }
1031 }
1032
1033 string rootContFilePath = getRootContFilePath();
1034 LOG_I("Delete root: %s", rootContFilePath.c_str());
1035 if (0 != (e = remove(rootContFilePath.c_str()))) {
1036 LOG_E("Delete root failed! error: %d", e);
1037 return MC_DRV_ERR_UNKNOWN;
1038 }
1039 return MC_DRV_OK;
1040 }
1041
1042 //------------------------------------------------------------------------------
1043 regObject_t *mcRegistryMemGetServiceBlob(mcSpid_t spid, void *trustlet, uint32_t tlSize)
1044 {
1045 regObject_t *regobj = NULL;
1046
1047 // Ensure that a UUID is provided.
1048 if (NULL == trustlet) {
1049 LOG_E("No trustlet buffer given");
1050 return NULL;
1051 }
1052
1053 // Check service blob size.
1054 if (tlSize > MAX_TL_SIZE ) {
1055 LOG_E("mcRegistryMemGetServiceBlob() failed: service blob too big: %d", tlSize);
1056 return NULL;
1057 }
1058
1059 mclfIntro_t *pIntro = (mclfIntro_t *)trustlet;
1060 // Check TL magic value.
1061 if (pIntro->magic != MC_SERVICE_HEADER_MAGIC_BE) {
1062 LOG_E("mcRegistryMemGetServiceBlob() failed: wrong header magic value: %d", pIntro->magic);
1063 return NULL;
1064 }
1065
1066 // Get service type.
1067 mclfHeaderV2_t *pHeader = (mclfHeaderV2_t *)trustlet;
1068 #ifndef NDEBUG
1069 {
1070 const char *service_types[] = {
1071 "illegal", "Driver", "Trustlet", "System Trustlet"
1072 };
1073 int serviceType_safe = pHeader->serviceType > SERVICE_TYPE_SYSTEM_TRUSTLET ? SERVICE_TYPE_ILLEGAL : pHeader->serviceType;
1074 LOG_I(" Service is a %s (service type %d)", service_types[serviceType_safe], pHeader->serviceType);
1075 }
1076 #endif
1077
1078 LOG_I(" Trustlet text %u data %u ", pHeader->text.len, pHeader->data.len);
1079
1080 // If loadable driver or system trustlet.
1081 if (pHeader->serviceType == SERVICE_TYPE_DRIVER || pHeader->serviceType == SERVICE_TYPE_SYSTEM_TRUSTLET) {
1082 // Take trustlet blob 'as is'.
1083 if (NULL == (regobj = (regObject_t *) (malloc(sizeof(regObject_t) + tlSize)))) {
1084 LOG_E("mcRegistryMemGetServiceBlob() failed: Out of memory");
1085 return NULL;
1086 }
1087 regobj->len = tlSize;
1088 regobj->tlStartOffset = 0;
1089 memcpy((char *)regobj->value, trustlet, tlSize);
1090 // If user trustlet.
1091 } else if (pHeader->serviceType == SERVICE_TYPE_SP_TRUSTLET) {
1092 // Take trustlet blob and append root, sp, and tl container.
1093 size_t regObjValueSize = tlSize + sizeof(mcBlobLenInfo_t) + 3 * MAX_SO_CONT_SIZE;
1094
1095 // Prepare registry object.
1096 if (NULL == (regobj = (regObject_t *) malloc(sizeof(regObject_t) + regObjValueSize))) {
1097 LOG_E("mcRegistryMemGetServiceBlob() failed: Out of memory");
1098 return NULL;
1099 }
1100 regobj->len = regObjValueSize;
1101 regobj->tlStartOffset = sizeof(mcBlobLenInfo_t);
1102 uint8_t *p = regobj->value;
1103
1104 // Reserve space for the blob length structure
1105 mcBlobLenInfo_ptr lenInfo = (mcBlobLenInfo_ptr)p;
1106 lenInfo->magic = MC_TLBLOBLEN_MAGIC;
1107 p += sizeof(mcBlobLenInfo_t);
1108 // Fill in trustlet blob after the len info
1109 memcpy(p, trustlet, tlSize);
1110 p += tlSize;
1111
1112 // Final registry object value looks like this:
1113 //
1114 // +---------------+---------------------------+-----------+---------+---------+
1115 // | Blob Len Info | TL-Header TL-Code TL-Data | Root Cont | SP Cont | TL Cont |
1116 // +---------------+---------------------------+-----------+-------------------+
1117 // /------ Trustlet BLOB ------/
1118 //
1119 // /------------------ regobj->header.len -------------------------------------/
1120
1121 // start at the end of the trustlet blob
1122 mcResult_t ret;
1123 do {
1124 uint32_t soTltContSize = MAX_SO_CONT_SIZE;
1125 uint32_t len;
1126
1127 // Fill in root container.
1128 len = sizeof(mcSoRootCont_t);
1129 if (MC_DRV_OK != (ret = mcRegistryReadRoot(p, &len))) {
1130 break;
1131 }
1132 lenInfo->rootContBlobSize = len;
1133 p += len;
1134
1135 // Fill in SP container.
1136 len = sizeof(mcSoSpCont_t);
1137 if (MC_DRV_OK != (ret = mcRegistryReadSp(spid, p, &len))) {
1138 break;
1139 }
1140 lenInfo->spContBlobSize = len;
1141 p += len;
1142
1143 // Fill in TLT Container
1144 // We know exactly how much space is left in the buffer
1145 soTltContSize = regObjValueSize - tlSize + sizeof(mcBlobLenInfo_t)
1146 - lenInfo->spContBlobSize - lenInfo->rootContBlobSize;
1147 if (MC_DRV_OK != (ret = mcRegistryReadTrustletCon(&pHeader->uuid, spid, p, &soTltContSize))) {
1148 break;
1149 }
1150 lenInfo->tlContBlobSize = soTltContSize;
1151 LOG_I(" Trustlet container %u bytes loaded", soTltContSize);
1152 // Depending on the trustlet container size we decide which structure to use
1153 // Unfortunate design but it should have to do for now
1154 if (soTltContSize == sizeof(mcSoTltCont_2_0_t)) {
1155 LOG_I(" Using 2.0 trustlet container");
1156 } else if (soTltContSize == sizeof(mcSoTltCont_2_1_t)) {
1157 LOG_I(" Using 2.1 trustlet container");
1158 } else {
1159 LOG_E("Trustlet container has unknown size");
1160 break;
1161 }
1162 } while (false);
1163
1164 if (MC_DRV_OK != ret) {
1165 LOG_E("mcRegistryMemGetServiceBlob() failed: Error code: %d", ret);
1166 free(regobj);
1167 return NULL;
1168 }
1169 // Now we know the sizes for all containers so set the correct size
1170 regobj->len = sizeof(mcBlobLenInfo_t) + tlSize +
1171 lenInfo->rootContBlobSize +
1172 lenInfo->spContBlobSize +
1173 lenInfo->tlContBlobSize;
1174 // Any other service type.
1175 } else {
1176 LOG_E("mcRegistryMemGetServiceBlob() failed: Unsupported service type %u", pHeader->serviceType);
1177 }
1178 return regobj;
1179 }
1180
1181
1182 //------------------------------------------------------------------------------
1183 regObject_t *mcRegistryFileGetServiceBlob(const char *trustlet, mcSpid_t spid)
1184 {
1185 struct stat sb;
1186 regObject_t *regobj = NULL;
1187 void *buffer;
1188
1189 // Ensure that a file name is provided.
1190 if (trustlet == NULL) {
1191 LOG_E("No file given");
1192 return NULL;
1193 }
1194
1195 int fd = open(trustlet, O_RDONLY);
1196 if (fd == -1) {
1197 LOG_E("Cannot open %s", trustlet);
1198 return NULL;
1199 }
1200
1201 if (fstat(fd, &sb) == -1) {
1202 LOG_E("mcRegistryFileGetServiceBlob() failed: Cound't get file size");
1203 goto error;
1204 }
1205
1206 buffer = mmap(NULL, sb.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
1207 if (buffer == MAP_FAILED) {
1208 LOG_E("mcRegistryFileGetServiceBlob(): Failed to map file to memory");
1209 goto error;
1210 }
1211
1212 regobj = mcRegistryMemGetServiceBlob(spid, buffer, sb.st_size);
1213
1214 // We don't actually care if either of them fails but should still print warnings
1215 if (munmap(buffer, sb.st_size)) {
1216 LOG_E("mcRegistryFileGetServiceBlob(): Failed to unmap memory");
1217 }
1218
1219 error:
1220 if (close(fd)) {
1221 LOG_E("mcRegistryFileGetServiceBlob(): Failed to close file %s", trustlet);
1222 }
1223
1224 return regobj;
1225 }
1226
1227
1228 //------------------------------------------------------------------------------
1229 regObject_t *mcRegistryGetServiceBlob(const mcUuid_t *uuid, bool isGpUuid)
1230 {
1231 // Ensure that a UUID is provided.
1232 if (NULL == uuid) {
1233 LOG_E("No UUID given");
1234 return NULL;
1235 }
1236
1237 // Open service blob file.
1238 string tlBinFilePath;
1239 if (isGpUuid) {
1240 tlBinFilePath = getTABinFilePath(uuid);
1241 } else {
1242 tlBinFilePath = getTlBinFilePath(uuid);
1243 }
1244 LOG_I("Loading %s", tlBinFilePath.c_str());
1245
1246 mcSpid_t spid = 0;
1247 if (isGpUuid) {
1248 string taspidFilePath = getTASpidFilePath(uuid);
1249 int fd = open(taspidFilePath.c_str(), O_RDONLY);
1250 if (fd == -1) {
1251 // This can be ok for System TAs
1252 //LOG_ERRNO("open");
1253 //LOG_E("Cannot open %s", taspidFilePath.c_str());
1254 //return NULL;
1255 } else {
1256 if (read(fd, &spid, sizeof(mcSpid_t))!=sizeof(mcSpid_t)) {
1257 close(fd);
1258 return NULL;
1259 }
1260 close(fd);
1261 }
1262 }
1263
1264 return mcRegistryFileGetServiceBlob(tlBinFilePath.c_str(), spid);
1265 }
1266
1267 //------------------------------------------------------------------------------
1268 regObject_t *mcRegistryGetDriverBlob(const char *filename)
1269 {
1270 regObject_t *regobj = mcRegistryFileGetServiceBlob(filename, 0);
1271
1272 if (regobj == NULL) {
1273 LOG_E("mcRegistryGetDriverBlob() failed");
1274 return NULL;
1275 }
1276
1277 // Get service type.
1278 mclfHeaderV2_t *pHeader = (mclfHeaderV2_t *)regobj->value;
1279
1280 // If file is not a driver we are not interested
1281 if (pHeader->serviceType != SERVICE_TYPE_DRIVER) {
1282 LOG_E("mcRegistryGetDriverBlob() failed: Unsupported service type %u", pHeader->serviceType);
1283 pHeader = NULL;
1284 free(regobj);
1285 regobj = NULL;
1286 }
1287
1288 return regobj;
1289 }
1290
1291 /** @} */