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