1# SPDX-License-Identifier:      GPL-2.0+
2# Copyright (c) 2021, Linaro Limited
3# Author: AKASHI Takahiro <takahiro.akashi@linaro.org>
4
5"""U-Boot UEFI: Firmware Update (Signed capsule with raw images) Test
6This test verifies capsule-on-disk firmware update
7with signed capsule files containing raw images
8"""
9
10import pytest
11from capsule_common import (
12    capsule_setup,
13    init_content,
14    place_capsule_file,
15    exec_manual_update,
16    check_file_removed,
17    verify_content,
18    do_reboot_dtb_specified
19)
20
21@pytest.mark.boardspec('sandbox')
22@pytest.mark.buildconfigspec('efi_capsule_firmware_raw')
23@pytest.mark.buildconfigspec('efi_capsule_authenticate')
24@pytest.mark.buildconfigspec('dfu')
25@pytest.mark.buildconfigspec('dfu_sf')
26@pytest.mark.buildconfigspec('cmd_efidebug')
27@pytest.mark.buildconfigspec('cmd_fat')
28@pytest.mark.buildconfigspec('cmd_memory')
29@pytest.mark.buildconfigspec('cmd_nvedit_efi')
30@pytest.mark.buildconfigspec('cmd_sf')
31@pytest.mark.slow
32class TestEfiCapsuleFirmwareSignedRaw():
33    """Firmware Update (Signed capsule with raw images) Test
34    """
35
36    def test_efi_capsule_auth1(
37            self, u_boot_config, ubman, efi_capsule_data):
38        """Test Case 1 - Update U-Boot on SPI Flash, raw image format
39        0x100000-0x150000: U-Boot binary (but dummy)
40
41        If the capsule is properly signed, the authentication
42        should pass and the firmware be updated.
43        """
44        disk_img = efi_capsule_data
45        capsule_files =  ['Test11']
46        with ubman.log.section('Test Case 1-a, before reboot'):
47            capsule_setup(ubman, disk_img, '0x0000000000000004')
48            init_content(ubman, '100000', 'u-boot.bin.old', 'Old')
49            place_capsule_file(ubman, capsule_files)
50
51        do_reboot_dtb_specified(u_boot_config, ubman, 'test_sig.dtb')
52
53        capsule_early = u_boot_config.buildconfig.get(
54            'config_efi_capsule_on_disk_early')
55        with ubman.log.section('Test Case 1-b, after reboot'):
56            if not capsule_early:
57                exec_manual_update(ubman, disk_img, capsule_files)
58
59            check_file_removed(ubman, disk_img, capsule_files)
60
61            verify_content(ubman, '100000', 'u-boot:New')
62
63    def test_efi_capsule_auth2(
64            self, u_boot_config, ubman, efi_capsule_data):
65        """Test Case 2 - Update U-Boot on SPI Flash, raw image format
66        0x100000-0x150000: U-Boot binary (but dummy)
67
68        If the capsule is signed but with an invalid key,
69        the authentication should fail and the firmware
70        not be updated.
71        """
72        disk_img = efi_capsule_data
73        capsule_files = ['Test12']
74        with ubman.log.section('Test Case 2-a, before reboot'):
75            capsule_setup(ubman, disk_img, '0x0000000000000004')
76            init_content(ubman, '100000', 'u-boot.bin.old', 'Old')
77            place_capsule_file(ubman, capsule_files)
78
79        do_reboot_dtb_specified(u_boot_config, ubman, 'test_sig.dtb')
80
81        capsule_early = u_boot_config.buildconfig.get(
82            'config_efi_capsule_on_disk_early')
83        with ubman.log.section('Test Case 2-b, after reboot'):
84            if not capsule_early:
85                exec_manual_update(ubman, disk_img, capsule_files)
86
87            check_file_removed(ubman, disk_img, capsule_files)
88
89            # TODO: check CapsuleStatus in CapsuleXXXX
90
91            verify_content(ubman, '100000', 'u-boot:Old')
92
93    def test_efi_capsule_auth3(
94            self, u_boot_config, ubman, efi_capsule_data):
95        """Test Case 3 - Update U-Boot on SPI Flash, raw image format
96        0x100000-0x150000: U-Boot binary (but dummy)
97
98        If the capsule is not signed, the authentication
99        should fail and the firmware not be updated.
100        """
101        disk_img = efi_capsule_data
102        capsule_files = ['Test02']
103        with ubman.log.section('Test Case 3-a, before reboot'):
104            capsule_setup(ubman, disk_img, '0x0000000000000004')
105            init_content(ubman, '100000', 'u-boot.bin.old', 'Old')
106            place_capsule_file(ubman, capsule_files)
107
108        do_reboot_dtb_specified(u_boot_config, ubman, 'test_sig.dtb')
109
110        capsule_early = u_boot_config.buildconfig.get(
111            'config_efi_capsule_on_disk_early')
112        with ubman.log.section('Test Case 3-b, after reboot'):
113            if not capsule_early:
114                exec_manual_update(ubman, disk_img, capsule_files)
115
116            # deleted anyway
117            check_file_removed(ubman, disk_img, capsule_files)
118
119            # TODO: check CapsuleStatus in CapsuleXXXX
120
121            verify_content(ubman, '100000', 'u-boot:Old')
122
123    def test_efi_capsule_auth4(
124            self, u_boot_config, ubman, efi_capsule_data):
125        """Test Case 4 - Update U-Boot on SPI Flash, raw image format with version information
126        0x100000-0x150000: U-Boot binary (but dummy)
127
128        If the capsule is properly signed, the authentication
129        should pass and the firmware be updated.
130        """
131        disk_img = efi_capsule_data
132        capsule_files = ['Test111', 'Test112']
133        with ubman.log.section('Test Case 4-a, before reboot'):
134            capsule_setup(ubman, disk_img, '0x0000000000000004')
135            init_content(ubman, '100000', 'u-boot.bin.old', 'Old')
136            place_capsule_file(ubman, capsule_files)
137
138        do_reboot_dtb_specified(u_boot_config, ubman, 'test_ver.dtb')
139
140        capsule_early = u_boot_config.buildconfig.get(
141            'config_efi_capsule_on_disk_early')
142        with ubman.log.section('Test Case 4-b, after reboot'):
143            if not capsule_early:
144                exec_manual_update(ubman, disk_img, capsule_files)
145
146            check_file_removed(ubman, disk_img, capsule_files)
147
148            output = ubman.run_command_list([
149                'env set dfu_alt_info "sf 0:0=u-boot-bin raw 0x100000 0x50000;'
150                'u-boot-env raw 0x150000 0x200000"',
151                'efidebug capsule esrt'])
152
153            # ensure that SANDBOX_UBOOT_IMAGE_GUID is in the ESRT.
154            assert '985F2937-7C2E-5E9A-8A5E-8E063312964B' in ''.join(output)
155            assert 'ESRT: fw_version=5' in ''.join(output)
156            assert 'ESRT: lowest_supported_fw_version=3' in ''.join(output)
157
158            # ensure that SANDBOX_UBOOT_ENV_IMAGE_GUID is in the ESRT.
159            assert '9E339473-C2EB-530A-A69B-0CD6BBBED40E' in ''.join(output)
160            assert 'ESRT: fw_version=10' in ''.join(output)
161            assert 'ESRT: lowest_supported_fw_version=7' in ''.join(output)
162
163            verify_content(ubman, '100000', 'u-boot:New')
164            verify_content(ubman, '150000', 'u-boot-env:New')
165
166    def test_efi_capsule_auth5(
167            self, u_boot_config, ubman, efi_capsule_data):
168        """Test Case 5 - Update U-Boot on SPI Flash, raw image format with version information
169        0x100000-0x150000: U-Boot binary (but dummy)
170
171        If the capsule is signed but fw_version is lower than lowest
172        supported version, the authentication should fail and the firmware
173        not be updated.
174        """
175        disk_img = efi_capsule_data
176        capsule_files = ['Test113']
177        with ubman.log.section('Test Case 5-a, before reboot'):
178            capsule_setup(ubman, disk_img, '0x0000000000000004')
179            init_content(ubman, '100000', 'u-boot.bin.old', 'Old')
180            place_capsule_file(ubman, capsule_files)
181
182        do_reboot_dtb_specified(u_boot_config, ubman, 'test_ver.dtb')
183
184        capsule_early = u_boot_config.buildconfig.get(
185            'config_efi_capsule_on_disk_early')
186        with ubman.log.section('Test Case 5-b, after reboot'):
187            if not capsule_early:
188                exec_manual_update(ubman, disk_img, capsule_files)
189
190            check_file_removed(ubman, disk_img, capsule_files)
191
192            verify_content(ubman, '100000', 'u-boot:Old')
193