1# SPDX-License-Identifier:      GPL-2.0+
2# Copyright (c) 2019, Linaro Limited
3# Author: AKASHI Takahiro <takahiro.akashi@linaro.org>
4#
5# U-Boot UEFI: Signed Image Authentication Test
6
7"""
8This test verifies image authentication for unsigned images.
9"""
10
11import pytest
12
13
14@pytest.mark.boardspec('sandbox')
15@pytest.mark.buildconfigspec('efi_secure_boot')
16@pytest.mark.buildconfigspec('cmd_efidebug')
17@pytest.mark.buildconfigspec('cmd_fat')
18@pytest.mark.buildconfigspec('cmd_nvedit_efi')
19@pytest.mark.slow
20class TestEfiUnsignedImage(object):
21    def test_efi_unsigned_image_auth1(self, u_boot_console, efi_boot_env):
22        """
23        Test Case 1 - rejected when not digest in db or dbx
24        """
25        u_boot_console.restart_uboot()
26        disk_img = efi_boot_env
27        with u_boot_console.log.section('Test Case 1'):
28            # Test Case 1
29            output = u_boot_console.run_command_list([
30                'host bind 0 %s' % disk_img,
31                'fatload host 0:1 4000000 KEK.auth',
32                'setenv -e -nv -bs -rt -at -i 4000000:$filesize KEK',
33                'fatload host 0:1 4000000 PK.auth',
34                'setenv -e -nv -bs -rt -at -i 4000000:$filesize PK'])
35            assert 'Failed to set EFI variable' not in ''.join(output)
36
37            output = u_boot_console.run_command_list([
38                'efidebug boot add 1 HELLO host 0:1 /helloworld.efi ""',
39                'efidebug boot next 1',
40                'bootefi bootmgr'])
41            assert '\'HELLO\' failed' in ''.join(output)
42            output = u_boot_console.run_command_list([
43                'efidebug boot next 1',
44                'efidebug test bootmgr'])
45            assert 'efi_start_image() returned: 26' in ''.join(output)
46            assert 'Hello, world!' not in ''.join(output)
47
48    def test_efi_unsigned_image_auth2(self, u_boot_console, efi_boot_env):
49        """
50        Test Case 2 - authenticated by digest in db
51        """
52        u_boot_console.restart_uboot()
53        disk_img = efi_boot_env
54        with u_boot_console.log.section('Test Case 2'):
55            # Test Case 2
56            output = u_boot_console.run_command_list([
57                'host bind 0 %s' % disk_img,
58                'fatload host 0:1 4000000 db_hello.auth',
59                'setenv -e -nv -bs -rt -at -i 4000000:$filesize db',
60                'fatload host 0:1 4000000 KEK.auth',
61                'setenv -e -nv -bs -rt -at -i 4000000:$filesize KEK',
62                'fatload host 0:1 4000000 PK.auth',
63                'setenv -e -nv -bs -rt -at -i 4000000:$filesize PK'])
64            assert 'Failed to set EFI variable' not in ''.join(output)
65
66            output = u_boot_console.run_command_list([
67                'efidebug boot add 1 HELLO host 0:1 /helloworld.efi ""',
68                'efidebug boot next 1',
69                'bootefi bootmgr'])
70            assert 'Hello, world!' in ''.join(output)
71
72    def test_efi_unsigned_image_auth3(self, u_boot_console, efi_boot_env):
73        """
74        Test Case 3 - rejected by digest in dbx
75        """
76        u_boot_console.restart_uboot()
77        disk_img = efi_boot_env
78        with u_boot_console.log.section('Test Case 3a'):
79            # Test Case 3a, rejected by dbx
80            output = u_boot_console.run_command_list([
81                'host bind 0 %s' % disk_img,
82                'fatload host 0:1 4000000 db_hello.auth',
83                'setenv -e -nv -bs -rt -at -i 4000000:$filesize dbx',
84                'fatload host 0:1 4000000 KEK.auth',
85                'setenv -e -nv -bs -rt -at -i 4000000:$filesize KEK',
86                'fatload host 0:1 4000000 PK.auth',
87                'setenv -e -nv -bs -rt -at -i 4000000:$filesize PK'])
88            assert 'Failed to set EFI variable' not in ''.join(output)
89
90            output = u_boot_console.run_command_list([
91                'efidebug boot add 1 HELLO host 0:1 /helloworld.efi ""',
92                'efidebug boot next 1',
93                'bootefi bootmgr'])
94            assert '\'HELLO\' failed' in ''.join(output)
95            output = u_boot_console.run_command_list([
96                'efidebug boot next 1',
97                'efidebug test bootmgr'])
98            assert 'efi_start_image() returned: 26' in ''.join(output)
99            assert 'Hello, world!' not in ''.join(output)
100
101        with u_boot_console.log.section('Test Case 3b'):
102            # Test Case 3b, rejected by dbx even if db allows
103            output = u_boot_console.run_command_list([
104                'fatload host 0:1 4000000 db_hello.auth',
105                'setenv -e -nv -bs -rt -at -i 4000000:$filesize db'])
106            assert 'Failed to set EFI variable' not in ''.join(output)
107
108            output = u_boot_console.run_command_list([
109                'efidebug boot add 1 HELLO host 0:1 /helloworld.efi ""',
110                'efidebug boot next 1',
111                'bootefi bootmgr'])
112            assert '\'HELLO\' failed' in ''.join(output)
113            output = u_boot_console.run_command_list([
114                'efidebug boot next 1',
115                'efidebug test bootmgr'])
116            assert 'efi_start_image() returned: 26' in ''.join(output)
117            assert 'Hello, world!' not in ''.join(output)
118