blob: eef39ea079480ef64f92dbe574ffb4c6eae9960e [file] [log] [blame]
Jens Wiklander8f7de3f2014-12-04 08:04:01 +01001#!/usr/bin/env python
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# All rights reserved.
6#
7# Redistribution and use in source and binary forms, with or without
8# modification, are permitted provided that the following conditions are met:
9#
10# 1. Redistributions of source code must retain the above copyright notice,
11# this list of conditions and the following disclaimer.
12#
13# 2. Redistributions in binary form must reproduce the above copyright notice,
14# this list of conditions and the following disclaimer in the documentation
15# and/or other materials provided with the distribution.
16#
17# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
21# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27# POSSIBILITY OF SUCH DAMAGE.
28#
29
30import argparse
31import sys
32import shutil
33import os
34import struct
35import hashlib
36
Jerome Forissier7a976652015-05-06 17:23:50 +020037arch_id = {'arm32': 0, 'arm64': 1}
Summer Qinac3cc6c2017-04-18 13:59:03 +010038image_id = {'pager': 0, 'paged': 1}
Jens Wiklander8f7de3f2014-12-04 08:04:01 +010039
Summer Qinac3cc6c2017-04-18 13:59:03 +010040def write_header_v1(outf, init_size, args, paged_size):
Jens Wiklander8f7de3f2014-12-04 08:04:01 +010041 magic = 0x4554504f # 'OPTE'
42 version = 1;
43 outf.write(struct.pack('<IBBHIIIII', \
Jerome Forissier7a976652015-05-06 17:23:50 +020044 magic, version, arch_id[args.arch], args.flags, init_size, \
Jens Wiklander8f7de3f2014-12-04 08:04:01 +010045 args.init_load_addr_hi, args.init_load_addr_lo, \
46 args.init_mem_usage, paged_size))
Summer Qinac3cc6c2017-04-18 13:59:03 +010047
48def write_header_v2(outf, init_size, args, paged_size):
49 magic = 0x4554504f # 'OPTE'
50 version = 2
51 nb_images = 1 if paged_size == 0 else 2
52 outf.write(struct.pack('<IBBHI', \
53 magic, version, arch_id[args.arch], args.flags, nb_images))
54 outf.write(struct.pack('<IIII', \
55 args.init_load_addr_hi, args.init_load_addr_lo, \
56 image_id['pager'], init_size))
57 if nb_images == 2:
58 outf.write(struct.pack('<IIII', \
59 0xffffffff, 0xffffffff, image_id['paged'], paged_size))
Jens Wiklander8f7de3f2014-12-04 08:04:01 +010060
61def append_to(outf, start_offs, in_fname, max_bytes=0xffffffff):
62 #print "Appending %s@0x%x 0x%x bytes at position 0x%x" % \
63 #( in_fname, start_offs, max_bytes, int(outf.tell()) )
Joakim Bech47805ee2016-07-29 17:48:39 +020064 inf = open(in_fname, 'rb');
Jens Wiklander8f7de3f2014-12-04 08:04:01 +010065 inf.seek(start_offs)
66 while True :
67 nbytes = min(16 * 1024, max_bytes)
68 if nbytes == 0 :
69 break
70 #print "Reading %s %d bytes" % (in_fname, nbytes)
71 buf = inf.read(nbytes)
72 if not buf :
73 break
74 outf.write(buf)
75 max_bytes -= len(buf)
76 inf.close()
77
78def append_hashes(outf, in_fname):
79 page_size = 4 * 1024
80
81 inf = open(in_fname, 'r')
82 while True :
83 page = inf.read(page_size)
84 if len(page) == page_size :
85 #print "Writing hash at position 0x%x" % \
86 #int(outf.tell())
87 outf.write(hashlib.sha256(page).digest())
88 elif len(page) == 0 :
89 break
90 else :
Joakim Bech47805ee2016-07-29 17:48:39 +020091 print("Error: short read, got " + repr(len(page)))
Jens Wiklander8f7de3f2014-12-04 08:04:01 +010092 sys.exit(1)
93
94 inf.close()
95
96def int_parse(str):
97 return int(str, 0)
98
99def get_args():
100 parser = argparse.ArgumentParser()
101 parser.add_argument('--arch', required=True, \
Jerome Forissier7a976652015-05-06 17:23:50 +0200102 choices=arch_id.keys(), \
103 help='Architecture')
Jens Wiklander8f7de3f2014-12-04 08:04:01 +0100104
105 parser.add_argument('--flags', \
106 type=int, default=0, \
107 help='Flags, currently none defined')
108
109 parser.add_argument('--init_size', \
110 required=True, type=int_parse, \
111 help='Size of initialization part of binary')
112
113 parser.add_argument('--init_load_addr_hi', \
114 type=int_parse, default=0, \
115 help='Upper 32 bits of load address of binary')
116
117 parser.add_argument('--init_load_addr_lo', \
118 required=True, type=int_parse, \
119 help='Lower 32 bits of load address of binary')
120
121 parser.add_argument('--init_mem_usage', \
122 required=True, type=int_parse, \
123 help='Total amount of used memory when initializing');
124
125 parser.add_argument('--tee_pager_bin', \
126 required=True, \
127 help='The input tee_pager.bin')
128
Jerome Forissier30ca3222015-03-18 15:01:52 +0100129 parser.add_argument('--tee_pageable_bin', \
Jens Wiklander8f7de3f2014-12-04 08:04:01 +0100130 required=True, \
Jerome Forissier30ca3222015-03-18 15:01:52 +0100131 help='The input tee_pageable.bin')
Jens Wiklander8f7de3f2014-12-04 08:04:01 +0100132
133 parser.add_argument('--out', \
Summer Qinac3cc6c2017-04-18 13:59:03 +0100134 required=False, type=argparse.FileType('wb'), \
Jens Wiklander8f7de3f2014-12-04 08:04:01 +0100135 help='The output tee.bin')
136
Summer Qinac3cc6c2017-04-18 13:59:03 +0100137 parser.add_argument('--out_header_v2', \
138 required=False, type=argparse.FileType('wb'), \
139 help='The output tee_header_v2.bin')
140
141 parser.add_argument('--out_pager_v2', \
142 required=False, type=argparse.FileType('wb'), \
143 help='The output tee_pager_v2.bin')
144
145 parser.add_argument('--out_pageable_v2', \
146 required=False, type=argparse.FileType('wb'), \
147 help='The output tee_pageable_v2.bin')
148
Jens Wiklander8f7de3f2014-12-04 08:04:01 +0100149 return parser.parse_args();
150
151def main():
152 args = get_args()
Jerome Forissier30ca3222015-03-18 15:01:52 +0100153 init_bin_size = args.init_size
154 tee_pager_fname = args.tee_pager_bin
155 tee_pageable_fname = args.tee_pageable_bin
Summer Qinac3cc6c2017-04-18 13:59:03 +0100156 pager_input_size = os.path.getsize(tee_pager_fname);
157 paged_input_size = os.path.getsize(tee_pageable_fname);
158 hash_size = paged_input_size / (4 * 1024) * \
159 hashlib.sha256().digest_size
Jens Wiklander8f7de3f2014-12-04 08:04:01 +0100160
Summer Qinac3cc6c2017-04-18 13:59:03 +0100161 if paged_input_size % (4 * 1024) != 0:
162 print("Error: pageable size not a multiple of 4K:" + \
163 repr(paged_input_size))
164 sys.exit(1)
Jens Wiklander8f7de3f2014-12-04 08:04:01 +0100165
Summer Qinac3cc6c2017-04-18 13:59:03 +0100166 init_size = pager_input_size + \
167 min(init_bin_size, paged_input_size) + \
168 hash_size
169 paged_size = paged_input_size - \
170 min(init_bin_size, paged_input_size)
Jens Wiklander8f7de3f2014-12-04 08:04:01 +0100171
Summer Qinac3cc6c2017-04-18 13:59:03 +0100172 if args.out is not None:
173 outf = args.out
174 write_header_v1(outf, init_size, args, paged_size)
175 append_to(outf, 0, tee_pager_fname)
176 append_to(outf, 0, tee_pageable_fname, init_bin_size)
177 append_hashes(outf, tee_pageable_fname)
178 append_to(outf, init_bin_size, tee_pageable_fname)
179 outf.close()
180
181 if args.out_header_v2 is not None:
182 outf = args.out_header_v2
183 write_header_v2(outf, init_size, args, paged_size)
184 outf.close()
185
186 if args.out_pager_v2 is not None:
187 outf = args.out_pager_v2
188 append_to(outf, 0, tee_pager_fname)
189 append_to(outf, 0, tee_pageable_fname, init_bin_size)
190 append_hashes(outf, tee_pageable_fname)
191 outf.close()
192
193 if args.out_pageable_v2 is not None:
194 outf = args.out_pageable_v2
195 append_to(outf, init_bin_size, tee_pageable_fname)
196 outf.close()
Jens Wiklander8f7de3f2014-12-04 08:04:01 +0100197
198if __name__ == "__main__":
199 main()