mobicore: allow loading trustlets from the vendor folder
[GitHub/LineageOS/android_hardware_samsung_slsi_exynos7580.git] / mobicore / daemon / Registry / PrivateRegistry.cpp
CommitLineData
15e8442f
JA
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
cd9434cc 9/*
15e8442f 10 * Copyright (c) 2013 TRUSTONIC LIMITED
cd9434cc
T
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 */
15e8442f 39
cd9434cc 40#include <stdlib.h>
cd9434cc
T
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"
15e8442f 59#include "MobiCoreRegistry.h"
cd9434cc 60
cd9434cc
T
61#include "uuid_attestation.h"
62
15e8442f 63#include "log.h"
cd9434cc 64
15e8442f
JA
65/** Maximum size of a trustlet in bytes. */
66#define MAX_TL_SIZE (1 * 1024 * 1024)
cd9434cc
T
67/** Maximum size of a shared object container in bytes. */
68#define MAX_SO_CONT_SIZE (512)
69
15e8442f
JA
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)
cd9434cc 72
15e8442f
JA
73#define MC_REGISTRY_CONTAINER_PATH "/data/app/mcRegistry"
74#define MC_REGISTRY_DEFAULT_PATH "/system/app/mcRegistry"
e586d28c 75#define MC_REGISTRY_VENDOR_PATH "/vendor/app/mcRegistry"
15e8442f 76#define MC_REGISTRY_FALLBACK_PATH "/data/app/mcRegistry"
cd9434cc 77#define AUTH_TOKEN_FILE_NAME "00000000.authtokcont"
cd9434cc
T
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
15e8442f 87using namespace std;
cd9434cc
T
88
89//------------------------------------------------------------------------------
15e8442f 90static string byteArrayToString(const void *bytes, size_t elems)
cd9434cc 91{
cd9434cc
T
92 char hx[elems * 2 + 1];
93
94 for (size_t i = 0; i < elems; i++) {
15e8442f 95 sprintf(&hx[i * 2], "%02x", ((uint8_t *)bytes)[i]);
cd9434cc 96 }
15e8442f 97 return string(hx);
cd9434cc
T
98}
99
100//------------------------------------------------------------------------------
15e8442f 101static string uint32ToString(uint32_t value)
cd9434cc
T
102{
103 char hx[8 + 1];
104 snprintf(hx, sizeof(hx), "%08X", value);
15e8442f
JA
105 string str(hx);
106 return string(str.rbegin(), str.rend());
cd9434cc
T
107}
108
109//------------------------------------------------------------------------------
15e8442f 110static bool doesDirExist(const char *path)
cd9434cc
T
111{
112 struct stat ss;
15e8442f
JA
113 if (path != NULL && stat(path, &ss) == 0 && S_ISDIR(ss.st_mode)) {
114 return true;
115 }
116 return false;
117}
118
119//------------------------------------------------------------------------------
120static 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());
cd9434cc 127
15e8442f
JA
128 assert(registryPath.length() != 0);
129
130 return registryPath;
cd9434cc
T
131}
132
133//------------------------------------------------------------------------------
15e8442f 134string getTlRegistryPath()
cd9434cc 135{
15e8442f
JA
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());
e586d28c
DW
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());
15e8442f 146 } else if (doesDirExist(MC_REGISTRY_FALLBACK_PATH)) {
e586d28c 147 // Third, attempt to use fallback registry environment variable.
15e8442f
JA
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;
cd9434cc
T
161}
162
163//------------------------------------------------------------------------------
15e8442f 164static string getAuthTokenFilePath()
cd9434cc
T
165{
166 const char *path;
15e8442f 167 string authTokenPath;
cd9434cc
T
168
169 // First, attempt to use regular auth token path environment variable.
170 path = getenv(ENV_MC_AUTH_TOKEN_PATH);
15e8442f
JA
171 if (doesDirExist(path)) {
172 LOG_I("getAuthTokenFilePath(): Using MC_AUTH_TOKEN_PATH %s", path);
cd9434cc
T
173 authTokenPath = path;
174 } else {
15e8442f
JA
175 authTokenPath = getRegistryPath();
176 LOG_I("getAuthTokenFilePath(): Using path %s", authTokenPath.c_str());
cd9434cc
T
177 }
178
179 return authTokenPath + "/" + AUTH_TOKEN_FILE_NAME;
180}
181
182//------------------------------------------------------------------------------
15e8442f 183static string getRootContFilePath()
cd9434cc 184{
15e8442f 185 return getRegistryPath() + "/" + ROOT_FILE_NAME;
cd9434cc
T
186}
187
188//------------------------------------------------------------------------------
15e8442f 189static string getSpDataPath(mcSpid_t spid)
cd9434cc 190{
15e8442f 191 return getRegistryPath() + "/" + uint32ToString(spid);
cd9434cc
T
192}
193
194//------------------------------------------------------------------------------
15e8442f 195static string getSpContFilePath(mcSpid_t spid)
cd9434cc 196{
15e8442f 197 return getRegistryPath() + "/" + uint32ToString(spid) + SP_CONT_FILE_EXT;
cd9434cc
T
198}
199
200//------------------------------------------------------------------------------
15e8442f 201static string getTlContFilePath(const mcUuid_t *uuid, const mcSpid_t spid)
cd9434cc 202{
15e8442f 203 return getRegistryPath() + "/" + byteArrayToString(uuid, sizeof(*uuid))
cd9434cc
T
204 + "." + uint32ToString(spid) + TL_CONT_FILE_EXT;
205}
206
207//------------------------------------------------------------------------------
15e8442f 208static string getTlDataPath(const mcUuid_t *uuid)
cd9434cc 209{
15e8442f 210 return getRegistryPath() + "/" + byteArrayToString(uuid, sizeof(*uuid));
cd9434cc
T
211}
212
213//------------------------------------------------------------------------------
15e8442f 214static string getTlDataFilePath(const mcUuid_t *uuid, mcPid_t pid)
cd9434cc
T
215{
216 return getTlDataPath(uuid) + "/" + uint32ToString(pid.data) + DATA_CONT_FILE_EXT;
217}
218
219//------------------------------------------------------------------------------
15e8442f 220static string getTlBinFilePath(const mcUuid_t *uuid)
cd9434cc 221{
15e8442f 222 return getTlRegistryPath() + "/" + byteArrayToString(uuid, sizeof(*uuid)) + TL_BIN_FILE_EXT;
cd9434cc
T
223}
224
225//------------------------------------------------------------------------------
15e8442f 226static string getTABinFilePath(const mcUuid_t *uuid)
cd9434cc 227{
15e8442f 228 return getTlRegistryPath() + "/" + byteArrayToString(uuid, sizeof(*uuid)) + GP_TA_BIN_FILE_EXT;
cd9434cc
T
229}
230
231//------------------------------------------------------------------------------
15e8442f 232static string getTASpidFilePath(const mcUuid_t *uuid)
cd9434cc 233{
15e8442f 234 return getTlRegistryPath() + "/" + byteArrayToString(uuid, sizeof(*uuid)) + GP_TA_SPID_FILE_EXT;
cd9434cc
T
235}
236
237//------------------------------------------------------------------------------
15e8442f 238mcResult_t mcRegistryStoreAuthToken(void *so, uint32_t size)
cd9434cc 239{
cd9434cc
T
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 }
15e8442f
JA
244 const string &authTokenFilePath = getAuthTokenFilePath();
245 LOG_I("store AuthToken: %s", authTokenFilePath.c_str());
cd9434cc 246
cd9434cc 247 FILE *fs = fopen(authTokenFilePath.c_str(), "wb");
15e8442f
JA
248 if (!fs) {
249 LOG_E("mcRegistry store So.Soc failed: %d", MC_DRV_ERR_INVALID_DEVICE_FILE);
cd9434cc
T
250 return MC_DRV_ERR_INVALID_DEVICE_FILE;
251 }
15e8442f
JA
252 fseek(fs, 0, SEEK_SET);
253 fwrite((char *)so, 1, size, fs);
254 fflush(fs);
cd9434cc
T
255 fclose(fs);
256
257 return MC_DRV_OK;
258}
259
15e8442f 260
cd9434cc 261//------------------------------------------------------------------------------
15e8442f 262mcResult_t mcRegistryReadAuthToken(mcSoAuthTokenCont_t *so)
cd9434cc 263{
cd9434cc
T
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 }
15e8442f
JA
268 const string &authTokenFilePath = getAuthTokenFilePath();
269 LOG_I("read AuthToken: %s", authTokenFilePath.c_str());
cd9434cc
T
270
271 FILE *fs = fopen(authTokenFilePath.c_str(), "rb");
15e8442f 272 if (!fs) {
cd9434cc
T
273 LOG_W("mcRegistry read So.Soc failed: %d", MC_DRV_ERR_INVALID_DEVICE_FILE);
274 return MC_DRV_ERR_INVALID_DEVICE_FILE;
275 }
15e8442f
JA
276 fseek(fs, 0, SEEK_END);
277 int32_t filesize = ftell(fs);
cd9434cc
T
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 }
15e8442f
JA
283 fseek(fs, 0, SEEK_SET);
284 if (fread((char *)so, 1, sizeof(mcSoAuthTokenCont_t), fs) !=
285 sizeof(mcSoAuthTokenCont_t))
286 {
cd9434cc 287 fclose(fs);
15e8442f 288 LOG_W("mcRegistry read So.Soc failed: %d", MC_DRV_ERR_INVALID_PARAMETER);
cd9434cc
T
289 return MC_DRV_ERR_INVALID_PARAMETER;
290 }
291 fclose(fs);
292
293 return MC_DRV_OK;
294}
295
296//------------------------------------------------------------------------------
297mcResult_t mcRegistryDeleteAuthToken(void)
298{
15e8442f
JA
299 if (remove(getAuthTokenFilePath().c_str())) {
300 LOG_ERRNO("Delete Auth token file!");
cd9434cc
T
301 return MC_DRV_ERR_UNKNOWN;
302 } else
303 return MC_DRV_OK;
304}
305
306
307//------------------------------------------------------------------------------
15e8442f 308mcResult_t mcRegistryStoreRoot(void *so, uint32_t size)
cd9434cc 309{
cd9434cc
T
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
15e8442f
JA
315 const string &rootContFilePath = getRootContFilePath();
316 LOG_I("store Root: %s", rootContFilePath.c_str());
cd9434cc
T
317
318 FILE *fs = fopen(rootContFilePath.c_str(), "wb");
15e8442f 319 if (!fs) {
cd9434cc
T
320 LOG_E("mcRegistry store So.Root failed: %d", MC_DRV_ERR_INVALID_DEVICE_FILE);
321 return MC_DRV_ERR_INVALID_DEVICE_FILE;
322 }
15e8442f
JA
323 fseek(fs, 0, SEEK_SET);
324 fwrite((char *)so, 1, size, fs);
cd9434cc
T
325 fflush(fs);
326 fclose(fs);
327
328 return MC_DRV_OK;
329}
330
331
332//------------------------------------------------------------------------------
333mcResult_t mcRegistryReadRoot(void *so, uint32_t *size)
334{
15e8442f 335 const string &rootContFilePath = getRootContFilePath();
cd9434cc
T
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 }
15e8442f 342 LOG_I(" Opening %s", rootContFilePath.c_str());
cd9434cc
T
343
344 FILE *fs = fopen(rootContFilePath.c_str(), "rb");
15e8442f 345 if (!fs) {
cd9434cc
T
346 LOG_W("mcRegistry read So.Root failed: %d", MC_DRV_ERR_INVALID_DEVICE_FILE);
347 return MC_DRV_ERR_INVALID_DEVICE_FILE;
348 }
15e8442f 349 readBytes = fread((char *)so, 1, *size, fs);
cd9434cc
T
350 fclose(fs);
351
352 if (readBytes > 0) {
15e8442f 353 *size = readBytes;
cd9434cc
T
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//------------------------------------------------------------------------------
15e8442f 363mcResult_t mcRegistryStoreSp(mcSpid_t spid, void *so, uint32_t size)
cd9434cc 364{
cd9434cc
T
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
15e8442f
JA
370 const string &spContFilePath = getSpContFilePath(spid);
371 LOG_I("store SP: %s", spContFilePath.c_str());
cd9434cc
T
372
373 FILE *fs = fopen(spContFilePath.c_str(), "wb");
15e8442f 374 if (!fs) {
cd9434cc
T
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 }
15e8442f
JA
378 fseek(fs, 0, SEEK_SET);
379 fwrite((char *)so, 1, size, fs);
cd9434cc
T
380 fflush(fs);
381 fclose(fs);
382
383 return MC_DRV_OK;
384}
385
386
387//------------------------------------------------------------------------------
388mcResult_t mcRegistryReadSp(mcSpid_t spid, void *so, uint32_t *size)
389{
15e8442f 390 const string &spContFilePath = getSpContFilePath(spid);
cd9434cc
T
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 }
15e8442f 396 LOG_I(" Reading %s", spContFilePath.c_str());
cd9434cc
T
397
398 FILE *fs = fopen(spContFilePath.c_str(), "rb");
15e8442f 399 if (!fs) {
cd9434cc
T
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 }
15e8442f 403 readBytes = fread((char *)so, 1, *size, fs);
cd9434cc
T
404 fclose(fs);
405
406 if (readBytes > 0) {
15e8442f 407 *size = readBytes;
cd9434cc
T
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//------------------------------------------------------------------------------
15e8442f 417mcResult_t mcRegistryStoreTrustletCon(const mcUuid_t *uuid, const mcSpid_t spid, void *so, uint32_t size)
cd9434cc 418{
cd9434cc
T
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
15e8442f
JA
424 const string &tlContFilePath = getTlContFilePath(uuid, spid);
425 LOG_I("store TLc: %s", tlContFilePath.c_str());
cd9434cc
T
426
427 FILE *fs = fopen(tlContFilePath.c_str(), "wb");
15e8442f 428 if (!fs) {
cd9434cc
T
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 }
15e8442f
JA
432 fseek(fs, 0, SEEK_SET);
433 fwrite((char *)so, 1, size, fs);
cd9434cc
T
434 fflush(fs);
435 fclose(fs);
436
437 return MC_DRV_OK;
438}
439
440static uint32_t getAsUint32BE(
15e8442f 441 void *pValueUnaligned
cd9434cc
T
442)
443{
15e8442f 444 uint8_t *p = (uint8_t *)pValueUnaligned;
cd9434cc
T
445 uint32_t val = p[3] | (p[2] << 8) | (p[1] << 16) | (p[0] << 24);
446 return val;
447}
448
15e8442f 449mcResult_t mcRegistryStoreTABlob(mcSpid_t spid, void *blob, uint32_t size)
cd9434cc 450{
15e8442f
JA
451
452 LOG_I("mcRegistryStoreTABlob started");
cd9434cc
T
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
15e8442f
JA
460 mclfHeaderV24_t *header24 = (mclfHeaderV24_t *)blob;
461 mclfHeaderV2_t *header20 = (mclfHeaderV2_t *)blob;
cd9434cc
T
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
15e8442f 475 TEEC_UUID uuid;
cd9434cc
T
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
15e8442f 493 uuid_attestation *pUa = (uuid_attestation *) & ((uint8_t *)blob)[header24->attestationOffset];
cd9434cc
T
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)) {
15e8442f 502 LOG_E("RegistryStoreTABlob failed - Attestation size is equal to %d and is less then %d", getAsUint32BE(&pUa->size), sizeof(uuid_attestation));
cd9434cc
T
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 }
15e8442f 525 const string tlBinFilePath = getTABinFilePath((mcUuid_t *)&uuid);
cd9434cc 526
15e8442f 527 LOG_I("Store TA blob at: %s", tlBinFilePath.c_str());
cd9434cc 528
15e8442f
JA
529 FILE *fs = fopen(tlBinFilePath.c_str(), "wb");
530 if (!fs) {
cd9434cc
T
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 }
15e8442f 534 fseek(fs, 0, SEEK_SET);
cd9434cc 535 fwrite(blob, 1, size, fs);
cd9434cc
T
536 fflush(fs);
537 fclose(fs);
538
539 if (header20->serviceType == SERVICE_TYPE_SP_TRUSTLET) {
15e8442f 540 const string taspidFilePath = getTASpidFilePath((mcUuid_t *)&uuid);
cd9434cc 541
15e8442f 542 LOG_I("Store spid file at: %s", taspidFilePath.c_str());
cd9434cc
T
543
544 FILE *fs = fopen(taspidFilePath.c_str(), "wb");
15e8442f
JA
545 if (!fs) {
546 //TODO: shouldn't we delete TA blob file ?
cd9434cc
T
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 }
15e8442f 550 fseek(fs, 0, SEEK_SET);
cd9434cc 551 fwrite(&spid, 1, sizeof(mcSpid_t), fs);
cd9434cc
T
552 fflush(fs);
553 fclose(fs);
554 }
555 return MC_DRV_OK;
556}
557
558//------------------------------------------------------------------------------
559mcResult_t mcRegistryReadTrustletCon(const mcUuid_t *uuid, const mcSpid_t spid, void *so, uint32_t *size)
560{
cd9434cc
T
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;
15e8442f
JA
566 const string &tlContFilePath = getTlContFilePath(uuid, spid);
567 LOG_I("read TLc: %s", tlContFilePath.c_str());
cd9434cc
T
568
569 FILE *fs = fopen(tlContFilePath.c_str(), "rb");
15e8442f 570 if (!fs) {
cd9434cc
T
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 }
15e8442f
JA
574 fseek(fs, 0, SEEK_SET);
575 readBytes = fread((char *)so, 1, *size, fs);
cd9434cc
T
576 fclose(fs);
577
578 if (readBytes > 0) {
15e8442f 579 *size = readBytes;
cd9434cc
T
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//------------------------------------------------------------------------------
15e8442f 589mcResult_t mcRegistryStoreData(void *so, uint32_t size)
cd9434cc 590{
15e8442f 591 mcSoDataCont_t *dataCont = (mcSoDataCont_t *)so;
cd9434cc
T
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 }
15e8442f 597 string pathname, filename;
cd9434cc
T
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
15e8442f 618 LOG_I("store DT: %s", filename.c_str());
cd9434cc
T
619
620 FILE *fs = fopen(filename.c_str(), "wb");
15e8442f 621 if (!fs) {
cd9434cc
T
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 }
15e8442f
JA
625 fseek(fs, 0, SEEK_SET);
626 fwrite((char *)dataCont, 1, MC_SO_SIZE(dataCont->soHeader.plainLen, dataCont->soHeader.encryptedLen), fs);
cd9434cc
T
627 fflush(fs);
628 fclose(fs);
629
630 return MC_DRV_OK;
631}
632
633
634//------------------------------------------------------------------------------
15e8442f 635mcResult_t mcRegistryReadData(uint32_t context, const mcCid_t *cid, mcPid_t pid __unused,
cd9434cc
T
636 mcSoDataCont_t *so, uint32_t maxLen)
637{
cd9434cc
T
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 }
15e8442f 643 string filename;
cd9434cc
T
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 }
15e8442f 656 LOG_I("read DT: %s", filename.c_str());
cd9434cc
T
657
658 FILE *fs = fopen(filename.c_str(), "rb");
15e8442f 659 if (!fs) {
cd9434cc
T
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 }
15e8442f
JA
663 fseek(fs, 0, SEEK_END);
664 uint32_t filesize = ftell(fs);
665 if (maxLen < filesize) {
cd9434cc
T
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 }
15e8442f
JA
670 fseek(fs, 0, SEEK_SET);
671 char *p = (char *) so;
672 if (fread(p, 1, sizeof(mcSoHeader_t), fs) != sizeof(mcSoHeader_t))
673 {
cd9434cc
T
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 }
cd9434cc 678 p += sizeof(mcSoHeader_t);
15e8442f 679 if (fread(p, 1, MC_SO_SIZE(so->soHeader.plainLen,
cd9434cc 680 so->soHeader.encryptedLen)
15e8442f
JA
681 - sizeof(mcSoHeader_t), fs) !=
682 MC_SO_SIZE(so->soHeader.plainLen, so->soHeader.encryptedLen)
683 - sizeof(mcSoHeader_t))
684 {
cd9434cc
T
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 }
cd9434cc
T
689 fclose(fs);
690
691 return MC_DRV_OK;
692}
693
694
695//------------------------------------------------------------------------------
15e8442f 696static size_t getFileContent(
cd9434cc
T
697 const char *pPath,
698 uint8_t **ppContent)
699{
700 FILE *pStream;
701 long filesize;
702 uint8_t *content = NULL;
cd9434cc
T
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 */
15e8442f 734 content = (uint8_t *)malloc(filesize);
cd9434cc
T
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 */
15e8442f 741 if (fread(content, (size_t)filesize, 1, pStream) != 1) {
cd9434cc
T
742 LOG_E("Error: Cannot read file: %s.", pPath);
743 goto error;
744 }
cd9434cc
T
745
746 /* Close the file */
747 fclose(pStream);
748 *ppContent = content;
749
750 /* Return number of bytes read */
15e8442f 751 return (size_t)filesize;
cd9434cc
T
752
753error:
15e8442f
JA
754 if (content != NULL) {
755 free(content);
cd9434cc
T
756 }
757 fclose(pStream);
758 return 0;
759}
760
761//------------------------------------------------------------------------------
762static 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)) {
15e8442f
JA
776 free(pTAData);
777 LOG_E("RegistryStoreTABlob failed - TA blob length is less then header size");
cd9434cc
T
778 return false;
779 }
780
15e8442f 781 mclfHeaderV2_t *header20 = (mclfHeaderV2_t *)pTAData;
cd9434cc
T
782
783 // Check header version
784 if (header20->intro.version < MC_MAKE_VERSION(2, 4)) {
15e8442f
JA
785 free(pTAData);
786 LOG_E("RegistryStoreTABlob failed - TA blob header version is less than 2.4");
cd9434cc
T
787 return false;
788 }
789
15e8442f 790 // Check blob size
cd9434cc
T
791 if (memcmp(uuid, &header20->uuid, sizeof(mcUuid_t)) == 0) {
792 res = true;
793 } else {
794 res = false;
795 }
796
15e8442f 797 free(pTAData);
cd9434cc
T
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.
15e8442f 804static int CleanupGPTAStorage(const char *basename)
cd9434cc
T
805{
806 DIR *dp;
807 struct dirent *de;
808 int e;
15e8442f
JA
809 string TAPath = getTlRegistryPath()+"/TbStorage/"+ basename;
810
cd9434cc
T
811 if (NULL != (dp = opendir(TAPath.c_str()))) {
812 while (NULL != (de = readdir(dp))) {
813 if (de->d_name[0] != '.') {
15e8442f
JA
814 string dname = TAPath + "/" + string (de->d_name);
815 LOG_I("delete DT: %s", dname.c_str());
cd9434cc
T
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 }
15e8442f 824 LOG_I("delete dir: %s", TAPath.c_str());
cd9434cc
T
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
15e8442f 833static void deleteSPTA(const mcUuid_t *uuid, const mcSpid_t spid, bool checkUuid)
cd9434cc
T
834{
835 DIR *dp;
836 struct dirent *de;
837 int e;
838
839 // Delete TABIN and SPID files - we loop searching required spid file
15e8442f
JA
840 string pathname = getRegistryPath();
841 if (NULL != (dp = opendir(pathname.c_str()))) {
cd9434cc 842 while (NULL != (de = readdir(dp))) {
15e8442f
JA
843 string spidFile;
844 string tabinFile;
845 string tabinUuid;
cd9434cc 846 size_t pch_dot, pch_slash;
15e8442f 847 spidFile = pathname + '/' + string(de->d_name);
cd9434cc 848 pch_dot = spidFile.find_last_of('.');
15e8442f 849 if (pch_dot == string::npos) continue;
cd9434cc 850 pch_slash = spidFile.find_last_of('/');
15e8442f 851 if ((pch_slash != string::npos) && (pch_slash > pch_dot)) continue;
cd9434cc
T
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;
15e8442f
JA
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 }
cd9434cc 871 if (0 != (e = remove(tabinFile.c_str()))) {
15e8442f
JA
872 LOG_E("remove TA file failed! errno: %d", e);
873 //return MC_DRV_ERR_UNKNOWN;
cd9434cc 874 }
cd9434cc 875 if (0 != (e = remove(spidFile.c_str()))) {
15e8442f
JA
876 LOG_E("remove SPID file failed! errno: %d", e);
877 //return MC_DRV_ERR_UNKNOWN;
cd9434cc 878 }
15e8442f 879 if (checkUuid) break;
cd9434cc
T
880 }
881 }
882 }
883 if (dp) {
884 closedir(dp);
885 }
15e8442f 886
cd9434cc
T
887 }
888}
889
890//------------------------------------------------------------------------------
891mcResult_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
15e8442f 903 string pathname = getTlDataPath(uuid);
cd9434cc
T
904 if (NULL != (dp = opendir(pathname.c_str()))) {
905 while (NULL != (de = readdir(dp))) {
906 if (de->d_name[0] != '.') {
15e8442f
JA
907 string dname = pathname + "/" + string (de->d_name);
908 LOG_I("delete DT: %s", dname.c_str());
cd9434cc
T
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 }
15e8442f 917 LOG_I("delete dir: %s", pathname.c_str());
cd9434cc
T
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
15e8442f
JA
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)
cd9434cc
T
930 }
931
15e8442f
JA
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());
cd9434cc 937 if (0 != (e = remove(tlContFilePath.c_str()))) {
15e8442f 938 LOG_E("remove Tlc failed! errno: %d", e);
cd9434cc
T
939 return MC_DRV_ERR_UNKNOWN;
940 }
cd9434cc
T
941 return MC_DRV_OK;
942}
943
944
945//------------------------------------------------------------------------------
946mcResult_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++) {
15e8442f 966 if (0 != strncmp((const char *) & (data.cont.children[i]), (const char *)&MC_UUID_FREE, sizeof(mcUuid_t))) {
cd9434cc
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
15e8442f
JA
975 // Delete remaining TABIN and SPID files
976 deleteSPTA(NULL,spid,false);
977
978 string pathname = getSpDataPath(spid);
cd9434cc
T
979
980 if (NULL != (dp = opendir(pathname.c_str()))) {
981 while (NULL != (de = readdir(dp))) {
982 if (de->d_name[0] != '.') {
15e8442f
JA
983 string dname = pathname + "/" + string (de->d_name);
984 LOG_I("delete DT: %s", dname.c_str());
cd9434cc
T
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 }
15e8442f 993 LOG_I("delete dir: %s", pathname.c_str());
cd9434cc
T
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 }
15e8442f
JA
999 string spContFilePath = getSpContFilePath(spid);
1000 LOG_I("delete Sp: %s", spContFilePath.c_str());
cd9434cc
T
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//------------------------------------------------------------------------------
1010mcResult_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
15e8442f
JA
1033 string rootContFilePath = getRootContFilePath();
1034 LOG_I("Delete root: %s", rootContFilePath.c_str());
cd9434cc
T
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//------------------------------------------------------------------------------
15e8442f
JA
1043regObject_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//------------------------------------------------------------------------------
1183regObject_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
1219error:
1220 if (close(fd)) {
1221 LOG_E("mcRegistryFileGetServiceBlob(): Failed to close file %s", trustlet);
1222 }
1223
1224 return regobj;
1225}
1226
1227
1228//------------------------------------------------------------------------------
1229regObject_t *mcRegistryGetServiceBlob(const mcUuid_t *uuid, bool isGpUuid)
cd9434cc
T
1230{
1231 // Ensure that a UUID is provided.
1232 if (NULL == uuid) {
1233 LOG_E("No UUID given");
15e8442f 1234 return NULL;
cd9434cc
T
1235 }
1236
15e8442f
JA
1237 // Open service blob file.
1238 string tlBinFilePath;
cd9434cc 1239 if (isGpUuid) {
15e8442f 1240 tlBinFilePath = getTABinFilePath(uuid);
cd9434cc 1241 } else {
15e8442f 1242 tlBinFilePath = getTlBinFilePath(uuid);
cd9434cc 1243 }
15e8442f 1244 LOG_I("Loading %s", tlBinFilePath.c_str());
cd9434cc 1245
15e8442f 1246 mcSpid_t spid = 0;
cd9434cc 1247 if (isGpUuid) {
15e8442f 1248 string taspidFilePath = getTASpidFilePath(uuid);
cd9434cc 1249 int fd = open(taspidFilePath.c_str(), O_RDONLY);
15e8442f
JA
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;
cd9434cc 1259 }
15e8442f 1260 close(fd);
cd9434cc
T
1261 }
1262 }
1263
15e8442f
JA
1264 return mcRegistryFileGetServiceBlob(tlBinFilePath.c_str(), spid);
1265}
1266
1267//------------------------------------------------------------------------------
1268regObject_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;
cd9434cc 1289}
15e8442f
JA
1290
1291/** @} */