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*d0747e2eSImre Kis# Copyright (c) 2020-2023, Arm Limited. 6dea46be3SJelle Sels# 7dea46be3SJelle Sels 8dea46be3SJelle Selsimport argparse 9dea46be3SJelle Selsimport array 10*d0747e2eSImre Kisfrom elftools.elf.elffile import ELFFile, ELFError 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 46e23cd783SJelle Sels parser.add_argument( 47e23cd783SJelle Sels '--manifest', 48e23cd783SJelle Sels dest="manifest", 49e23cd783SJelle Sels required=False, 50e23cd783SJelle Sels help='path to the SP manifest file') 51e23cd783SJelle 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: 77*d0747e2eSImre Kis try: 78dea46be3SJelle Sels elffile = ELFFile(f) 79*d0747e2eSImre Kis except ELFError: 80*d0747e2eSImre Kis # Binary format SP, return zero flags 81*d0747e2eSImre Kis return 0 82dea46be3SJelle Sels 83dea46be3SJelle Sels for s in elffile.iter_sections(): 84dea46be3SJelle Sels if get_name(s) == '.sp_head': 85dea46be3SJelle Sels return struct.unpack('<16x4xI', s.data()[:24])[0] 86dea46be3SJelle Sels 87dea46be3SJelle Sels raise Exception('.sp_head section not found') 88dea46be3SJelle Sels 89dea46be3SJelle Sels 90e23cd783SJelle Selsdef dump_bin(f, ts, compress): 91e23cd783SJelle Sels with open(ts, 'rb') as _ts: 92e23cd783SJelle Sels bytes = _ts.read() 93e23cd783SJelle Sels uncompressed_size = len(bytes) 94e23cd783SJelle Sels if compress: 95e23cd783SJelle Sels bytes = zlib.compress(bytes) 96e23cd783SJelle Sels size = len(bytes) 97e23cd783SJelle Sels 98e23cd783SJelle Sels i = 0 99e23cd783SJelle Sels while i < size: 100e23cd783SJelle Sels if i % 8 == 0: 101e23cd783SJelle Sels f.write('\t\t') 102e23cd783SJelle Sels f.write(hex(bytes[i]) + ',') 103e23cd783SJelle Sels i = i + 1 104e23cd783SJelle Sels if i % 8 == 0 or i == size: 105e23cd783SJelle Sels f.write('\n') 106e23cd783SJelle Sels else: 107e23cd783SJelle Sels f.write(' ') 108e23cd783SJelle Sels return (size, uncompressed_size) 109e23cd783SJelle Sels 110e23cd783SJelle Sels 111dea46be3SJelle Selsdef main(): 112dea46be3SJelle Sels args = get_args() 113dea46be3SJelle Sels is_sp = False 114dea46be3SJelle Sels 115dea46be3SJelle Sels if args.ta is None and args.sp is None: 116dea46be3SJelle Sels raise Exception('The --ta or the --sp flag is required') 117dea46be3SJelle Sels 118dea46be3SJelle Sels if args.ta is not None and args.sp is not None: 119dea46be3SJelle Sels raise Exception('The --ta and the --sp can\'t be combined') 120dea46be3SJelle Sels 121dea46be3SJelle Sels if args.ta is not None: 122dea46be3SJelle Sels ts = args.ta 123dea46be3SJelle Sels is_sp = False 124dea46be3SJelle Sels 125dea46be3SJelle Sels if args.sp is not None: 126dea46be3SJelle Sels ts = args.sp 127dea46be3SJelle Sels is_sp = True 128dea46be3SJelle Sels 129dea46be3SJelle Sels ts_uuid = uuid.UUID(re.sub(r'\..*', '', os.path.basename(ts))) 130dea46be3SJelle Sels 131dea46be3SJelle Sels f = open(args.out, 'w') 132dea46be3SJelle Sels f.write('/* Generated from ' + ts + ' by ' + 133dea46be3SJelle Sels os.path.basename(__file__) + ' */\n\n') 134dea46be3SJelle Sels f.write('#include <kernel/embedded_ts.h>\n\n') 135dea46be3SJelle Sels f.write('#include <scattered_array.h>\n\n') 136dea46be3SJelle Sels f.write('const uint8_t ts_bin_' + ts_uuid.hex + '[] = {\n') 137e23cd783SJelle Sels ts_size, ts_uncompressed_size = dump_bin(f, ts, args.compress) 138dea46be3SJelle Sels f.write('};\n') 139dea46be3SJelle Sels 140dea46be3SJelle Sels if is_sp: 141e23cd783SJelle Sels 142e23cd783SJelle Sels f.write('#include <kernel/secure_partition.h>\n\n') 143e23cd783SJelle Sels f.write('const uint8_t fdt_bin_' + ts_uuid.hex + '[] = {\n') 144e23cd783SJelle Sels dump_bin(f, args.manifest, False) 145e23cd783SJelle Sels f.write('};\n') 146dea46be3SJelle Sels f.write('SCATTERED_ARRAY_DEFINE_PG_ITEM(sp_images, struct \ 147e23cd783SJelle Sels sp_image) = {\n') 148e23cd783SJelle Sels f.write('\t.fdt = fdt_bin_' + ts_uuid.hex + ',\n') 149e23cd783SJelle Sels 150e23cd783SJelle Sels f.write('. image = {') 151dea46be3SJelle Sels f.write('\t.flags = 0x{:04x},\n'.format(sp_get_flags(ts))) 152dea46be3SJelle Sels else: 153dea46be3SJelle Sels f.write('SCATTERED_ARRAY_DEFINE_PG_ITEM(early_tas, struct \ 154dea46be3SJelle Sels embedded_ts) = {\n') 155dea46be3SJelle Sels f.write('\t.flags = 0x{:04x},\n'.format(ta_get_flags(ts))) 156dea46be3SJelle Sels f.write('\t.uuid = {\n') 157dea46be3SJelle Sels f.write('\t\t.timeLow = 0x{:08x},\n'.format(ts_uuid.time_low)) 158dea46be3SJelle Sels f.write('\t\t.timeMid = 0x{:04x},\n'.format(ts_uuid.time_mid)) 159dea46be3SJelle Sels f.write('\t\t.timeHiAndVersion = ' + 160dea46be3SJelle Sels '0x{:04x},\n'.format(ts_uuid.time_hi_version)) 161dea46be3SJelle Sels f.write('\t\t.clockSeqAndNode = {\n') 162dea46be3SJelle Sels csn = '{0:02x}{1:02x}{2:012x}'.format(ts_uuid.clock_seq_hi_variant, 163dea46be3SJelle Sels ts_uuid.clock_seq_low, ts_uuid.node) 164dea46be3SJelle Sels f.write('\t\t\t') 165dea46be3SJelle Sels f.write(', '.join('0x' + csn[i:i + 2] for i in range(0, len(csn), 2))) 166dea46be3SJelle Sels f.write('\n\t\t},\n\t},\n') 167dea46be3SJelle Sels f.write('\t.size = sizeof(ts_bin_' + ts_uuid.hex + 168e23cd783SJelle Sels '), /* {:d} */\n'.format(ts_size)) 169dea46be3SJelle Sels f.write('\t.ts = ts_bin_' + ts_uuid.hex + ',\n') 170dea46be3SJelle Sels if args.compress: 171dea46be3SJelle Sels f.write('\t.uncompressed_size = ' 172e23cd783SJelle Sels '{:d},\n'.format(ts_uncompressed_size)) 173e23cd783SJelle Sels if is_sp: 174e23cd783SJelle Sels f.write('}\n') 175dea46be3SJelle Sels f.write('};\n') 176dea46be3SJelle Sels f.close() 177dea46be3SJelle Sels 178dea46be3SJelle Sels 179dea46be3SJelle Selsif __name__ == "__main__": 180dea46be3SJelle Sels main() 181