1 /*
2 * Copyright 2023, Rockchip Electronics Co., Ltd
3 * hisping lin, <hisping.lin@rock-chips.com>
4 *
5 * SPDX-License-Identifier: GPL-2.0+
6 */
7 #include <stdlib.h>
8 #include <boot_rkimg.h>
9 #include <command.h>
10 #include <common.h>
11 #include <mmc.h>
12 #include <optee_include/OpteeClientLoadTa.h>
13
is_uuid_equal(TEEC_UUID uuid1,TEEC_UUID uuid2)14 int is_uuid_equal(TEEC_UUID uuid1, TEEC_UUID uuid2)
15 {
16 bool a, b, c;
17
18 a = (uuid1.timeLow == uuid2.timeLow);
19 b = (uuid1.timeMid == uuid2.timeMid);
20 c = (uuid1.timeHiAndVersion == uuid2.timeHiAndVersion);
21 if ((a & b & c) == 0) {
22 return 0;
23 } else {
24 if (memcmp(uuid1.clockSeqAndNode,
25 uuid2.clockSeqAndNode, 8) == 0) {
26 return 1;
27 } else {
28 return 0;
29 }
30 }
31 }
32
tee_uuid_from_octets(TEEC_UUID * d,const uint8_t * s)33 void tee_uuid_from_octets(TEEC_UUID *d, const uint8_t *s)
34 {
35 d->timeLow = (s[0] << 24) | (s[1] << 16) | (s[2] << 8) | s[3];
36 d->timeMid = (s[4] << 8) | s[5];
37 d->timeHiAndVersion = (s[6] << 8) | s[7];
38 memcpy(d->clockSeqAndNode, s + 8, sizeof(d->clockSeqAndNode));
39 }
40
41 static struct blk_desc *dev_desc;
42 static disk_partition_t part_info;
search_ta(void * uuid_octets,void * ta,size_t * ta_size)43 int search_ta(void *uuid_octets, void *ta, size_t *ta_size)
44 {
45 char fname[255];
46 char *format;
47 unsigned long ret = 0;
48 TEEC_UUID uuid;
49 TEEC_UUID ta_uuid;
50 uint8_t *userta;
51 struct userta_header *header;
52 struct userta_item *item;
53 int ta_ver;
54 int res;
55
56 if (!uuid_octets || !ta_size) {
57 printf("TEEC: wrong parameter to search_ta\n");
58 return -1;
59 }
60
61 if (!dev_desc) {
62 dev_desc = rockchip_get_bootdev();
63 if (!dev_desc) {
64 printf("TEEC: %s: Could not find device\n", __func__);
65 return -1;
66 }
67
68 if (part_get_info_by_name(dev_desc,
69 "userta", &part_info) < 0) {
70 dev_desc = NULL;
71 printf("TEEC: Could not find userta partition\n");
72 return -1;
73 }
74 }
75
76 #ifdef CONFIG_OPTEE_V1
77 memcpy(&uuid, uuid_octets, sizeof(TEEC_UUID));
78 ta_ver = 1;
79 format = "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x.ta";
80 #endif
81
82 #ifdef CONFIG_OPTEE_V2
83 tee_uuid_from_octets(&uuid, uuid_octets);
84 ta_ver = 2;
85 format = "%08x-%04x-%04x-%02x%02x%02x%02x%02x%02x%02x%02x.ta";
86 #endif
87
88 snprintf(fname, 255,
89 format,
90 uuid.timeLow,
91 uuid.timeMid,
92 uuid.timeHiAndVersion,
93 uuid.clockSeqAndNode[0],
94 uuid.clockSeqAndNode[1],
95 uuid.clockSeqAndNode[2],
96 uuid.clockSeqAndNode[3],
97 uuid.clockSeqAndNode[4],
98 uuid.clockSeqAndNode[5],
99 uuid.clockSeqAndNode[6],
100 uuid.clockSeqAndNode[7]);
101
102 printf("Attempt to load %s \n", fname);
103
104 userta = (uint8_t *)memalign(CONFIG_SYS_CACHELINE_SIZE, part_info.size * part_info.blksz);
105 if (!userta) {
106 printf("TEEC: Malloc failed!\n");
107 res = -1;
108 goto exit;
109 }
110
111 ret = blk_dread(dev_desc, part_info.start, part_info.size, userta);
112 if (ret != part_info.size) {
113 printf("TEEC: blk_dread fail\n");
114 res = -1;
115 goto exit;
116 }
117
118 header = (struct userta_header *)userta;
119 if (header->magic != 0x524B5441 || header->img_ver != 1) {
120 printf("TEEC: userta_header format error! \n");
121 res = -1;
122 goto exit;
123 }
124
125 item = (struct userta_item *)(header + 1);
126
127 for (int i = 0; i < header->ta_num; i++) {
128 tee_uuid_from_octets(&ta_uuid, item->ta_uuid);
129 snprintf(fname, 255,
130 format,
131 ta_uuid.timeLow,
132 ta_uuid.timeMid,
133 ta_uuid.timeHiAndVersion,
134 ta_uuid.clockSeqAndNode[0],
135 ta_uuid.clockSeqAndNode[1],
136 ta_uuid.clockSeqAndNode[2],
137 ta_uuid.clockSeqAndNode[3],
138 ta_uuid.clockSeqAndNode[4],
139 ta_uuid.clockSeqAndNode[5],
140 ta_uuid.clockSeqAndNode[6],
141 ta_uuid.clockSeqAndNode[7]);
142 debug("search TA %s \n", fname);
143 debug("item->ta_offset=0x%x item->ta_len=0x%x *ta_size=%zu\n",
144 item->ta_offset, item->ta_len, *ta_size);
145
146 if (is_uuid_equal(ta_uuid, uuid) && item->ta_ver == ta_ver) {
147 if (item->ta_len <= *ta_size && ta)
148 memcpy(ta, userta + item->ta_offset, item->ta_len);
149 *ta_size = item->ta_len;
150 res = TA_BINARY_FOUND;
151 goto exit;
152 } else {
153 item++;
154 }
155 }
156 res = TA_BINARY_NOT_FOUND;
157
158 exit:
159 if (userta)
160 free(userta);
161 return res;
162 }
163