xref: /rk3399_rockchip-uboot/lib/optee_clientApi/OpteeClientLoadTa.c (revision 436fc6d8486bf43c63b3bb9ec872523f92491494)
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