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