blob: b080d482af91b56a064c3d38adbba88b169f338c [file] [log] [blame]
Simon Glassd977ecd2016-07-03 09:40:46 -06001# SPDX-License-Identifier: GPL-2.0+
Tom Rini10e47792018-05-06 17:58:06 -04002# Copyright (c) 2016, Google Inc.
Simon Glassd977ecd2016-07-03 09:40:46 -06003#
4# U-Boot Verified Boot Test
5
6"""
7This tests verified boot in the following ways:
8
9For image verification:
10- Create FIT (unsigned) with mkimage
11- Check that verification shows that no keys are verified
12- Sign image
13- Check that verification shows that a key is now verified
14
15For configuration verification:
16- Corrupt signature and check for failure
17- Create FIT (with unsigned configuration) with mkimage
Simon Glassd5deca02016-07-31 17:35:04 -060018- Check that image verification works
Simon Glassd977ecd2016-07-03 09:40:46 -060019- Sign the FIT and mark the key as 'required' for verification
20- Check that image verification works
21- Corrupt the signature
22- Check that image verification no-longer works
23
24Tests run with both SHA1 and SHA256 hashing.
25"""
26
Simon Glasse9eeca82021-09-19 15:14:48 -060027import os
Simon Glass5e942f72021-02-15 17:08:08 -070028import shutil
Teddy Reede6a47832018-06-09 11:38:05 -040029import struct
Simon Glass861b5042020-03-18 11:44:05 -060030import pytest
Simon Glassd977ecd2016-07-03 09:40:46 -060031import u_boot_utils as util
Simon Glassc35df8f2020-03-18 11:43:59 -060032import vboot_forge
Simon Glass5e942f72021-02-15 17:08:08 -070033import vboot_evil
Simon Glassd977ecd2016-07-03 09:40:46 -060034
Simon Glass5e942f72021-02-15 17:08:08 -070035# Only run the full suite on a few combinations, since it doesn't add any more
36# test coverage.
Simon Glassa0ba39d2020-03-18 11:44:00 -060037TESTDATA = [
Simon Glasse9eeca82021-09-19 15:14:48 -060038 ['sha1-basic', 'sha1', '', None, False, True],
39 ['sha1-pad', 'sha1', '', '-E -p 0x10000', False, False],
40 ['sha1-pss', 'sha1', '-pss', None, False, False],
41 ['sha1-pss-pad', 'sha1', '-pss', '-E -p 0x10000', False, False],
42 ['sha256-basic', 'sha256', '', None, False, False],
43 ['sha256-pad', 'sha256', '', '-E -p 0x10000', False, False],
44 ['sha256-pss', 'sha256', '-pss', None, False, False],
45 ['sha256-pss-pad', 'sha256', '-pss', '-E -p 0x10000', False, False],
46 ['sha256-pss-required', 'sha256', '-pss', None, True, False],
47 ['sha256-pss-pad-required', 'sha256', '-pss', '-E -p 0x10000', True, True],
Jamin Lin5975ad72022-01-19 16:23:21 +080048 ['sha384-basic', 'sha384', '', None, False, False],
49 ['sha384-pad', 'sha384', '', '-E -p 0x10000', False, False],
Simon Glassa0ba39d2020-03-18 11:44:00 -060050]
51
Michal Simek6e035ab2016-07-18 08:49:08 +020052@pytest.mark.boardspec('sandbox')
Simon Glassd977ecd2016-07-03 09:40:46 -060053@pytest.mark.buildconfigspec('fit_signature')
Stephen Warren2079db32017-09-18 11:11:49 -060054@pytest.mark.requiredtool('dtc')
55@pytest.mark.requiredtool('fdtget')
56@pytest.mark.requiredtool('fdtput')
57@pytest.mark.requiredtool('openssl')
Simon Glasse9eeca82021-09-19 15:14:48 -060058@pytest.mark.parametrize("name,sha_algo,padding,sign_options,required,full_test",
Simon Glass5e942f72021-02-15 17:08:08 -070059 TESTDATA)
Simon Glasse9eeca82021-09-19 15:14:48 -060060def test_vboot(u_boot_console, name, sha_algo, padding, sign_options, required,
Simon Glass5e942f72021-02-15 17:08:08 -070061 full_test):
Simon Glassd977ecd2016-07-03 09:40:46 -060062 """Test verified boot signing with mkimage and verification with 'bootm'.
63
64 This works using sandbox only as it needs to update the device tree used
65 by U-Boot to hold public keys from the signing process.
66
67 The SHA1 and SHA256 tests are combined into a single test since the
68 key-generation process is quite slow and we want to avoid doing it twice.
69 """
70 def dtc(dts):
Simon Glassd5deca02016-07-31 17:35:04 -060071 """Run the device tree compiler to compile a .dts file
Simon Glassd977ecd2016-07-03 09:40:46 -060072
73 The output file will be the same as the input file but with a .dtb
74 extension.
75
76 Args:
77 dts: Device tree file to compile.
78 """
79 dtb = dts.replace('.dts', '.dtb')
Simon Glassba8116c2016-07-31 17:35:05 -060080 util.run_and_log(cons, 'dtc %s %s%s -O dtb '
81 '-o %s%s' % (dtc_args, datadir, dts, tmpdir, dtb))
Simon Glassd977ecd2016-07-03 09:40:46 -060082
Simon Glass5e942f72021-02-15 17:08:08 -070083 def run_bootm(sha_algo, test_type, expect_string, boots, fit=None):
Simon Glassd977ecd2016-07-03 09:40:46 -060084 """Run a 'bootm' command U-Boot.
85
86 This always starts a fresh U-Boot instance since the device tree may
87 contain a new public key.
88
89 Args:
Simon Glassf223c732016-07-31 17:35:06 -060090 test_type: A string identifying the test type.
91 expect_string: A string which is expected in the output.
92 sha_algo: Either 'sha1' or 'sha256', to select the algorithm to
93 use.
Tom Rinib65ce462016-09-18 09:46:58 -040094 boots: A boolean that is True if Linux should boot and False if
95 we are expected to not boot
Simon Glass5e942f72021-02-15 17:08:08 -070096 fit: FIT filename to load and verify
Simon Glassd977ecd2016-07-03 09:40:46 -060097 """
Simon Glass5e942f72021-02-15 17:08:08 -070098 if not fit:
99 fit = '%stest.fit' % tmpdir
Simon Glass37c2ce12016-07-31 17:35:08 -0600100 cons.restart_uboot()
Simon Glass2a40d832016-07-31 17:35:07 -0600101 with cons.log.section('Verified boot %s %s' % (sha_algo, test_type)):
102 output = cons.run_command_list(
Simon Glass5e942f72021-02-15 17:08:08 -0700103 ['host load hostfs - 100 %s' % fit,
Simon Glass861b5042020-03-18 11:44:05 -0600104 'fdt addr 100',
105 'bootm 100'])
106 assert expect_string in ''.join(output)
Tom Rinib65ce462016-09-18 09:46:58 -0400107 if boots:
Simon Glass861b5042020-03-18 11:44:05 -0600108 assert 'sandbox: continuing, as we cannot run' in ''.join(output)
Philippe Reynes1d5ef522019-09-18 16:04:53 +0200109 else:
Simon Glass724c03b2020-03-18 11:44:04 -0600110 assert('sandbox: continuing, as we cannot run'
111 not in ''.join(output))
Simon Glassd977ecd2016-07-03 09:40:46 -0600112
113 def make_fit(its):
Simon Glassd5deca02016-07-31 17:35:04 -0600114 """Make a new FIT from the .its source file.
Simon Glassd977ecd2016-07-03 09:40:46 -0600115
116 This runs 'mkimage -f' to create a new FIT.
117
118 Args:
Simon Glassd5deca02016-07-31 17:35:04 -0600119 its: Filename containing .its source.
Simon Glassd977ecd2016-07-03 09:40:46 -0600120 """
121 util.run_and_log(cons, [mkimage, '-D', dtc_args, '-f',
122 '%s%s' % (datadir, its), fit])
123
Philippe Reynes2fbd17c2020-04-29 15:26:16 +0200124 def sign_fit(sha_algo, options):
Simon Glassd977ecd2016-07-03 09:40:46 -0600125 """Sign the FIT
126
127 Signs the FIT and writes the signature into it. It also writes the
128 public key into the dtb.
Simon Glassf223c732016-07-31 17:35:06 -0600129
130 Args:
131 sha_algo: Either 'sha1' or 'sha256', to select the algorithm to
132 use.
Philippe Reynes2fbd17c2020-04-29 15:26:16 +0200133 options: Options to provide to mkimage.
Simon Glassd977ecd2016-07-03 09:40:46 -0600134 """
Philippe Reynes2fbd17c2020-04-29 15:26:16 +0200135 args = [mkimage, '-F', '-k', tmpdir, '-K', dtb, '-r', fit]
136 if options:
137 args += options.split(' ')
Simon Glassf223c732016-07-31 17:35:06 -0600138 cons.log.action('%s: Sign images' % sha_algo)
Philippe Reynes2fbd17c2020-04-29 15:26:16 +0200139 util.run_and_log(cons, args)
Simon Glassd977ecd2016-07-03 09:40:46 -0600140
Thirupathaiah Annapureddy7e703f72020-08-16 23:01:10 -0700141 def sign_fit_norequire(sha_algo, options):
142 """Sign the FIT
143
144 Signs the FIT and writes the signature into it. It also writes the
145 public key into the dtb. It does not mark key as 'required' in dtb.
146
147 Args:
148 sha_algo: Either 'sha1' or 'sha256', to select the algorithm to
149 use.
150 options: Options to provide to mkimage.
151 """
152 args = [mkimage, '-F', '-k', tmpdir, '-K', dtb, fit]
153 if options:
154 args += options.split(' ')
155 cons.log.action('%s: Sign images' % sha_algo)
156 util.run_and_log(cons, args)
157
Teddy Reede6a47832018-06-09 11:38:05 -0400158 def replace_fit_totalsize(size):
159 """Replace FIT header's totalsize with something greater.
160
161 The totalsize must be less than or equal to FIT_SIGNATURE_MAX_SIZE.
162 If the size is greater, the signature verification should return false.
163
164 Args:
165 size: The new totalsize of the header
166
167 Returns:
168 prev_size: The previous totalsize read from the header
169 """
170 total_size = 0
171 with open(fit, 'r+b') as handle:
172 handle.seek(4)
173 total_size = handle.read(4)
174 handle.seek(4)
175 handle.write(struct.pack(">I", size))
176 return struct.unpack(">I", total_size)[0]
177
Simon Glassb4a2f6a2020-03-18 11:44:07 -0600178 def create_rsa_pair(name):
179 """Generate a new RSA key paid and certificate
180
181 Args:
182 name: Name of of the key (e.g. 'dev')
183 """
184 public_exponent = 65537
Jamin Lin5975ad72022-01-19 16:23:21 +0800185
186 if sha_algo == "sha384":
187 rsa_keygen_bits = 3072
188 else:
189 rsa_keygen_bits = 2048
190
Simon Glassb4a2f6a2020-03-18 11:44:07 -0600191 util.run_and_log(cons, 'openssl genpkey -algorithm RSA -out %s%s.key '
Jamin Lin5975ad72022-01-19 16:23:21 +0800192 '-pkeyopt rsa_keygen_bits:%d '
Simon Glassb4a2f6a2020-03-18 11:44:07 -0600193 '-pkeyopt rsa_keygen_pubexp:%d' %
Jamin Lin5975ad72022-01-19 16:23:21 +0800194 (tmpdir, name, rsa_keygen_bits, public_exponent))
Simon Glassb4a2f6a2020-03-18 11:44:07 -0600195
196 # Create a certificate containing the public key
197 util.run_and_log(cons, 'openssl req -batch -new -x509 -key %s%s.key '
198 '-out %s%s.crt' % (tmpdir, name, tmpdir, name))
199
Philippe Reynes2fbd17c2020-04-29 15:26:16 +0200200 def test_with_algo(sha_algo, padding, sign_options):
Simon Glassd5deca02016-07-31 17:35:04 -0600201 """Test verified boot with the given hash algorithm.
Simon Glassd977ecd2016-07-03 09:40:46 -0600202
203 This is the main part of the test code. The same procedure is followed
204 for both hashing algorithms.
205
206 Args:
Simon Glassf223c732016-07-31 17:35:06 -0600207 sha_algo: Either 'sha1' or 'sha256', to select the algorithm to
208 use.
Philippe Reynes2fbd17c2020-04-29 15:26:16 +0200209 padding: Either '' or '-pss', to select the padding to use for the
210 rsa signature algorithm.
211 sign_options: Options to mkimage when signing a fit image.
Simon Glassd977ecd2016-07-03 09:40:46 -0600212 """
Simon Glassdc3ab7e2016-07-31 17:35:02 -0600213 # Compile our device tree files for kernel and U-Boot. These are
214 # regenerated here since mkimage will modify them (by adding a
215 # public key) below.
Simon Glassd977ecd2016-07-03 09:40:46 -0600216 dtc('sandbox-kernel.dts')
217 dtc('sandbox-u-boot.dts')
218
219 # Build the FIT, but don't sign anything yet
Simon Glassf223c732016-07-31 17:35:06 -0600220 cons.log.action('%s: Test FIT with signed images' % sha_algo)
Simon Glass861b5042020-03-18 11:44:05 -0600221 make_fit('sign-images-%s%s.its' % (sha_algo, padding))
Tom Rinib65ce462016-09-18 09:46:58 -0400222 run_bootm(sha_algo, 'unsigned images', 'dev-', True)
Simon Glassd977ecd2016-07-03 09:40:46 -0600223
224 # Sign images with our dev keys
Philippe Reynes2fbd17c2020-04-29 15:26:16 +0200225 sign_fit(sha_algo, sign_options)
Tom Rinib65ce462016-09-18 09:46:58 -0400226 run_bootm(sha_algo, 'signed images', 'dev+', True)
Simon Glassd977ecd2016-07-03 09:40:46 -0600227
228 # Create a fresh .dtb without the public keys
229 dtc('sandbox-u-boot.dts')
230
Simon Glassf223c732016-07-31 17:35:06 -0600231 cons.log.action('%s: Test FIT with signed configuration' % sha_algo)
Simon Glass861b5042020-03-18 11:44:05 -0600232 make_fit('sign-configs-%s%s.its' % (sha_algo, padding))
Tom Rinib65ce462016-09-18 09:46:58 -0400233 run_bootm(sha_algo, 'unsigned config', '%s+ OK' % sha_algo, True)
Simon Glassd977ecd2016-07-03 09:40:46 -0600234
235 # Sign images with our dev keys
Philippe Reynes2fbd17c2020-04-29 15:26:16 +0200236 sign_fit(sha_algo, sign_options)
Tom Rinib65ce462016-09-18 09:46:58 -0400237 run_bootm(sha_algo, 'signed config', 'dev+', True)
Simon Glassd977ecd2016-07-03 09:40:46 -0600238
Simon Glassf223c732016-07-31 17:35:06 -0600239 cons.log.action('%s: Check signed config on the host' % sha_algo)
Simon Glassd977ecd2016-07-03 09:40:46 -0600240
Simon Glassf411a892020-03-18 11:43:58 -0600241 util.run_and_log(cons, [fit_check_sign, '-f', fit, '-k', dtb])
Simon Glassd977ecd2016-07-03 09:40:46 -0600242
Simon Glass5e942f72021-02-15 17:08:08 -0700243 if full_test:
Simon Glassb823daa2021-02-15 17:08:12 -0700244 # Make sure that U-Boot checks that the config is in the list of
245 # hashed nodes. If it isn't, a security bypass is possible.
Simon Glass5e942f72021-02-15 17:08:08 -0700246 ffit = '%stest.forged.fit' % tmpdir
247 shutil.copyfile(fit, ffit)
248 with open(ffit, 'rb') as fd:
249 root, strblock = vboot_forge.read_fdt(fd)
250 root, strblock = vboot_forge.manipulate(root, strblock)
251 with open(ffit, 'w+b') as fd:
252 vboot_forge.write_fdt(root, strblock, fd)
253 util.run_and_log_expect_exception(
254 cons, [fit_check_sign, '-f', ffit, '-k', dtb],
255 1, 'Failed to verify required signature')
256
257 run_bootm(sha_algo, 'forged config', 'Bad Data Hash', False, ffit)
Simon Glassc35df8f2020-03-18 11:43:59 -0600258
Simon Glass5e942f72021-02-15 17:08:08 -0700259 # Try adding an evil root node. This should be detected.
260 efit = '%stest.evilf.fit' % tmpdir
261 shutil.copyfile(fit, efit)
262 vboot_evil.add_evil_node(fit, efit, evil_kernel, 'fakeroot')
263
264 util.run_and_log_expect_exception(
265 cons, [fit_check_sign, '-f', efit, '-k', dtb],
266 1, 'Failed to verify required signature')
Simon Glass19d2c022021-02-15 17:08:11 -0700267 run_bootm(sha_algo, 'evil fakeroot', 'Bad FIT kernel image format',
268 False, efit)
Simon Glass5e942f72021-02-15 17:08:08 -0700269
270 # Try adding an @ to the kernel node name. This should be detected.
271 efit = '%stest.evilk.fit' % tmpdir
272 shutil.copyfile(fit, efit)
273 vboot_evil.add_evil_node(fit, efit, evil_kernel, 'kernel@')
274
Simon Glassb823daa2021-02-15 17:08:12 -0700275 msg = 'Signature checking prevents use of unit addresses (@) in nodes'
Simon Glass5e942f72021-02-15 17:08:08 -0700276 util.run_and_log_expect_exception(
277 cons, [fit_check_sign, '-f', efit, '-k', dtb],
Simon Glassb823daa2021-02-15 17:08:12 -0700278 1, msg)
279 run_bootm(sha_algo, 'evil kernel@', msg, False, efit)
Simon Glassc35df8f2020-03-18 11:43:59 -0600280
281 # Create a new properly signed fit and replace header bytes
282 make_fit('sign-configs-%s%s.its' % (sha_algo, padding))
Philippe Reynes2fbd17c2020-04-29 15:26:16 +0200283 sign_fit(sha_algo, sign_options)
Teddy Reede6a47832018-06-09 11:38:05 -0400284 bcfg = u_boot_console.config.buildconfig
285 max_size = int(bcfg.get('config_fit_signature_max_size', 0x10000000), 0)
286 existing_size = replace_fit_totalsize(max_size + 1)
Simon Glass724c03b2020-03-18 11:44:04 -0600287 run_bootm(sha_algo, 'Signed config with bad hash', 'Bad Data Hash',
288 False)
Teddy Reede6a47832018-06-09 11:38:05 -0400289 cons.log.action('%s: Check overflowed FIT header totalsize' % sha_algo)
290
291 # Replace with existing header bytes
292 replace_fit_totalsize(existing_size)
293 run_bootm(sha_algo, 'signed config', 'dev+', True)
294 cons.log.action('%s: Check default FIT header totalsize' % sha_algo)
295
Simon Glassd977ecd2016-07-03 09:40:46 -0600296 # Increment the first byte of the signature, which should cause failure
Simon Glassba8116c2016-07-31 17:35:05 -0600297 sig = util.run_and_log(cons, 'fdtget -t bx %s %s value' %
298 (fit, sig_node))
Simon Glassd977ecd2016-07-03 09:40:46 -0600299 byte_list = sig.split()
300 byte = int(byte_list[0], 16)
Simon Glassdc3ab7e2016-07-31 17:35:02 -0600301 byte_list[0] = '%x' % (byte + 1)
Simon Glassd977ecd2016-07-03 09:40:46 -0600302 sig = ' '.join(byte_list)
Simon Glassba8116c2016-07-31 17:35:05 -0600303 util.run_and_log(cons, 'fdtput -t bx %s %s value %s' %
304 (fit, sig_node, sig))
Simon Glassd977ecd2016-07-03 09:40:46 -0600305
Simon Glass724c03b2020-03-18 11:44:04 -0600306 run_bootm(sha_algo, 'Signed config with bad hash', 'Bad Data Hash',
307 False)
Simon Glassd977ecd2016-07-03 09:40:46 -0600308
Simon Glassf223c732016-07-31 17:35:06 -0600309 cons.log.action('%s: Check bad config on the host' % sha_algo)
Simon Glass861b5042020-03-18 11:44:05 -0600310 util.run_and_log_expect_exception(
311 cons, [fit_check_sign, '-f', fit, '-k', dtb],
312 1, 'Failed to verify required signature')
Simon Glassd977ecd2016-07-03 09:40:46 -0600313
Philippe Reynes2fbd17c2020-04-29 15:26:16 +0200314 def test_required_key(sha_algo, padding, sign_options):
Philippe Reynes1d5ef522019-09-18 16:04:53 +0200315 """Test verified boot with the given hash algorithm.
316
Simon Glass724c03b2020-03-18 11:44:04 -0600317 This function tests if U-Boot rejects an image when a required key isn't
318 used to sign a FIT.
Philippe Reynes1d5ef522019-09-18 16:04:53 +0200319
320 Args:
Simon Glass724c03b2020-03-18 11:44:04 -0600321 sha_algo: Either 'sha1' or 'sha256', to select the algorithm to use
Philippe Reynes2fbd17c2020-04-29 15:26:16 +0200322 padding: Either '' or '-pss', to select the padding to use for the
323 rsa signature algorithm.
324 sign_options: Options to mkimage when signing a fit image.
Philippe Reynes1d5ef522019-09-18 16:04:53 +0200325 """
326 # Compile our device tree files for kernel and U-Boot. These are
327 # regenerated here since mkimage will modify them (by adding a
328 # public key) below.
329 dtc('sandbox-kernel.dts')
330 dtc('sandbox-u-boot.dts')
331
Philippe Reynes1d5ef522019-09-18 16:04:53 +0200332 cons.log.action('%s: Test FIT with configs images' % sha_algo)
Simon Glass724c03b2020-03-18 11:44:04 -0600333
334 # Build the FIT with prod key (keys required) and sign it. This puts the
335 # signature into sandbox-u-boot.dtb, marked 'required'
Simon Glass861b5042020-03-18 11:44:05 -0600336 make_fit('sign-configs-%s%s-prod.its' % (sha_algo, padding))
Philippe Reynes2fbd17c2020-04-29 15:26:16 +0200337 sign_fit(sha_algo, sign_options)
Simon Glass724c03b2020-03-18 11:44:04 -0600338
339 # Build the FIT with dev key (keys NOT required). This adds the
340 # signature into sandbox-u-boot.dtb, NOT marked 'required'.
Simon Glass861b5042020-03-18 11:44:05 -0600341 make_fit('sign-configs-%s%s.its' % (sha_algo, padding))
Thirupathaiah Annapureddy7e703f72020-08-16 23:01:10 -0700342 sign_fit_norequire(sha_algo, sign_options)
Philippe Reynes1d5ef522019-09-18 16:04:53 +0200343
Simon Glass724c03b2020-03-18 11:44:04 -0600344 # So now sandbox-u-boot.dtb two signatures, for the prod and dev keys.
345 # Only the prod key is set as 'required'. But FIT we just built has
Thirupathaiah Annapureddy7e703f72020-08-16 23:01:10 -0700346 # a dev signature only (sign_fit_norequire() overwrites the FIT).
Simon Glass724c03b2020-03-18 11:44:04 -0600347 # Try to boot the FIT with dev key. This FIT should not be accepted by
348 # U-Boot because the prod key is required.
349 run_bootm(sha_algo, 'required key', '', False)
Philippe Reynes1d5ef522019-09-18 16:04:53 +0200350
Thirupathaiah Annapureddy7e703f72020-08-16 23:01:10 -0700351 # Build the FIT with dev key (keys required) and sign it. This puts the
352 # signature into sandbox-u-boot.dtb, marked 'required'.
353 make_fit('sign-configs-%s%s.its' % (sha_algo, padding))
354 sign_fit(sha_algo, sign_options)
355
356 # Set the required-mode policy to "any".
357 # So now sandbox-u-boot.dtb two signatures, for the prod and dev keys.
358 # Both the dev and prod key are set as 'required'. But FIT we just built has
359 # a dev signature only (sign_fit() overwrites the FIT).
360 # Try to boot the FIT with dev key. This FIT should be accepted by
361 # U-Boot because the dev key is required and policy is "any" required key.
362 util.run_and_log(cons, 'fdtput -t s %s /signature required-mode any' %
363 (dtb))
364 run_bootm(sha_algo, 'multi required key', 'dev+', True)
365
366 # Set the required-mode policy to "all".
367 # So now sandbox-u-boot.dtb two signatures, for the prod and dev keys.
368 # Both the dev and prod key are set as 'required'. But FIT we just built has
369 # a dev signature only (sign_fit() overwrites the FIT).
370 # Try to boot the FIT with dev key. This FIT should not be accepted by
371 # U-Boot because the prod key is required and policy is "all" required key
372 util.run_and_log(cons, 'fdtput -t s %s /signature required-mode all' %
373 (dtb))
374 run_bootm(sha_algo, 'multi required key', '', False)
375
Simon Glassd977ecd2016-07-03 09:40:46 -0600376 cons = u_boot_console
Simon Glasse9eeca82021-09-19 15:14:48 -0600377 tmpdir = os.path.join(cons.config.result_dir, name) + '/'
378 if not os.path.exists(tmpdir):
379 os.mkdir(tmpdir)
Stephen Warren7047d952016-07-18 10:07:25 -0600380 datadir = cons.config.source_dir + '/test/py/tests/vboot/'
Simon Glassd977ecd2016-07-03 09:40:46 -0600381 fit = '%stest.fit' % tmpdir
382 mkimage = cons.config.build_dir + '/tools/mkimage'
383 fit_check_sign = cons.config.build_dir + '/tools/fit_check_sign'
384 dtc_args = '-I dts -O dtb -i %s' % tmpdir
385 dtb = '%ssandbox-u-boot.dtb' % tmpdir
Philippe Reynesa28e9222018-11-14 13:51:05 +0100386 sig_node = '/configurations/conf-1/signature'
Simon Glassd977ecd2016-07-03 09:40:46 -0600387
Simon Glassb4a2f6a2020-03-18 11:44:07 -0600388 create_rsa_pair('dev')
389 create_rsa_pair('prod')
Philippe Reynes1d5ef522019-09-18 16:04:53 +0200390
Simon Glassd977ecd2016-07-03 09:40:46 -0600391 # Create a number kernel image with zeroes
Simon Glass5e942f72021-02-15 17:08:08 -0700392 with open('%stest-kernel.bin' % tmpdir, 'wb') as fd:
393 fd.write(500 * b'\0')
394
395 # Create a second kernel image with ones
396 evil_kernel = '%stest-kernel1.bin' % tmpdir
397 with open(evil_kernel, 'wb') as fd:
398 fd.write(500 * b'\x01')
Simon Glassd977ecd2016-07-03 09:40:46 -0600399
400 try:
401 # We need to use our own device tree file. Remember to restore it
402 # afterwards.
403 old_dtb = cons.config.dtb
404 cons.config.dtb = dtb
Simon Glassa0ba39d2020-03-18 11:44:00 -0600405 if required:
Philippe Reynes2fbd17c2020-04-29 15:26:16 +0200406 test_required_key(sha_algo, padding, sign_options)
Simon Glassa0ba39d2020-03-18 11:44:00 -0600407 else:
Philippe Reynes2fbd17c2020-04-29 15:26:16 +0200408 test_with_algo(sha_algo, padding, sign_options)
Simon Glassd977ecd2016-07-03 09:40:46 -0600409 finally:
Simon Glass37c2ce12016-07-31 17:35:08 -0600410 # Go back to the original U-Boot with the correct dtb.
Simon Glassd977ecd2016-07-03 09:40:46 -0600411 cons.config.dtb = old_dtb
Simon Glass37c2ce12016-07-31 17:35:08 -0600412 cons.restart_uboot()