1dea46be3SJelle Sels#!/usr/bin/env python3 2dea46be3SJelle Sels# SPDX-License-Identifier: BSD-2-Clause 3dea46be3SJelle Sels# 4dea46be3SJelle Sels# Copyright (c) 2017, 2020, Linaro Limited 5*e23cd783SJelle Sels# Copyright (c) 2020-2022, Arm Limited. 6dea46be3SJelle Sels# 7dea46be3SJelle Sels 8dea46be3SJelle Selsimport argparse 9dea46be3SJelle Selsimport array 10dea46be3SJelle Selsfrom elftools.elf.elffile import ELFFile 11dea46be3SJelle Selsimport os 12dea46be3SJelle Selsimport re 13dea46be3SJelle Selsimport struct 14dea46be3SJelle Selsimport uuid 15dea46be3SJelle Selsimport zlib 16dea46be3SJelle Sels 17dea46be3SJelle Sels 18dea46be3SJelle Selsdef get_args(): 19dea46be3SJelle Sels parser = argparse.ArgumentParser( 20dea46be3SJelle Sels description='Converts a Trusted ' 21dea46be3SJelle Sels 'Application ELF file into a C source file, ready for ' 22dea46be3SJelle Sels 'inclusion in the TEE binary as an "early TA".') 23dea46be3SJelle Sels 24dea46be3SJelle Sels parser.add_argument('--out', required=True, 25dea46be3SJelle Sels help='Name of the output C file') 26dea46be3SJelle Sels 27dea46be3SJelle Sels parser.add_argument( 28dea46be3SJelle Sels '--ta', 29dea46be3SJelle Sels required=False, 30dea46be3SJelle Sels help='Path to the TA binary. File name has to be: <uuid>.* ' 31dea46be3SJelle Sels 'such as: 8aaaf200-2450-11e4-abe2-0002a5d5c51b.stripped.elf') 32dea46be3SJelle Sels 33dea46be3SJelle Sels parser.add_argument( 34dea46be3SJelle Sels '--sp', 35dea46be3SJelle Sels required=False, 36dea46be3SJelle Sels help='Path to the SP binary. File name has to be: <uuid>.* ' 37dea46be3SJelle Sels 'such as: 8aaaf200-2450-11e4-abe2-0002a5d5c51b.stripped.elf') 38dea46be3SJelle Sels 39dea46be3SJelle Sels parser.add_argument( 40dea46be3SJelle Sels '--compress', 41dea46be3SJelle Sels dest="compress", 42dea46be3SJelle Sels action="store_true", 43dea46be3SJelle Sels help='Compress the image using the DEFLATE ' 44dea46be3SJelle Sels 'algorithm') 45dea46be3SJelle Sels 46*e23cd783SJelle Sels parser.add_argument( 47*e23cd783SJelle Sels '--manifest', 48*e23cd783SJelle Sels dest="manifest", 49*e23cd783SJelle Sels required=False, 50*e23cd783SJelle Sels help='path to the SP manifest file') 51*e23cd783SJelle Sels 52dea46be3SJelle Sels return parser.parse_args() 53dea46be3SJelle Sels 54dea46be3SJelle Sels 55dea46be3SJelle Selsdef get_name(obj): 56dea46be3SJelle Sels # Symbol or section .name can be a byte array or a string, we want a string 57dea46be3SJelle Sels try: 58dea46be3SJelle Sels name = obj.name.decode() 59dea46be3SJelle Sels except (UnicodeDecodeError, AttributeError): 60dea46be3SJelle Sels name = obj.name 61dea46be3SJelle Sels return name 62dea46be3SJelle Sels 63dea46be3SJelle Sels 64dea46be3SJelle Selsdef ta_get_flags(ta_f): 65dea46be3SJelle Sels with open(ta_f, 'rb') as f: 66dea46be3SJelle Sels elffile = ELFFile(f) 67dea46be3SJelle Sels 68dea46be3SJelle Sels for s in elffile.iter_sections(): 69dea46be3SJelle Sels if get_name(s) == '.ta_head': 70dea46be3SJelle Sels return struct.unpack('<16x4xI', s.data()[:24])[0] 71dea46be3SJelle Sels 72dea46be3SJelle Sels raise Exception('.ta_head section not found') 73dea46be3SJelle Sels 74dea46be3SJelle Sels 75dea46be3SJelle Selsdef sp_get_flags(sp_f): 76dea46be3SJelle Sels with open(sp_f, 'rb') as f: 77dea46be3SJelle Sels elffile = ELFFile(f) 78dea46be3SJelle Sels 79dea46be3SJelle Sels for s in elffile.iter_sections(): 80dea46be3SJelle Sels if get_name(s) == '.sp_head': 81dea46be3SJelle Sels return struct.unpack('<16x4xI', s.data()[:24])[0] 82dea46be3SJelle Sels 83dea46be3SJelle Sels raise Exception('.sp_head section not found') 84dea46be3SJelle Sels 85dea46be3SJelle Sels 86*e23cd783SJelle Selsdef dump_bin(f, ts, compress): 87*e23cd783SJelle Sels with open(ts, 'rb') as _ts: 88*e23cd783SJelle Sels bytes = _ts.read() 89*e23cd783SJelle Sels uncompressed_size = len(bytes) 90*e23cd783SJelle Sels if compress: 91*e23cd783SJelle Sels bytes = zlib.compress(bytes) 92*e23cd783SJelle Sels size = len(bytes) 93*e23cd783SJelle Sels 94*e23cd783SJelle Sels i = 0 95*e23cd783SJelle Sels while i < size: 96*e23cd783SJelle Sels if i % 8 == 0: 97*e23cd783SJelle Sels f.write('\t\t') 98*e23cd783SJelle Sels f.write(hex(bytes[i]) + ',') 99*e23cd783SJelle Sels i = i + 1 100*e23cd783SJelle Sels if i % 8 == 0 or i == size: 101*e23cd783SJelle Sels f.write('\n') 102*e23cd783SJelle Sels else: 103*e23cd783SJelle Sels f.write(' ') 104*e23cd783SJelle Sels return (size, uncompressed_size) 105*e23cd783SJelle Sels 106*e23cd783SJelle Sels 107dea46be3SJelle Selsdef main(): 108dea46be3SJelle Sels args = get_args() 109dea46be3SJelle Sels is_sp = False 110dea46be3SJelle Sels 111dea46be3SJelle Sels if args.ta is None and args.sp is None: 112dea46be3SJelle Sels raise Exception('The --ta or the --sp flag is required') 113dea46be3SJelle Sels 114dea46be3SJelle Sels if args.ta is not None and args.sp is not None: 115dea46be3SJelle Sels raise Exception('The --ta and the --sp can\'t be combined') 116dea46be3SJelle Sels 117dea46be3SJelle Sels if args.ta is not None: 118dea46be3SJelle Sels ts = args.ta 119dea46be3SJelle Sels is_sp = False 120dea46be3SJelle Sels 121dea46be3SJelle Sels if args.sp is not None: 122dea46be3SJelle Sels ts = args.sp 123dea46be3SJelle Sels is_sp = True 124dea46be3SJelle Sels 125dea46be3SJelle Sels ts_uuid = uuid.UUID(re.sub(r'\..*', '', os.path.basename(ts))) 126dea46be3SJelle Sels 127dea46be3SJelle Sels f = open(args.out, 'w') 128dea46be3SJelle Sels f.write('/* Generated from ' + ts + ' by ' + 129dea46be3SJelle Sels os.path.basename(__file__) + ' */\n\n') 130dea46be3SJelle Sels f.write('#include <kernel/embedded_ts.h>\n\n') 131dea46be3SJelle Sels f.write('#include <scattered_array.h>\n\n') 132dea46be3SJelle Sels f.write('const uint8_t ts_bin_' + ts_uuid.hex + '[] = {\n') 133*e23cd783SJelle Sels ts_size, ts_uncompressed_size = dump_bin(f, ts, args.compress) 134dea46be3SJelle Sels f.write('};\n') 135dea46be3SJelle Sels 136dea46be3SJelle Sels if is_sp: 137*e23cd783SJelle Sels 138*e23cd783SJelle Sels f.write('#include <kernel/secure_partition.h>\n\n') 139*e23cd783SJelle Sels f.write('const uint8_t fdt_bin_' + ts_uuid.hex + '[] = {\n') 140*e23cd783SJelle Sels dump_bin(f, args.manifest, False) 141*e23cd783SJelle Sels f.write('};\n') 142dea46be3SJelle Sels f.write('SCATTERED_ARRAY_DEFINE_PG_ITEM(sp_images, struct \ 143*e23cd783SJelle Sels sp_image) = {\n') 144*e23cd783SJelle Sels f.write('\t.fdt = fdt_bin_' + ts_uuid.hex + ',\n') 145*e23cd783SJelle Sels 146*e23cd783SJelle Sels f.write('. image = {') 147dea46be3SJelle Sels f.write('\t.flags = 0x{:04x},\n'.format(sp_get_flags(ts))) 148dea46be3SJelle Sels else: 149dea46be3SJelle Sels f.write('SCATTERED_ARRAY_DEFINE_PG_ITEM(early_tas, struct \ 150dea46be3SJelle Sels embedded_ts) = {\n') 151dea46be3SJelle Sels f.write('\t.flags = 0x{:04x},\n'.format(ta_get_flags(ts))) 152dea46be3SJelle Sels f.write('\t.uuid = {\n') 153dea46be3SJelle Sels f.write('\t\t.timeLow = 0x{:08x},\n'.format(ts_uuid.time_low)) 154dea46be3SJelle Sels f.write('\t\t.timeMid = 0x{:04x},\n'.format(ts_uuid.time_mid)) 155dea46be3SJelle Sels f.write('\t\t.timeHiAndVersion = ' + 156dea46be3SJelle Sels '0x{:04x},\n'.format(ts_uuid.time_hi_version)) 157dea46be3SJelle Sels f.write('\t\t.clockSeqAndNode = {\n') 158dea46be3SJelle Sels csn = '{0:02x}{1:02x}{2:012x}'.format(ts_uuid.clock_seq_hi_variant, 159dea46be3SJelle Sels ts_uuid.clock_seq_low, ts_uuid.node) 160dea46be3SJelle Sels f.write('\t\t\t') 161dea46be3SJelle Sels f.write(', '.join('0x' + csn[i:i + 2] for i in range(0, len(csn), 2))) 162dea46be3SJelle Sels f.write('\n\t\t},\n\t},\n') 163dea46be3SJelle Sels f.write('\t.size = sizeof(ts_bin_' + ts_uuid.hex + 164*e23cd783SJelle Sels '), /* {:d} */\n'.format(ts_size)) 165dea46be3SJelle Sels f.write('\t.ts = ts_bin_' + ts_uuid.hex + ',\n') 166dea46be3SJelle Sels if args.compress: 167dea46be3SJelle Sels f.write('\t.uncompressed_size = ' 168*e23cd783SJelle Sels '{:d},\n'.format(ts_uncompressed_size)) 169*e23cd783SJelle Sels if is_sp: 170*e23cd783SJelle Sels f.write('}\n') 171dea46be3SJelle Sels f.write('};\n') 172dea46be3SJelle Sels f.close() 173dea46be3SJelle Sels 174dea46be3SJelle Sels 175dea46be3SJelle Selsif __name__ == "__main__": 176dea46be3SJelle Sels main() 177