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