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