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