summaryrefslogtreecommitdiff
path: root/test/py
diff options
context:
space:
mode:
Diffstat (limited to 'test/py')
-rw-r--r--test/py/conftest.py2
-rw-r--r--test/py/requirements.txt3
-rw-r--r--test/py/tests/test_efi_capsule/test_capsule_firmware.py14
-rw-r--r--test/py/tests/test_efi_secboot/test_signed.py16
-rw-r--r--test/py/tests/test_efi_secboot/test_signed_intca.py8
-rw-r--r--test/py/tests/test_efi_secboot/test_unsigned.py8
-rw-r--r--test/py/tests/test_fit_ecdsa.py111
-rw-r--r--test/py/tests/test_log.py1
-rw-r--r--test/py/tests/test_ofplatdata.py2
-rw-r--r--test/py/tests/test_qfw.py26
-rw-r--r--test/py/tests/test_scp03.py27
11 files changed, 195 insertions, 23 deletions
diff --git a/test/py/conftest.py b/test/py/conftest.py
index 9bfd9263455..1b909cde9d3 100644
--- a/test/py/conftest.py
+++ b/test/py/conftest.py
@@ -226,7 +226,7 @@ def pytest_configure(config):
import u_boot_console_exec_attach
console = u_boot_console_exec_attach.ConsoleExecAttach(log, ubconfig)
-re_ut_test_list = re.compile(r'_u_boot_list_2_(.*)_test_2_\1_test_(.*)\s*$')
+re_ut_test_list = re.compile(r'_u_boot_list_2_ut_(.*)_test_2_\1_test_(.*)\s*$')
def generate_ut_subtest(metafunc, fixture_name, sym_path):
"""Provide parametrization for a ut_subtest fixture.
diff --git a/test/py/requirements.txt b/test/py/requirements.txt
index 926bccad694..9c346b4b41f 100644
--- a/test/py/requirements.txt
+++ b/test/py/requirements.txt
@@ -10,8 +10,9 @@ packaging==19.2
pbr==5.4.3
pluggy==0.13.0
py==1.8.0
+pycryptodomex==3.9.8
pyelftools==0.27
-pygit2==1.4.0
+pygit2==0.28.2
pyparsing==2.4.2
pytest==5.2.1
python-mimeparse==1.6.0
diff --git a/test/py/tests/test_efi_capsule/test_capsule_firmware.py b/test/py/tests/test_efi_capsule/test_capsule_firmware.py
index f006fa95d65..160a64a14b4 100644
--- a/test/py/tests/test_efi_capsule/test_capsule_firmware.py
+++ b/test/py/tests/test_efi_capsule/test_capsule_firmware.py
@@ -39,7 +39,7 @@ class TestEfiCapsuleFirmwareFit(object):
with u_boot_console.log.section('Test Case 1-a, before reboot'):
output = u_boot_console.run_command_list([
'host bind 0 %s' % disk_img,
- 'efidebug boot add 1 TEST host 0:1 /helloworld.efi ""',
+ 'efidebug boot add -b 1 TEST host 0:1 /helloworld.efi ""',
'efidebug boot order 1',
'env set -e OsIndications',
'env set dfu_alt_info "sf 0:0=u-boot-bin raw 0x100000 0x50000;u-boot-env raw 0x150000 0x200000"',
@@ -114,7 +114,7 @@ class TestEfiCapsuleFirmwareFit(object):
with u_boot_console.log.section('Test Case 2-a, before reboot'):
output = u_boot_console.run_command_list([
'host bind 0 %s' % disk_img,
- 'efidebug boot add 1 TEST host 0:1 /helloworld.efi ""',
+ 'efidebug boot add -b 1 TEST host 0:1 /helloworld.efi ""',
'efidebug boot order 1',
'env set -e -nv -bs -rt OsIndications =0x0000000000000004',
'env set dfu_alt_info "sf 0:0=u-boot-bin raw 0x100000 0x50000;u-boot-env raw 0x150000 0x200000"',
@@ -188,7 +188,7 @@ class TestEfiCapsuleFirmwareFit(object):
with u_boot_console.log.section('Test Case 3-a, before reboot'):
output = u_boot_console.run_command_list([
'host bind 0 %s' % disk_img,
- 'efidebug boot add 1 TEST host 0:1 /helloworld.efi ""',
+ 'efidebug boot add -b 1 TEST host 0:1 /helloworld.efi ""',
'efidebug boot order 1',
'env set -e -nv -bs -rt OsIndications =0x0000000000000004',
'env set dfu_alt_info "sf 0:0=u-boot-bin raw 0x100000 0x50000;u-boot-env raw 0x150000 0x200000"',
@@ -229,6 +229,14 @@ class TestEfiCapsuleFirmwareFit(object):
output = u_boot_console.run_command(
'env print -e -all Capsule0000')
+ output = u_boot_console.run_command_list(['efidebug capsule esrt'])
+
+ # ensure that EFI_FIRMWARE_IMAGE_TYPE_UBOOT_FIT_GUID is in the ESRT.
+ assert 'AE13FF2D-9AD4-4E25-9AC8-6D80B3B22147' in ''.join(output)
+
+ # ensure that EFI_FIRMWARE_IMAGE_TYPE_UBOOT_RAW_GUID is in the ESRT.
+ assert 'E2BB9C06-70E9-4B14-97A3-5A7913176E3F' in ''.join(output)
+
output = u_boot_console.run_command_list([
'host bind 0 %s' % disk_img,
'fatls host 0:1 %s' % CAPSULE_INSTALL_DIR])
diff --git a/test/py/tests/test_efi_secboot/test_signed.py b/test/py/tests/test_efi_secboot/test_signed.py
index 863685e215b..75f5ea77230 100644
--- a/test/py/tests/test_efi_secboot/test_signed.py
+++ b/test/py/tests/test_efi_secboot/test_signed.py
@@ -28,7 +28,7 @@ class TestEfiSignedImage(object):
# Test Case 1a, run signed image if no PK
output = u_boot_console.run_command_list([
'host bind 0 %s' % disk_img,
- 'efidebug boot add 1 HELLO1 host 0:1 /helloworld.efi.signed ""',
+ 'efidebug boot add -b 1 HELLO1 host 0:1 /helloworld.efi.signed ""',
'efidebug boot next 1',
'bootefi bootmgr'])
assert 'Hello, world!' in ''.join(output)
@@ -36,7 +36,7 @@ class TestEfiSignedImage(object):
with u_boot_console.log.section('Test Case 1b'):
# Test Case 1b, run unsigned image if no PK
output = u_boot_console.run_command_list([
- 'efidebug boot add 2 HELLO2 host 0:1 /helloworld.efi ""',
+ 'efidebug boot add -b 2 HELLO2 host 0:1 /helloworld.efi ""',
'efidebug boot next 2',
'bootefi bootmgr'])
assert 'Hello, world!' in ''.join(output)
@@ -58,13 +58,13 @@ class TestEfiSignedImage(object):
'setenv -e -nv -bs -rt -at -i 4000000:$filesize PK'])
assert 'Failed to set EFI variable' not in ''.join(output)
output = u_boot_console.run_command_list([
- 'efidebug boot add 1 HELLO1 host 0:1 /helloworld.efi.signed ""',
+ 'efidebug boot add -b 1 HELLO1 host 0:1 /helloworld.efi.signed ""',
'efidebug boot next 1',
'efidebug test bootmgr'])
assert('\'HELLO1\' failed' in ''.join(output))
assert('efi_start_image() returned: 26' in ''.join(output))
output = u_boot_console.run_command_list([
- 'efidebug boot add 2 HELLO2 host 0:1 /helloworld.efi ""',
+ 'efidebug boot add -b 2 HELLO2 host 0:1 /helloworld.efi ""',
'efidebug boot next 2',
'efidebug test bootmgr'])
assert '\'HELLO2\' failed' in ''.join(output)
@@ -104,7 +104,7 @@ class TestEfiSignedImage(object):
'setenv -e -nv -bs -rt -at -i 4000000:$filesize PK'])
assert 'Failed to set EFI variable' not in ''.join(output)
output = u_boot_console.run_command_list([
- 'efidebug boot add 1 HELLO host 0:1 /helloworld.efi.signed ""',
+ 'efidebug boot add -b 1 HELLO host 0:1 /helloworld.efi.signed ""',
'efidebug boot next 1',
'efidebug test bootmgr'])
assert '\'HELLO\' failed' in ''.join(output)
@@ -142,7 +142,7 @@ class TestEfiSignedImage(object):
'setenv -e -nv -bs -rt -at -i 4000000:$filesize PK'])
assert 'Failed to set EFI variable' not in ''.join(output)
output = u_boot_console.run_command_list([
- 'efidebug boot add 1 HELLO host 0:1 /helloworld.efi.signed ""',
+ 'efidebug boot add -b 1 HELLO host 0:1 /helloworld.efi.signed ""',
'efidebug boot next 1',
'efidebug test bootmgr'])
assert '\'HELLO\' failed' in ''.join(output)
@@ -169,7 +169,7 @@ class TestEfiSignedImage(object):
'setenv -e -nv -bs -rt -at -i 4000000:$filesize PK'])
assert 'Failed to set EFI variable' not in ''.join(output)
output = u_boot_console.run_command_list([
- 'efidebug boot add 1 HELLO host 0:1 /helloworld.efi.signed_2sigs ""',
+ 'efidebug boot add -b 1 HELLO host 0:1 /helloworld.efi.signed_2sigs ""',
'efidebug boot next 1',
'efidebug test bootmgr'])
assert 'Hello, world!' in ''.join(output)
@@ -227,7 +227,7 @@ class TestEfiSignedImage(object):
'setenv -e -nv -bs -rt -at -i 4000000:$filesize PK'])
assert 'Failed to set EFI variable' not in ''.join(output)
output = u_boot_console.run_command_list([
- 'efidebug boot add 1 HELLO host 0:1 /helloworld.efi.signed ""',
+ 'efidebug boot add -b 1 HELLO host 0:1 /helloworld.efi.signed ""',
'efidebug boot next 1',
'bootefi bootmgr'])
assert 'Hello, world!' in ''.join(output)
diff --git a/test/py/tests/test_efi_secboot/test_signed_intca.py b/test/py/tests/test_efi_secboot/test_signed_intca.py
index 70d6be00e8a..0849572a514 100644
--- a/test/py/tests/test_efi_secboot/test_signed_intca.py
+++ b/test/py/tests/test_efi_secboot/test_signed_intca.py
@@ -39,7 +39,7 @@ class TestEfiSignedImageIntca(object):
assert 'Failed to set EFI variable' not in ''.join(output)
output = u_boot_console.run_command_list([
- 'efidebug boot add 1 HELLO_a host 0:1 /helloworld.efi.signed_a ""',
+ 'efidebug boot add -b 1 HELLO_a host 0:1 /helloworld.efi.signed_a ""',
'efidebug boot next 1',
'efidebug test bootmgr'])
assert '\'HELLO_a\' failed' in ''.join(output)
@@ -48,7 +48,7 @@ class TestEfiSignedImageIntca(object):
with u_boot_console.log.section('Test Case 1b'):
# Test Case 1b, signed and authenticated by root CA
output = u_boot_console.run_command_list([
- 'efidebug boot add 2 HELLO_ab host 0:1 /helloworld.efi.signed_ab ""',
+ 'efidebug boot add -b 2 HELLO_ab host 0:1 /helloworld.efi.signed_ab ""',
'efidebug boot next 2',
'bootefi bootmgr'])
assert 'Hello, world!' in ''.join(output)
@@ -70,7 +70,7 @@ class TestEfiSignedImageIntca(object):
assert 'Failed to set EFI variable' not in ''.join(output)
output = u_boot_console.run_command_list([
- 'efidebug boot add 1 HELLO_abc host 0:1 /helloworld.efi.signed_abc ""',
+ 'efidebug boot add -b 1 HELLO_abc host 0:1 /helloworld.efi.signed_abc ""',
'efidebug boot next 1',
'efidebug test bootmgr'])
assert '\'HELLO_abc\' failed' in ''.join(output)
@@ -116,7 +116,7 @@ class TestEfiSignedImageIntca(object):
assert 'Failed to set EFI variable' not in ''.join(output)
output = u_boot_console.run_command_list([
- 'efidebug boot add 1 HELLO_abc host 0:1 /helloworld.efi.signed_abc ""',
+ 'efidebug boot add -b 1 HELLO_abc host 0:1 /helloworld.efi.signed_abc ""',
'efidebug boot next 1',
'efidebug test bootmgr'])
assert 'Hello, world!' in ''.join(output)
diff --git a/test/py/tests/test_efi_secboot/test_unsigned.py b/test/py/tests/test_efi_secboot/test_unsigned.py
index 56f56e19eb8..8e026f7566a 100644
--- a/test/py/tests/test_efi_secboot/test_unsigned.py
+++ b/test/py/tests/test_efi_secboot/test_unsigned.py
@@ -35,7 +35,7 @@ class TestEfiUnsignedImage(object):
assert 'Failed to set EFI variable' not in ''.join(output)
output = u_boot_console.run_command_list([
- 'efidebug boot add 1 HELLO host 0:1 /helloworld.efi ""',
+ 'efidebug boot add -b 1 HELLO host 0:1 /helloworld.efi ""',
'efidebug boot next 1',
'bootefi bootmgr'])
assert '\'HELLO\' failed' in ''.join(output)
@@ -64,7 +64,7 @@ class TestEfiUnsignedImage(object):
assert 'Failed to set EFI variable' not in ''.join(output)
output = u_boot_console.run_command_list([
- 'efidebug boot add 1 HELLO host 0:1 /helloworld.efi ""',
+ 'efidebug boot add -b 1 HELLO host 0:1 /helloworld.efi ""',
'efidebug boot next 1',
'bootefi bootmgr'])
assert 'Hello, world!' in ''.join(output)
@@ -88,7 +88,7 @@ class TestEfiUnsignedImage(object):
assert 'Failed to set EFI variable' not in ''.join(output)
output = u_boot_console.run_command_list([
- 'efidebug boot add 1 HELLO host 0:1 /helloworld.efi ""',
+ 'efidebug boot add -b 1 HELLO host 0:1 /helloworld.efi ""',
'efidebug boot next 1',
'bootefi bootmgr'])
assert '\'HELLO\' failed' in ''.join(output)
@@ -106,7 +106,7 @@ class TestEfiUnsignedImage(object):
assert 'Failed to set EFI variable' not in ''.join(output)
output = u_boot_console.run_command_list([
- 'efidebug boot add 1 HELLO host 0:1 /helloworld.efi ""',
+ 'efidebug boot add -b 1 HELLO host 0:1 /helloworld.efi ""',
'efidebug boot next 1',
'bootefi bootmgr'])
assert '\'HELLO\' failed' in ''.join(output)
diff --git a/test/py/tests/test_fit_ecdsa.py b/test/py/tests/test_fit_ecdsa.py
new file mode 100644
index 00000000000..87b60812229
--- /dev/null
+++ b/test/py/tests/test_fit_ecdsa.py
@@ -0,0 +1,111 @@
+# SPDX-License-Identifier: GPL-2.0+
+#
+# Copyright (c) 2020,2021 Alexandru Gagniuc <mr.nuke.me@gmail.com>
+
+"""
+Test ECDSA signing of FIT images
+
+This test uses mkimage to sign an existing FIT image with an ECDSA key. The
+signature is then extracted, and verified against pyCryptodome.
+This test doesn't run the sandbox. It only checks the host tool 'mkimage'
+"""
+
+import pytest
+import u_boot_utils as util
+from Cryptodome.Hash import SHA256
+from Cryptodome.PublicKey import ECC
+from Cryptodome.Signature import DSS
+
+class SignableFitImage(object):
+ """ Helper to manipulate a FIT image on disk """
+ def __init__(self, cons, file_name):
+ self.fit = file_name
+ self.cons = cons
+ self.signable_nodes = set()
+
+ def __fdt_list(self, path):
+ return util.run_and_log(self.cons, f'fdtget -l {self.fit} {path}')
+
+ def __fdt_set(self, node, **prop_value):
+ for prop, value in prop_value.items():
+ util.run_and_log(self.cons, f'fdtput -ts {self.fit} {node} {prop} {value}')
+
+ def __fdt_get_binary(self, node, prop):
+ numbers = util.run_and_log(self.cons, f'fdtget -tbi {self.fit} {node} {prop}')
+
+ bignum = bytearray()
+ for little_num in numbers.split():
+ bignum.append(int(little_num))
+
+ return bignum
+
+ def find_signable_image_nodes(self):
+ for node in self.__fdt_list('/images').split():
+ image = f'/images/{node}'
+ if 'signature' in self.__fdt_list(image):
+ self.signable_nodes.add(image)
+
+ return self.signable_nodes
+
+ def change_signature_algo_to_ecdsa(self):
+ for image in self.signable_nodes:
+ self.__fdt_set(f'{image}/signature', algo='sha256,ecdsa256')
+
+ def sign(self, mkimage, key_file):
+ util.run_and_log(self.cons, [mkimage, '-F', self.fit, f'-G{key_file}'])
+
+ def check_signatures(self, key):
+ for image in self.signable_nodes:
+ raw_sig = self.__fdt_get_binary(f'{image}/signature', 'value')
+ raw_bin = self.__fdt_get_binary(image, 'data')
+
+ sha = SHA256.new(raw_bin)
+ verifier = DSS.new(key, 'fips-186-3')
+ verifier.verify(sha, bytes(raw_sig))
+
+
+@pytest.mark.buildconfigspec('fit_signature')
+@pytest.mark.requiredtool('dtc')
+@pytest.mark.requiredtool('fdtget')
+@pytest.mark.requiredtool('fdtput')
+def test_fit_ecdsa(u_boot_console):
+ """ Test that signatures generated by mkimage are legible. """
+ def generate_ecdsa_key():
+ return ECC.generate(curve='prime256v1')
+
+ def assemble_fit_image(dest_fit, its, destdir):
+ dtc_args = f'-I dts -O dtb -i {destdir}'
+ util.run_and_log(cons, [mkimage, '-D', dtc_args, '-f', its, dest_fit])
+
+ def dtc(dts):
+ dtb = dts.replace('.dts', '.dtb')
+ util.run_and_log(cons, f'dtc {datadir}/{dts} -O dtb -o {tempdir}/{dtb}')
+
+ cons = u_boot_console
+ mkimage = cons.config.build_dir + '/tools/mkimage'
+ datadir = cons.config.source_dir + '/test/py/tests/vboot/'
+ tempdir = cons.config.result_dir
+ key_file = f'{tempdir}/ecdsa-test-key.pem'
+ fit_file = f'{tempdir}/test.fit'
+ dtc('sandbox-kernel.dts')
+
+ key = generate_ecdsa_key()
+
+ # Create a fake kernel image -- zeroes will do just fine
+ with open(f'{tempdir}/test-kernel.bin', 'w') as fd:
+ fd.write(500 * chr(0))
+
+ # invocations of mkimage expect to read the key from disk
+ with open(key_file, 'w') as f:
+ f.write(key.export_key(format='PEM'))
+
+ assemble_fit_image(fit_file, f'{datadir}/sign-images-sha256.its', tempdir)
+
+ fit = SignableFitImage(cons, fit_file)
+ nodes = fit.find_signable_image_nodes()
+ if len(nodes) == 0:
+ raise ValueError('FIT image has no "/image" nodes with "signature"')
+
+ fit.change_signature_algo_to_ecdsa()
+ fit.sign(mkimage, key_file)
+ fit.check_signatures(key)
diff --git a/test/py/tests/test_log.py b/test/py/tests/test_log.py
index f889120f2b3..140dcb9aa2b 100644
--- a/test/py/tests/test_log.py
+++ b/test/py/tests/test_log.py
@@ -45,5 +45,4 @@ def test_log_dropped(u_boot_console):
cons = u_boot_console
cons.restart_uboot()
output = cons.get_spawn_output().replace('\r', '')
- assert 'sandbox: starting...' in output
assert (not 'debug: main' in output)
diff --git a/test/py/tests/test_ofplatdata.py b/test/py/tests/test_ofplatdata.py
index 92d09b7aa19..e9cce4daf48 100644
--- a/test/py/tests/test_ofplatdata.py
+++ b/test/py/tests/test_ofplatdata.py
@@ -4,7 +4,7 @@
import pytest
import u_boot_utils as util
-@pytest.mark.boardspec('sandbox')
+@pytest.mark.boardspec('sandbox_spl')
@pytest.mark.buildconfigspec('spl_of_platdata')
def test_spl_devicetree(u_boot_console):
"""Test content of spl device-tree"""
diff --git a/test/py/tests/test_qfw.py b/test/py/tests/test_qfw.py
new file mode 100644
index 00000000000..8b668c9721a
--- /dev/null
+++ b/test/py/tests/test_qfw.py
@@ -0,0 +1,26 @@
+# SPDX-License-Identifier: GPL-2.0+
+# Copyright (c) 2021, Asherah Connor <ashe@kivikakk.ee>
+
+# Test qfw command implementation
+
+import pytest
+
+@pytest.mark.buildconfigspec('cmd_qfw')
+def test_qfw_cpus(u_boot_console):
+ "Test QEMU firmware config reports the CPU count."
+
+ output = u_boot_console.run_command('qfw cpus')
+ # The actual number varies depending on the board under test, so only
+ # assert a non-zero output.
+ assert 'cpu(s) online' in output
+ assert '0 cpu(s) online' not in output
+
+@pytest.mark.buildconfigspec('cmd_qfw')
+def test_qfw_list(u_boot_console):
+ "Test QEMU firmware config lists devices."
+
+ output = u_boot_console.run_command('qfw list')
+ # Assert either:
+ # 1) 'test-one', from the sandbox driver, or
+ # 2) 'bootorder', found in every real QEMU implementation.
+ assert ("bootorder" in output) or ("test-one" in output)
diff --git a/test/py/tests/test_scp03.py b/test/py/tests/test_scp03.py
new file mode 100644
index 00000000000..1f689252ddf
--- /dev/null
+++ b/test/py/tests/test_scp03.py
@@ -0,0 +1,27 @@
+# Copyright (c) 2021 Foundries.io Ltd
+#
+# SPDX-License-Identifier: GPL-2.0+
+#
+# SCP03 command test
+
+"""
+This tests SCP03 command in U-boot.
+
+For additional details check doc/usage/scp03.rst
+"""
+
+import pytest
+import u_boot_utils as util
+
+@pytest.mark.buildconfigspec('cmd_scp03')
+def test_scp03(u_boot_console):
+ """Enable and provision keys with SCP03
+ """
+
+ success_str1 = "SCP03 is enabled"
+ success_str2 = "SCP03 is provisioned"
+
+ response = u_boot_console.run_command('scp03 enable')
+ assert success_str1 in response
+ response = u_boot_console.run_command('scp03 provision')
+ assert success_str2 in response