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