blob: a76a62cc8796bb059451cb2692d681d19648ca1c [file] [log] [blame]
Rouven Czerwinskibbaeed42019-08-07 20:07:00 +02001#!/usr/bin/env python3
Jerome Forissier1bb92982017-12-15 14:27:02 +01002# SPDX-License-Identifier: BSD-2-Clause
Jens Wiklander8f7de3f2014-12-04 08:04:01 +01003#
Summer Qinac3cc6c2017-04-18 13:59:03 +01004# Copyright (c) 2014-2017, Linaro Limited
Jens Wiklander8f7de3f2014-12-04 08:04:01 +01005#
Jens Wiklander8f7de3f2014-12-04 08:04:01 +01006
7import argparse
8import sys
9import shutil
10import os
11import struct
12import hashlib
13
Jerome Forissier7a976652015-05-06 17:23:50 +020014arch_id = {'arm32': 0, 'arm64': 1}
Summer Qinac3cc6c2017-04-18 13:59:03 +010015image_id = {'pager': 0, 'paged': 1}
Jens Wiklander8f7de3f2014-12-04 08:04:01 +010016
Jerome Forissier15a991a2018-11-14 10:59:55 +010017
Summer Qinac3cc6c2017-04-18 13:59:03 +010018def write_header_v1(outf, init_size, args, paged_size):
Jerome Forissier15a991a2018-11-14 10:59:55 +010019 magic = 0x4554504f # 'OPTE'
20 version = 1
21 outf.write(struct.pack('<IBBHIIIII',
22 magic,
23 version,
24 arch_id[args.arch],
25 args.flags,
26 init_size,
27 args.init_load_addr_hi,
28 args.init_load_addr_lo,
29 args.init_mem_usage,
30 paged_size))
31
Summer Qinac3cc6c2017-04-18 13:59:03 +010032
33def write_header_v2(outf, init_size, args, paged_size):
Jerome Forissier15a991a2018-11-14 10:59:55 +010034 magic = 0x4554504f # 'OPTE'
35 version = 2
36 nb_images = 1 if paged_size == 0 else 2
37 outf.write(struct.pack('<IBBHI', magic, version,
38 arch_id[args.arch], args.flags, nb_images))
39 outf.write(struct.pack('<IIII',
40 args.init_load_addr_hi, args.init_load_addr_lo,
41 image_id['pager'], init_size))
42 if nb_images == 2:
43 outf.write(
44 struct.pack(
45 '<IIII',
46 0xffffffff,
47 0xffffffff,
48 image_id['paged'],
49 paged_size))
50
Jens Wiklander8f7de3f2014-12-04 08:04:01 +010051
52def append_to(outf, start_offs, in_fname, max_bytes=0xffffffff):
Jerome Forissier15a991a2018-11-14 10:59:55 +010053 inf = open(in_fname, 'rb')
54 inf.seek(start_offs)
55 while True:
56 nbytes = min(16 * 1024, max_bytes)
57 if nbytes == 0:
58 break
59 buf = inf.read(nbytes)
60 if not buf:
61 break
62 outf.write(buf)
63 max_bytes -= len(buf)
64 inf.close()
65
Jens Wiklander8f7de3f2014-12-04 08:04:01 +010066
67def append_hashes(outf, in_fname):
Jerome Forissier15a991a2018-11-14 10:59:55 +010068 page_size = 4 * 1024
Jens Wiklander8f7de3f2014-12-04 08:04:01 +010069
Volodymyr Babchukedbb89f2019-01-11 21:14:26 +020070 inf = open(in_fname, 'rb')
Jerome Forissier15a991a2018-11-14 10:59:55 +010071 while True:
72 page = inf.read(page_size)
73 if len(page) == page_size:
74 outf.write(hashlib.sha256(page).digest())
75 elif len(page) == 0:
76 break
77 else:
Rouven Czerwinskibbaeed42019-08-07 20:07:00 +020078 print("Error: short read, got {}".format(len(page)))
Jerome Forissier15a991a2018-11-14 10:59:55 +010079 sys.exit(1)
Jens Wiklander8f7de3f2014-12-04 08:04:01 +010080
Jerome Forissier15a991a2018-11-14 10:59:55 +010081 inf.close()
82
Jens Wiklander8f7de3f2014-12-04 08:04:01 +010083
84def int_parse(str):
Jerome Forissier15a991a2018-11-14 10:59:55 +010085 return int(str, 0)
86
Jens Wiklander8f7de3f2014-12-04 08:04:01 +010087
88def get_args():
Jerome Forissier15a991a2018-11-14 10:59:55 +010089 parser = argparse.ArgumentParser()
90 parser.add_argument('--arch', required=True,
Rouven Czerwinskibbaeed42019-08-07 20:07:00 +020091 choices=list(arch_id.keys()),
Jerome Forissier15a991a2018-11-14 10:59:55 +010092 help='Architecture')
Jens Wiklander8f7de3f2014-12-04 08:04:01 +010093
Jerome Forissier15a991a2018-11-14 10:59:55 +010094 parser.add_argument('--flags',
95 type=int, default=0,
96 help='Flags, currently none defined')
Jens Wiklander8f7de3f2014-12-04 08:04:01 +010097
Jerome Forissier15a991a2018-11-14 10:59:55 +010098 parser.add_argument('--init_size',
99 required=True, type=int_parse,
100 help='Size of initialization part of binary')
Jens Wiklander8f7de3f2014-12-04 08:04:01 +0100101
Jerome Forissier15a991a2018-11-14 10:59:55 +0100102 parser.add_argument('--init_load_addr_hi',
103 type=int_parse, default=0,
104 help='Upper 32 bits of load address of binary')
Jens Wiklander8f7de3f2014-12-04 08:04:01 +0100105
Jerome Forissier15a991a2018-11-14 10:59:55 +0100106 parser.add_argument('--init_load_addr_lo',
107 required=True, type=int_parse,
108 help='Lower 32 bits of load address of binary')
Jens Wiklander8f7de3f2014-12-04 08:04:01 +0100109
Jerome Forissier15a991a2018-11-14 10:59:55 +0100110 parser.add_argument('--init_mem_usage',
111 required=True, type=int_parse,
112 help='Total amount of used memory when initializing')
Jens Wiklander8f7de3f2014-12-04 08:04:01 +0100113
Jerome Forissier15a991a2018-11-14 10:59:55 +0100114 parser.add_argument('--tee_pager_bin',
115 required=True,
116 help='The input tee_pager.bin')
Jens Wiklander8f7de3f2014-12-04 08:04:01 +0100117
Jerome Forissier15a991a2018-11-14 10:59:55 +0100118 parser.add_argument('--tee_pageable_bin',
119 required=True,
120 help='The input tee_pageable.bin')
Jens Wiklander8f7de3f2014-12-04 08:04:01 +0100121
Jerome Forissier15a991a2018-11-14 10:59:55 +0100122 parser.add_argument('--out',
123 required=False, type=argparse.FileType('wb'),
124 help='The output tee.bin')
Jens Wiklander8f7de3f2014-12-04 08:04:01 +0100125
Jerome Forissier15a991a2018-11-14 10:59:55 +0100126 parser.add_argument('--out_header_v2',
127 required=False, type=argparse.FileType('wb'),
128 help='The output tee_header_v2.bin')
Summer Qinac3cc6c2017-04-18 13:59:03 +0100129
Jerome Forissier15a991a2018-11-14 10:59:55 +0100130 parser.add_argument('--out_pager_v2',
131 required=False, type=argparse.FileType('wb'),
132 help='The output tee_pager_v2.bin')
Summer Qinac3cc6c2017-04-18 13:59:03 +0100133
Jerome Forissier15a991a2018-11-14 10:59:55 +0100134 parser.add_argument('--out_pageable_v2',
135 required=False, type=argparse.FileType('wb'),
136 help='The output tee_pageable_v2.bin')
Summer Qinac3cc6c2017-04-18 13:59:03 +0100137
Jerome Forissier15a991a2018-11-14 10:59:55 +0100138 return parser.parse_args()
139
Jens Wiklander8f7de3f2014-12-04 08:04:01 +0100140
141def main():
Jerome Forissier15a991a2018-11-14 10:59:55 +0100142 args = get_args()
143 init_bin_size = args.init_size
144 tee_pager_fname = args.tee_pager_bin
145 tee_pageable_fname = args.tee_pageable_bin
146 pager_input_size = os.path.getsize(tee_pager_fname)
147 paged_input_size = os.path.getsize(tee_pageable_fname)
Volodymyr Babchukdbf259b2018-12-18 23:54:26 +0200148 hash_size = paged_input_size // (4 * 1024) * \
Jerome Forissier15a991a2018-11-14 10:59:55 +0100149 hashlib.sha256().digest_size
Jens Wiklander8f7de3f2014-12-04 08:04:01 +0100150
Jerome Forissier15a991a2018-11-14 10:59:55 +0100151 if paged_input_size % (4 * 1024) != 0:
Rouven Czerwinskibbaeed42019-08-07 20:07:00 +0200152 print("Error: pageable size not a multiple of 4K: {}".format(
153 paged_input_size))
Jerome Forissier15a991a2018-11-14 10:59:55 +0100154 sys.exit(1)
Jens Wiklander8f7de3f2014-12-04 08:04:01 +0100155
Jerome Forissier15a991a2018-11-14 10:59:55 +0100156 init_size = pager_input_size + \
157 min(init_bin_size, paged_input_size) + \
158 hash_size
159 paged_size = paged_input_size - \
160 min(init_bin_size, paged_input_size)
Jens Wiklander8f7de3f2014-12-04 08:04:01 +0100161
Jerome Forissier15a991a2018-11-14 10:59:55 +0100162 if args.out is not None:
163 outf = args.out
164 write_header_v1(outf, init_size, args, paged_size)
165 append_to(outf, 0, tee_pager_fname)
166 append_to(outf, 0, tee_pageable_fname, init_bin_size)
167 append_hashes(outf, tee_pageable_fname)
168 append_to(outf, init_bin_size, tee_pageable_fname)
169 outf.close()
Summer Qinac3cc6c2017-04-18 13:59:03 +0100170
Jerome Forissier15a991a2018-11-14 10:59:55 +0100171 if args.out_header_v2 is not None:
172 outf = args.out_header_v2
173 write_header_v2(outf, init_size, args, paged_size)
174 outf.close()
Summer Qinac3cc6c2017-04-18 13:59:03 +0100175
Jerome Forissier15a991a2018-11-14 10:59:55 +0100176 if args.out_pager_v2 is not None:
177 outf = args.out_pager_v2
178 append_to(outf, 0, tee_pager_fname)
179 append_to(outf, 0, tee_pageable_fname, init_bin_size)
180 append_hashes(outf, tee_pageable_fname)
181 outf.close()
Summer Qinac3cc6c2017-04-18 13:59:03 +0100182
Jerome Forissier15a991a2018-11-14 10:59:55 +0100183 if args.out_pageable_v2 is not None:
184 outf = args.out_pageable_v2
185 append_to(outf, init_bin_size, tee_pageable_fname)
186 outf.close()
187
Jens Wiklander8f7de3f2014-12-04 08:04:01 +0100188
189if __name__ == "__main__":
Jerome Forissier15a991a2018-11-14 10:59:55 +0100190 main()