diff options
author | Klaus Heinrich Kiwi <klaus@linux.vnet.ibm.com> | 2021-03-26 17:14:10 -0300 |
---|---|---|
committer | Richard Purdie <richard.purdie@linuxfoundation.org> | 2021-04-06 11:36:51 +0100 |
commit | 03f39e81112c95450f1ed2ad8fb5306b2ac12d15 (patch) | |
tree | 1d0fb7c7d55f40e70b6ed2c55c838ca37f8abbee /meta/lib/oeqa | |
parent | 575cf33e6b7124899f2eb7c72afb67e67ad2a449 (diff) | |
download | poky-03f39e81112c95450f1ed2ad8fb5306b2ac12d15.tar.gz |
oe-selftest: Add U-Boot fitImage signing testcases
Derived from the similar kernel fitImage sign testcase, the U-Boot
fitImage testcases exercises the following fitimage.FitImageTest
scenarios:
* test_uboot_fit_image - create unsigned U-Boot fitImage
* test_uboot_sign_fit_image - create unsigned U-Boot fitImage in
addition to signed Kernel fitImage
* test_sign_standalone_uboot_fit_image - Create signed U-Boot fitImage
without a Kernel fitImage
* test_sign_cascaded_uboot_fit_image - Create and sign U-Boot and
Kernel fitImages
(From OE-Core rev: e71e4c617568496ae3bd6bb678f97b4f73cb43d8)
Signed-off-by: Klaus Heinrich Kiwi <klaus@linux.vnet.ibm.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Diffstat (limited to 'meta/lib/oeqa')
-rw-r--r-- | meta/lib/oeqa/selftest/cases/fitimage.py | 468 |
1 files changed, 468 insertions, 0 deletions
diff --git a/meta/lib/oeqa/selftest/cases/fitimage.py b/meta/lib/oeqa/selftest/cases/fitimage.py index 02692de822..b911fded74 100644 --- a/meta/lib/oeqa/selftest/cases/fitimage.py +++ b/meta/lib/oeqa/selftest/cases/fitimage.py | |||
@@ -231,6 +231,474 @@ UBOOT_MKIMAGE_SIGN_ARGS = "-c 'a smart comment'" | |||
231 | result = runCmd('grep "### uboot-mkimage signing wrapper message" %s/log.do_assemble_fitimage' % tempdir, ignore_status=True) | 231 | result = runCmd('grep "### uboot-mkimage signing wrapper message" %s/log.do_assemble_fitimage' % tempdir, ignore_status=True) |
232 | self.assertEqual(result.status, 0, 'UBOOT_MKIMAGE_SIGN did not work') | 232 | self.assertEqual(result.status, 0, 'UBOOT_MKIMAGE_SIGN did not work') |
233 | 233 | ||
234 | def test_uboot_fit_image(self): | ||
235 | """ | ||
236 | Summary: Check if Uboot FIT image and Image Tree Source | ||
237 | (its) are built and the Image Tree Source has the | ||
238 | correct fields. | ||
239 | Expected: 1. u-boot-fitImage and u-boot-its can be built | ||
240 | 2. The type, load address, entrypoint address and | ||
241 | default values of U-boot image are correct in the | ||
242 | Image Tree Source. Not all the fields are tested, | ||
243 | only the key fields that wont vary between | ||
244 | different architectures. | ||
245 | Product: oe-core | ||
246 | Author: Klaus Heinrich Kiwi <klaus@linux.vnet.ibm.com> | ||
247 | based on work by Usama Arif <usama.arif@arm.com> | ||
248 | """ | ||
249 | config = """ | ||
250 | # We need at least CONFIG_SPL_LOAD_FIT and CONFIG_SPL_OF_CONTROL set | ||
251 | MACHINE = "qemuarm" | ||
252 | UBOOT_MACHINE = "am57xx_evm_defconfig" | ||
253 | SPL_BINARY = "MLO" | ||
254 | |||
255 | # Enable creation of the U-Boot fitImage | ||
256 | UBOOT_FITIMAGE_ENABLE = "1" | ||
257 | |||
258 | # (U-boot) fitImage properties | ||
259 | UBOOT_LOADADDRESS = "0x80080000" | ||
260 | UBOOT_ENTRYPOINT = "0x80080000" | ||
261 | UBOOT_FIT_DESC = "A model description" | ||
262 | |||
263 | # Enable creation of Kernel fitImage | ||
264 | KERNEL_IMAGETYPES += " fitImage " | ||
265 | KERNEL_CLASSES = " kernel-fitimage" | ||
266 | UBOOT_SIGN_ENABLE = "1" | ||
267 | FIT_GENERATE_KEYS = "1" | ||
268 | UBOOT_SIGN_KEYDIR = "${TOPDIR}/signing-keys" | ||
269 | UBOOT_SIGN_KEYNAME = "oe-selftest" | ||
270 | FIT_SIGN_INDIVIDUAL = "1" | ||
271 | """ | ||
272 | self.write_config(config) | ||
273 | |||
274 | # The U-Boot fitImage is created as part of linux recipe | ||
275 | bitbake("virtual/kernel") | ||
276 | |||
277 | deploy_dir_image = get_bb_var('DEPLOY_DIR_IMAGE') | ||
278 | machine = get_bb_var('MACHINE') | ||
279 | fitimage_its_path = os.path.join(deploy_dir_image, | ||
280 | "u-boot-its-%s" % (machine,)) | ||
281 | fitimage_path = os.path.join(deploy_dir_image, | ||
282 | "u-boot-fitImage-%s" % (machine,)) | ||
283 | |||
284 | self.assertTrue(os.path.exists(fitimage_its_path), | ||
285 | "%s image tree source doesn't exist" % (fitimage_its_path)) | ||
286 | self.assertTrue(os.path.exists(fitimage_path), | ||
287 | "%s FIT image doesn't exist" % (fitimage_path)) | ||
288 | |||
289 | # Check that the type, load address, entrypoint address and default | ||
290 | # values for kernel and ramdisk in Image Tree Source are as expected. | ||
291 | # The order of fields in the below array is important. Not all the | ||
292 | # fields are tested, only the key fields that wont vary between | ||
293 | # different architectures. | ||
294 | its_field_check = [ | ||
295 | 'description = "A model description";', | ||
296 | 'type = "uboot";', | ||
297 | 'load = <0x80080000>;', | ||
298 | 'entry = <0x80080000>;', | ||
299 | 'default = "conf";', | ||
300 | 'loadables = "uboot";', | ||
301 | 'fdt = "fdt";' | ||
302 | ] | ||
303 | |||
304 | with open(fitimage_its_path) as its_file: | ||
305 | field_index = 0 | ||
306 | for line in its_file: | ||
307 | if field_index == len(its_field_check): | ||
308 | break | ||
309 | if its_field_check[field_index] in line: | ||
310 | field_index +=1 | ||
311 | |||
312 | if field_index != len(its_field_check): # if its equal, the test passed | ||
313 | self.assertTrue(field_index == len(its_field_check), | ||
314 | "Fields in Image Tree Source File %s did not match, error in finding %s" | ||
315 | % (fitimage_its_path, its_field_check[field_index])) | ||
316 | |||
317 | def test_uboot_sign_fit_image(self): | ||
318 | """ | ||
319 | Summary: Check if Uboot FIT image and Image Tree Source | ||
320 | (its) are built and the Image Tree Source has the | ||
321 | correct fields, in the scenario where the Kernel | ||
322 | is also creating/signing it's fitImage. | ||
323 | Expected: 1. u-boot-fitImage and u-boot-its can be built | ||
324 | 2. The type, load address, entrypoint address and | ||
325 | default values of U-boot image are correct in the | ||
326 | Image Tree Source. Not all the fields are tested, | ||
327 | only the key fields that wont vary between | ||
328 | different architectures. | ||
329 | Product: oe-core | ||
330 | Author: Klaus Heinrich Kiwi <klaus@linux.vnet.ibm.com> | ||
331 | based on work by Usama Arif <usama.arif@arm.com> | ||
332 | """ | ||
333 | config = """ | ||
334 | # We need at least CONFIG_SPL_LOAD_FIT and CONFIG_SPL_OF_CONTROL set | ||
335 | MACHINE = "qemuarm" | ||
336 | UBOOT_MACHINE = "am57xx_evm_defconfig" | ||
337 | SPL_BINARY = "MLO" | ||
338 | |||
339 | # Enable creation of the U-Boot fitImage | ||
340 | UBOOT_FITIMAGE_ENABLE = "1" | ||
341 | |||
342 | # (U-boot) fitImage properties | ||
343 | UBOOT_LOADADDRESS = "0x80080000" | ||
344 | UBOOT_ENTRYPOINT = "0x80080000" | ||
345 | UBOOT_FIT_DESC = "A model description" | ||
346 | KERNEL_IMAGETYPES += " fitImage " | ||
347 | KERNEL_CLASSES = " kernel-fitimage test-mkimage-wrapper " | ||
348 | UBOOT_SIGN_ENABLE = "1" | ||
349 | FIT_GENERATE_KEYS = "1" | ||
350 | UBOOT_SIGN_KEYDIR = "${TOPDIR}/signing-keys" | ||
351 | UBOOT_SIGN_KEYNAME = "oe-selftest" | ||
352 | FIT_SIGN_INDIVIDUAL = "1" | ||
353 | UBOOT_MKIMAGE_SIGN_ARGS = "-c 'a smart U-Boot comment'" | ||
354 | """ | ||
355 | self.write_config(config) | ||
356 | |||
357 | # The U-Boot fitImage is created as part of linux recipe | ||
358 | bitbake("virtual/kernel") | ||
359 | |||
360 | deploy_dir_image = get_bb_var('DEPLOY_DIR_IMAGE') | ||
361 | machine = get_bb_var('MACHINE') | ||
362 | fitimage_its_path = os.path.join(deploy_dir_image, | ||
363 | "u-boot-its-%s" % (machine,)) | ||
364 | fitimage_path = os.path.join(deploy_dir_image, | ||
365 | "u-boot-fitImage-%s" % (machine,)) | ||
366 | |||
367 | self.assertTrue(os.path.exists(fitimage_its_path), | ||
368 | "%s image tree source doesn't exist" % (fitimage_its_path)) | ||
369 | self.assertTrue(os.path.exists(fitimage_path), | ||
370 | "%s FIT image doesn't exist" % (fitimage_path)) | ||
371 | |||
372 | # Check that the type, load address, entrypoint address and default | ||
373 | # values for kernel and ramdisk in Image Tree Source are as expected. | ||
374 | # The order of fields in the below array is important. Not all the | ||
375 | # fields are tested, only the key fields that wont vary between | ||
376 | # different architectures. | ||
377 | its_field_check = [ | ||
378 | 'description = "A model description";', | ||
379 | 'type = "uboot";', | ||
380 | 'load = <0x80080000>;', | ||
381 | 'entry = <0x80080000>;', | ||
382 | 'default = "conf";', | ||
383 | 'loadables = "uboot";', | ||
384 | 'fdt = "fdt";' | ||
385 | ] | ||
386 | |||
387 | with open(fitimage_its_path) as its_file: | ||
388 | field_index = 0 | ||
389 | for line in its_file: | ||
390 | if field_index == len(its_field_check): | ||
391 | break | ||
392 | if its_field_check[field_index] in line: | ||
393 | field_index +=1 | ||
394 | |||
395 | if field_index != len(its_field_check): # if its equal, the test passed | ||
396 | self.assertTrue(field_index == len(its_field_check), | ||
397 | "Fields in Image Tree Source File %s did not match, error in finding %s" | ||
398 | % (fitimage_its_path, its_field_check[field_index])) | ||
399 | |||
400 | |||
401 | def test_sign_standalone_uboot_fit_image(self): | ||
402 | """ | ||
403 | Summary: Check if U-Boot FIT image and Image Tree Source (its) are | ||
404 | created and signed correctly for the scenario where only | ||
405 | the U-Boot proper fitImage is being created and signed. | ||
406 | Expected: 1) U-Boot its and FIT image are built successfully | ||
407 | 2) Scanning the its file indicates signing is enabled | ||
408 | as requested by SPL_SIGN_ENABLE (using keys generated | ||
409 | via UBOOT_FIT_GENERATE_KEYS) | ||
410 | 3) Dumping the FIT image indicates signature values | ||
411 | are present | ||
412 | 4) Examination of the do_uboot_assemble_fitimage | ||
413 | runfile/logfile indicate that UBOOT_MKIMAGE, UBOOT_MKIMAGE_SIGN | ||
414 | and SPL_MKIMAGE_SIGN_ARGS are working as expected. | ||
415 | Product: oe-core | ||
416 | Author: Klaus Heinrich Kiwi <klaus@linux.vnet.ibm.com> based upon | ||
417 | work by Paul Eggleton <paul.eggleton@microsoft.com> and | ||
418 | Usama Arif <usama.arif@arm.com> | ||
419 | """ | ||
420 | config = """ | ||
421 | # There's no U-boot deconfig with CONFIG_FIT_SIGNATURE yet, so we need at | ||
422 | # least CONFIG_SPL_LOAD_FIT and CONFIG_SPL_OF_CONTROL set | ||
423 | MACHINE = "qemuarm" | ||
424 | UBOOT_MACHINE = "am57xx_evm_defconfig" | ||
425 | SPL_BINARY = "MLO" | ||
426 | # The kernel-fitimage class is a dependency even if we're only | ||
427 | # creating/signing the U-Boot fitImage | ||
428 | KERNEL_CLASSES = " kernel-fitimage test-mkimage-wrapper " | ||
429 | # Enable creation and signing of the U-Boot fitImage | ||
430 | UBOOT_FITIMAGE_ENABLE = "1" | ||
431 | SPL_SIGN_ENABLE = "1" | ||
432 | SPL_SIGN_KEYNAME = "spl-oe-selftest" | ||
433 | SPL_SIGN_KEYDIR = "${TOPDIR}/signing-keys" | ||
434 | UBOOT_DTB_BINARY = "u-boot.dtb" | ||
435 | UBOOT_ENTRYPOINT = "0x80000000" | ||
436 | UBOOT_LOADADDRESS = "0x80000000" | ||
437 | UBOOT_DTB_LOADADDRESS = "0x82000000" | ||
438 | UBOOT_ARCH = "arm" | ||
439 | SPL_MKIMAGE_DTCOPTS = "-I dts -O dtb -p 2000" | ||
440 | SPL_MKIMAGE_SIGN_ARGS = "-c 'a smart U-Boot comment'" | ||
441 | UBOOT_EXTLINUX = "0" | ||
442 | UBOOT_FIT_GENERATE_KEYS = "1" | ||
443 | UBOOT_FIT_HASH_ALG = "sha256" | ||
444 | """ | ||
445 | self.write_config(config) | ||
446 | |||
447 | # The U-Boot fitImage is created as part of linux recipe | ||
448 | bitbake("virtual/kernel") | ||
449 | |||
450 | image_type = "core-image-minimal" | ||
451 | deploy_dir_image = get_bb_var('DEPLOY_DIR_IMAGE') | ||
452 | machine = get_bb_var('MACHINE') | ||
453 | fitimage_its_path = os.path.join(deploy_dir_image, | ||
454 | "u-boot-its-%s" % (machine,)) | ||
455 | fitimage_path = os.path.join(deploy_dir_image, | ||
456 | "u-boot-fitImage-%s" % (machine,)) | ||
457 | |||
458 | self.assertTrue(os.path.exists(fitimage_its_path), | ||
459 | "%s image tree source doesn't exist" % (fitimage_its_path)) | ||
460 | self.assertTrue(os.path.exists(fitimage_path), | ||
461 | "%s FIT image doesn't exist" % (fitimage_path)) | ||
462 | |||
463 | req_itspaths = [ | ||
464 | ['/', 'images', 'uboot'], | ||
465 | ['/', 'images', 'uboot', 'signature'], | ||
466 | ['/', 'images', 'fdt'], | ||
467 | ['/', 'images', 'fdt', 'signature'], | ||
468 | ] | ||
469 | |||
470 | itspath = [] | ||
471 | itspaths = [] | ||
472 | linect = 0 | ||
473 | sigs = {} | ||
474 | with open(fitimage_its_path) as its_file: | ||
475 | linect += 1 | ||
476 | for line in its_file: | ||
477 | line = line.strip() | ||
478 | if line.endswith('};'): | ||
479 | itspath.pop() | ||
480 | elif line.endswith('{'): | ||
481 | itspath.append(line[:-1].strip()) | ||
482 | itspaths.append(itspath[:]) | ||
483 | elif itspath and itspath[-1] == 'signature': | ||
484 | itsdotpath = '.'.join(itspath) | ||
485 | if not itsdotpath in sigs: | ||
486 | sigs[itsdotpath] = {} | ||
487 | if not '=' in line or not line.endswith(';'): | ||
488 | self.fail('Unexpected formatting in %s sigs section line %d:%s' % (fitimage_its_path, linect, line)) | ||
489 | key, value = line.split('=', 1) | ||
490 | sigs[itsdotpath][key.rstrip()] = value.lstrip().rstrip(';') | ||
491 | |||
492 | for reqpath in req_itspaths: | ||
493 | if not reqpath in itspaths: | ||
494 | self.fail('Missing section in its file: %s' % reqpath) | ||
495 | |||
496 | reqsigvalues_image = { | ||
497 | 'algo': '"sha256,rsa2048"', | ||
498 | 'key-name-hint': '"spl-oe-selftest"', | ||
499 | } | ||
500 | |||
501 | for itspath, values in sigs.items(): | ||
502 | reqsigvalues = reqsigvalues_image | ||
503 | for reqkey, reqvalue in reqsigvalues.items(): | ||
504 | value = values.get(reqkey, None) | ||
505 | if value is None: | ||
506 | self.fail('Missing key "%s" in its file signature section %s' % (reqkey, itspath)) | ||
507 | self.assertEqual(value, reqvalue) | ||
508 | |||
509 | # Dump the image to see if it really got signed | ||
510 | bitbake("u-boot-tools-native -c addto_recipe_sysroot") | ||
511 | result = runCmd('bitbake -e u-boot-tools-native | grep ^RECIPE_SYSROOT_NATIVE=') | ||
512 | recipe_sysroot_native = result.output.split('=')[1].strip('"') | ||
513 | dumpimage_path = os.path.join(recipe_sysroot_native, 'usr', 'bin', 'dumpimage') | ||
514 | result = runCmd('%s -l %s' % (dumpimage_path, fitimage_path)) | ||
515 | in_signed = None | ||
516 | signed_sections = {} | ||
517 | for line in result.output.splitlines(): | ||
518 | if line.startswith((' Image')): | ||
519 | in_signed = re.search('\((.*)\)', line).groups()[0] | ||
520 | elif re.match(' \w', line): | ||
521 | in_signed = None | ||
522 | elif in_signed: | ||
523 | if not in_signed in signed_sections: | ||
524 | signed_sections[in_signed] = {} | ||
525 | key, value = line.split(':', 1) | ||
526 | signed_sections[in_signed][key.strip()] = value.strip() | ||
527 | self.assertIn('uboot', signed_sections) | ||
528 | self.assertIn('fdt', signed_sections) | ||
529 | for signed_section, values in signed_sections.items(): | ||
530 | value = values.get('Sign algo', None) | ||
531 | self.assertEqual(value, 'sha256,rsa2048:spl-oe-selftest', 'Signature algorithm for %s not expected value' % signed_section) | ||
532 | value = values.get('Sign value', None) | ||
533 | self.assertEqual(len(value), 512, 'Signature value for section %s not expected length' % signed_section) | ||
534 | |||
535 | # Check for SPL_MKIMAGE_SIGN_ARGS | ||
536 | result = runCmd('bitbake -e virtual/kernel | grep ^T=') | ||
537 | tempdir = result.output.split('=', 1)[1].strip().strip('') | ||
538 | result = runCmd('grep "a smart U-Boot comment" %s/run.do_uboot_assemble_fitimage' % tempdir, ignore_status=True) | ||
539 | self.assertEqual(result.status, 0, 'SPL_MKIMAGE_SIGN_ARGS value did not get used') | ||
540 | |||
541 | # Check for evidence of test-mkimage-wrapper class | ||
542 | result = runCmd('grep "### uboot-mkimage wrapper message" %s/log.do_uboot_assemble_fitimage' % tempdir, ignore_status=True) | ||
543 | self.assertEqual(result.status, 0, 'UBOOT_MKIMAGE did not work') | ||
544 | result = runCmd('grep "### uboot-mkimage signing wrapper message" %s/log.do_uboot_assemble_fitimage' % tempdir, ignore_status=True) | ||
545 | self.assertEqual(result.status, 0, 'UBOOT_MKIMAGE_SIGN did not work') | ||
546 | |||
547 | def test_sign_cascaded_uboot_fit_image(self): | ||
548 | """ | ||
549 | Summary: Check if U-Boot FIT image and Image Tree Source (its) are | ||
550 | created and signed correctly for the scenario where both | ||
551 | U-Boot proper and Kernel fitImages are being created and | ||
552 | signed. | ||
553 | Expected: 1) U-Boot its and FIT image are built successfully | ||
554 | 2) Scanning the its file indicates signing is enabled | ||
555 | as requested by SPL_SIGN_ENABLE (using keys generated | ||
556 | via UBOOT_FIT_GENERATE_KEYS) | ||
557 | 3) Dumping the FIT image indicates signature values | ||
558 | are present | ||
559 | 4) Examination of the do_uboot_assemble_fitimage | ||
560 | runfile/logfile indicate that UBOOT_MKIMAGE, UBOOT_MKIMAGE_SIGN | ||
561 | and SPL_MKIMAGE_SIGN_ARGS are working as expected. | ||
562 | Product: oe-core | ||
563 | Author: Klaus Heinrich Kiwi <klaus@linux.vnet.ibm.com> based upon | ||
564 | work by Paul Eggleton <paul.eggleton@microsoft.com> and | ||
565 | Usama Arif <usama.arif@arm.com> | ||
566 | """ | ||
567 | config = """ | ||
568 | # There's no U-boot deconfig with CONFIG_FIT_SIGNATURE yet, so we need at | ||
569 | # least CONFIG_SPL_LOAD_FIT and CONFIG_SPL_OF_CONTROL set | ||
570 | MACHINE = "qemuarm" | ||
571 | UBOOT_MACHINE = "am57xx_evm_defconfig" | ||
572 | SPL_BINARY = "MLO" | ||
573 | # Enable creation and signing of the U-Boot fitImage | ||
574 | UBOOT_FITIMAGE_ENABLE = "1" | ||
575 | SPL_SIGN_ENABLE = "1" | ||
576 | SPL_SIGN_KEYNAME = "spl-cascaded-oe-selftest" | ||
577 | SPL_SIGN_KEYDIR = "${TOPDIR}/signing-keys" | ||
578 | UBOOT_DTB_BINARY = "u-boot.dtb" | ||
579 | UBOOT_ENTRYPOINT = "0x80000000" | ||
580 | UBOOT_LOADADDRESS = "0x80000000" | ||
581 | UBOOT_MKIMAGE_DTCOPTS = "-I dts -O dtb -p 2000" | ||
582 | UBOOT_MKIMAGE_SIGN_ARGS = "-c 'a smart cascaded Kernel comment'" | ||
583 | UBOOT_DTB_LOADADDRESS = "0x82000000" | ||
584 | UBOOT_ARCH = "arm" | ||
585 | SPL_MKIMAGE_DTCOPTS = "-I dts -O dtb -p 2000" | ||
586 | SPL_MKIMAGE_SIGN_ARGS = "-c 'a smart cascaded U-Boot comment'" | ||
587 | UBOOT_EXTLINUX = "0" | ||
588 | UBOOT_FIT_GENERATE_KEYS = "1" | ||
589 | UBOOT_FIT_HASH_ALG = "sha256" | ||
590 | KERNEL_IMAGETYPES += " fitImage " | ||
591 | KERNEL_CLASSES = " kernel-fitimage test-mkimage-wrapper " | ||
592 | UBOOT_SIGN_ENABLE = "1" | ||
593 | FIT_GENERATE_KEYS = "1" | ||
594 | UBOOT_SIGN_KEYDIR = "${TOPDIR}/signing-keys" | ||
595 | UBOOT_SIGN_KEYNAME = "kernel-oe-selftest" | ||
596 | FIT_SIGN_INDIVIDUAL = "1" | ||
597 | """ | ||
598 | self.write_config(config) | ||
599 | |||
600 | # The U-Boot fitImage is created as part of linux recipe | ||
601 | bitbake("virtual/kernel") | ||
602 | |||
603 | image_type = "core-image-minimal" | ||
604 | deploy_dir_image = get_bb_var('DEPLOY_DIR_IMAGE') | ||
605 | machine = get_bb_var('MACHINE') | ||
606 | fitimage_its_path = os.path.join(deploy_dir_image, | ||
607 | "u-boot-its-%s" % (machine,)) | ||
608 | fitimage_path = os.path.join(deploy_dir_image, | ||
609 | "u-boot-fitImage-%s" % (machine,)) | ||
610 | |||
611 | self.assertTrue(os.path.exists(fitimage_its_path), | ||
612 | "%s image tree source doesn't exist" % (fitimage_its_path)) | ||
613 | self.assertTrue(os.path.exists(fitimage_path), | ||
614 | "%s FIT image doesn't exist" % (fitimage_path)) | ||
615 | |||
616 | req_itspaths = [ | ||
617 | ['/', 'images', 'uboot'], | ||
618 | ['/', 'images', 'uboot', 'signature'], | ||
619 | ['/', 'images', 'fdt'], | ||
620 | ['/', 'images', 'fdt', 'signature'], | ||
621 | ] | ||
622 | |||
623 | itspath = [] | ||
624 | itspaths = [] | ||
625 | linect = 0 | ||
626 | sigs = {} | ||
627 | with open(fitimage_its_path) as its_file: | ||
628 | linect += 1 | ||
629 | for line in its_file: | ||
630 | line = line.strip() | ||
631 | if line.endswith('};'): | ||
632 | itspath.pop() | ||
633 | elif line.endswith('{'): | ||
634 | itspath.append(line[:-1].strip()) | ||
635 | itspaths.append(itspath[:]) | ||
636 | elif itspath and itspath[-1] == 'signature': | ||
637 | itsdotpath = '.'.join(itspath) | ||
638 | if not itsdotpath in sigs: | ||
639 | sigs[itsdotpath] = {} | ||
640 | if not '=' in line or not line.endswith(';'): | ||
641 | self.fail('Unexpected formatting in %s sigs section line %d:%s' % (fitimage_its_path, linect, line)) | ||
642 | key, value = line.split('=', 1) | ||
643 | sigs[itsdotpath][key.rstrip()] = value.lstrip().rstrip(';') | ||
644 | |||
645 | for reqpath in req_itspaths: | ||
646 | if not reqpath in itspaths: | ||
647 | self.fail('Missing section in its file: %s' % reqpath) | ||
648 | |||
649 | reqsigvalues_image = { | ||
650 | 'algo': '"sha256,rsa2048"', | ||
651 | 'key-name-hint': '"spl-cascaded-oe-selftest"', | ||
652 | } | ||
653 | |||
654 | for itspath, values in sigs.items(): | ||
655 | reqsigvalues = reqsigvalues_image | ||
656 | for reqkey, reqvalue in reqsigvalues.items(): | ||
657 | value = values.get(reqkey, None) | ||
658 | if value is None: | ||
659 | self.fail('Missing key "%s" in its file signature section %s' % (reqkey, itspath)) | ||
660 | self.assertEqual(value, reqvalue) | ||
661 | |||
662 | # Dump the image to see if it really got signed | ||
663 | bitbake("u-boot-tools-native -c addto_recipe_sysroot") | ||
664 | result = runCmd('bitbake -e u-boot-tools-native | grep ^RECIPE_SYSROOT_NATIVE=') | ||
665 | recipe_sysroot_native = result.output.split('=')[1].strip('"') | ||
666 | dumpimage_path = os.path.join(recipe_sysroot_native, 'usr', 'bin', 'dumpimage') | ||
667 | result = runCmd('%s -l %s' % (dumpimage_path, fitimage_path)) | ||
668 | in_signed = None | ||
669 | signed_sections = {} | ||
670 | for line in result.output.splitlines(): | ||
671 | if line.startswith((' Image')): | ||
672 | in_signed = re.search('\((.*)\)', line).groups()[0] | ||
673 | elif re.match(' \w', line): | ||
674 | in_signed = None | ||
675 | elif in_signed: | ||
676 | if not in_signed in signed_sections: | ||
677 | signed_sections[in_signed] = {} | ||
678 | key, value = line.split(':', 1) | ||
679 | signed_sections[in_signed][key.strip()] = value.strip() | ||
680 | self.assertIn('uboot', signed_sections) | ||
681 | self.assertIn('fdt', signed_sections) | ||
682 | for signed_section, values in signed_sections.items(): | ||
683 | value = values.get('Sign algo', None) | ||
684 | self.assertEqual(value, 'sha256,rsa2048:spl-cascaded-oe-selftest', 'Signature algorithm for %s not expected value' % signed_section) | ||
685 | value = values.get('Sign value', None) | ||
686 | self.assertEqual(len(value), 512, 'Signature value for section %s not expected length' % signed_section) | ||
687 | |||
688 | # Check for SPL_MKIMAGE_SIGN_ARGS | ||
689 | result = runCmd('bitbake -e virtual/kernel | grep ^T=') | ||
690 | tempdir = result.output.split('=', 1)[1].strip().strip('') | ||
691 | result = runCmd('grep "a smart cascaded U-Boot comment" %s/run.do_uboot_assemble_fitimage' % tempdir, ignore_status=True) | ||
692 | self.assertEqual(result.status, 0, 'SPL_MKIMAGE_SIGN_ARGS value did not get used') | ||
693 | |||
694 | # Check for evidence of test-mkimage-wrapper class | ||
695 | result = runCmd('grep "### uboot-mkimage wrapper message" %s/log.do_uboot_assemble_fitimage' % tempdir, ignore_status=True) | ||
696 | self.assertEqual(result.status, 0, 'UBOOT_MKIMAGE did not work') | ||
697 | result = runCmd('grep "### uboot-mkimage signing wrapper message" %s/log.do_uboot_assemble_fitimage' % tempdir, ignore_status=True) | ||
698 | self.assertEqual(result.status, 0, 'UBOOT_MKIMAGE_SIGN did not work') | ||
699 | |||
700 | |||
701 | |||
234 | def test_initramfs_bundle(self): | 702 | def test_initramfs_bundle(self): |
235 | """ | 703 | """ |
236 | Summary: Verifies the content of the initramfs bundle node in the FIT Image Tree Source (its) | 704 | Summary: Verifies the content of the initramfs bundle node in the FIT Image Tree Source (its) |