~funderscore blog cgit wiki get in touch
aboutsummaryrefslogtreecommitdiff
blob: 054be1ee971be3b39dbda2b1b5d8aac2d72bcec6 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
# SPDX-License-Identifier:      GPL-2.0+
# Copyright (c) 2020, Linaro Limited
# Author: AKASHI Takahiro <takahiro.akashi@linaro.org>

"""Fixture for UEFI capsule test."""

from subprocess import call, check_call, CalledProcessError
import pytest
from capsule_defs import CAPSULE_DATA_DIR, CAPSULE_INSTALL_DIR, EFITOOLS_PATH

@pytest.fixture(scope='session')
def efi_capsule_data(request, u_boot_config):
    """Set up a file system and return path to image.

    The function sets up a file system to be used in UEFI capsule and
    authentication test and returns a path to disk image to be used
    for testing.

    request -- Pytest request object.
    u_boot_config -- U-Boot configuration.
    """
    mnt_point = u_boot_config.persistent_data_dir + '/test_efi_capsule'
    data_dir = mnt_point + CAPSULE_DATA_DIR
    install_dir = mnt_point + CAPSULE_INSTALL_DIR
    image_path = u_boot_config.persistent_data_dir + '/test_efi_capsule.img'

    try:
        # Create a target device
        check_call('dd if=/dev/zero of=./spi.bin bs=1MiB count=16', shell=True)

        check_call('rm -rf %s' % mnt_point, shell=True)
        check_call('mkdir -p %s' % data_dir, shell=True)
        check_call('mkdir -p %s' % install_dir, shell=True)

        capsule_auth_enabled = u_boot_config.buildconfig.get(
                    'config_efi_capsule_authenticate')
        if capsule_auth_enabled:
            # Create private key (SIGNER.key) and certificate (SIGNER.crt)
            check_call('cd %s; '
                       'openssl req -x509 -sha256 -newkey rsa:2048 '
                            '-subj /CN=TEST_SIGNER/ -keyout SIGNER.key '
                            '-out SIGNER.crt -nodes -days 365'
                       % data_dir, shell=True)
            check_call('cd %s; %scert-to-efi-sig-list SIGNER.crt SIGNER.esl'
                       % (data_dir, EFITOOLS_PATH), shell=True)

            # Update dtb adding capsule certificate
            check_call('cd %s; '
                       'cp %s/test/py/tests/test_efi_capsule/signature.dts .'
                       % (data_dir, u_boot_config.source_dir), shell=True)
            check_call('cd %s; '
                       'dtc -@ -I dts -O dtb -o signature.dtbo signature.dts; '
                       'fdtoverlay -i %s/arch/sandbox/dts/test.dtb '
                            '-o test_sig.dtb signature.dtbo'
                       % (data_dir, u_boot_config.build_dir), shell=True)

            # Create *malicious* private key (SIGNER2.key) and certificate
            # (SIGNER2.crt)
            check_call('cd %s; '
                       'openssl req -x509 -sha256 -newkey rsa:2048 '
                            '-subj /CN=TEST_SIGNER/ -keyout SIGNER2.key '
                            '-out SIGNER2.crt -nodes -days 365'
                       % data_dir, shell=True)

        # Update dtb to add the version information
        check_call('cd %s; '
                   'cp %s/test/py/tests/test_efi_capsule/version.dts .'
                   % (data_dir, u_boot_config.source_dir), shell=True)
        if capsule_auth_enabled:
            check_call('cd %s; '
                       'dtc -@ -I dts -O dtb -o version.dtbo version.dts; '
                       'fdtoverlay -i test_sig.dtb '
                            '-o test_ver.dtb version.dtbo'
                       % (data_dir), shell=True)
        else:
            check_call('cd %s; '
                       'dtc -@ -I dts -O dtb -o version.dtbo version.dts; '
                       'fdtoverlay -i %s/arch/sandbox/dts/test.dtb '
                            '-o test_ver.dtb version.dtbo'
                       % (data_dir, u_boot_config.build_dir), shell=True)

        # Create capsule files
        # two regions: one for u-boot.bin and the other for u-boot.env
        check_call('cd %s; echo -n u-boot:Old > u-boot.bin.old; echo -n u-boot:New > u-boot.bin.new; echo -n u-boot-env:Old > u-boot.env.old; echo -n u-boot-env:New > u-boot.env.new' % data_dir,
                   shell=True)
        check_call('sed -e \"s?BINFILE1?u-boot.bin.new?\" -e \"s?BINFILE2?u-boot.env.new?\" %s/test/py/tests/test_efi_capsule/uboot_bin_env.its > %s/uboot_bin_env.its' %
                   (u_boot_config.source_dir, data_dir),
                   shell=True)
        check_call('cd %s; %s/tools/mkimage -f uboot_bin_env.its uboot_bin_env.itb' %
                   (data_dir, u_boot_config.build_dir),
                   shell=True)
        check_call('cd %s; %s/tools/mkeficapsule --index 1 --guid 09D7CF52-0720-4710-91D1-08469B7FE9C8 u-boot.bin.new Test01' %
                   (data_dir, u_boot_config.build_dir),
                   shell=True)
        check_call('cd %s; %s/tools/mkeficapsule --index 2 --guid 5A7021F5-FEF2-48B4-AABA-832E777418C0 u-boot.env.new Test02' %
                   (data_dir, u_boot_config.build_dir),
                   shell=True)
        check_call('cd %s; %s/tools/mkeficapsule --index 1 --guid 058B7D83-50D5-4C47-A195-60D86AD341C4 u-boot.bin.new Test03' %
                   (data_dir, u_boot_config.build_dir),
                   shell=True)
        check_call('cd %s; %s/tools/mkeficapsule --index 1 --guid 3673B45D-6A7C-46F3-9E60-ADABB03F7937 uboot_bin_env.itb Test04' %
                   (data_dir, u_boot_config.build_dir),
                   shell=True)
        check_call('cd %s; %s/tools/mkeficapsule --index 1 --guid  058B7D83-50D5-4C47-A195-60D86AD341C4 uboot_bin_env.itb Test05' %
                   (data_dir, u_boot_config.build_dir),
                   shell=True)
        check_call('cd %s; %s/tools/mkeficapsule --index 1 --fw-version 5 '
                        '--guid 09D7CF52-0720-4710-91D1-08469B7FE9C8 u-boot.bin.new Test101' %
                   (data_dir, u_boot_config.build_dir),
                   shell=True)
        check_call('cd %s; %s/tools/mkeficapsule --index 2 --fw-version 10 '
                        '--guid 5A7021F5-FEF2-48B4-AABA-832E777418C0 u-boot.env.new Test102' %
                   (data_dir, u_boot_config.build_dir),
                   shell=True)
        check_call('cd %s; %s/tools/mkeficapsule --index 1 --fw-version 2 '
                        '--guid 09D7CF52-0720-4710-91D1-08469B7FE9C8 u-boot.bin.new Test103' %
                   (data_dir, u_boot_config.build_dir),
                   shell=True)
        check_call('cd %s; %s/tools/mkeficapsule --index 1 --fw-version 5 '
                        '--guid 3673B45D-6A7C-46F3-9E60-ADABB03F7937 uboot_bin_env.itb Test104' %
                   (data_dir, u_boot_config.build_dir),
                   shell=True)
        check_call('cd %s; %s/tools/mkeficapsule --index 1 --fw-version 2 '
                        '--guid 3673B45D-6A7C-46F3-9E60-ADABB03F7937 uboot_bin_env.itb Test105' %
                   (data_dir, u_boot_config.build_dir),
                   shell=True)

        if capsule_auth_enabled:
            # raw firmware signed with proper key
            check_call('cd %s; '
                       '%s/tools/mkeficapsule --index 1 --monotonic-count 1 '
                            '--private-key SIGNER.key --certificate SIGNER.crt '
                            '--guid 09D7CF52-0720-4710-91D1-08469B7FE9C8 '
                            'u-boot.bin.new Test11'
                       % (data_dir, u_boot_config.build_dir),
                       shell=True)
            # raw firmware signed with *mal* key
            check_call('cd %s; '
                       '%s/tools/mkeficapsule --index 1 --monotonic-count 1 '
                            '--private-key SIGNER2.key '
                            '--certificate SIGNER2.crt '
                            '--guid 09D7CF52-0720-4710-91D1-08469B7FE9C8 '
                            'u-boot.bin.new Test12'
                       % (data_dir, u_boot_config.build_dir),
                       shell=True)
            # FIT firmware signed with proper key
            check_call('cd %s; '
                       '%s/tools/mkeficapsule --index 1 --monotonic-count 1 '
                            '--private-key SIGNER.key --certificate SIGNER.crt '
                            '--guid 3673B45D-6A7C-46F3-9E60-ADABB03F7937 '
                            'uboot_bin_env.itb Test13'
                       % (data_dir, u_boot_config.build_dir),
                       shell=True)
            # FIT firmware signed with *mal* key
            check_call('cd %s; '
                       '%s/tools/mkeficapsule --index 1 --monotonic-count 1 '
                            '--private-key SIGNER2.key '
                            '--certificate SIGNER2.crt '
                            '--guid 3673B45D-6A7C-46F3-9E60-ADABB03F7937 '
                            'uboot_bin_env.itb Test14'
                       % (data_dir, u_boot_config.build_dir),
                       shell=True)
            # raw firmware signed with proper key with version information
            check_call('cd %s; '
                       '%s/tools/mkeficapsule --index 1 --monotonic-count 1 '
                            '--fw-version 5 '
                            '--private-key SIGNER.key --certificate SIGNER.crt '
                            '--guid 09D7CF52-0720-4710-91D1-08469B7FE9C8 '
                            'u-boot.bin.new Test111'
                       % (data_dir, u_boot_config.build_dir),
                       shell=True)
            # raw firmware signed with proper key with version information
            check_call('cd %s; '
                       '%s/tools/mkeficapsule --index 2 --monotonic-count 1 '
                            '--fw-version 10 '
                            '--private-key SIGNER.key --certificate SIGNER.crt '
                            '--guid 5A7021F5-FEF2-48B4-AABA-832E777418C0 '
                            'u-boot.env.new Test112'
                       % (data_dir, u_boot_config.build_dir),
                       shell=True)
            # raw firmware signed with proper key with lower version information
            check_call('cd %s; '
                       '%s/tools/mkeficapsule --index 1 --monotonic-count 1 '
                            '--fw-version 2 '
                            '--private-key SIGNER.key --certificate SIGNER.crt '
                            '--guid 09D7CF52-0720-4710-91D1-08469B7FE9C8 '
                            'u-boot.bin.new Test113'
                       % (data_dir, u_boot_config.build_dir),
                       shell=True)
            # FIT firmware signed with proper key with version information
            check_call('cd %s; '
                       '%s/tools/mkeficapsule --index 1 --monotonic-count 1 '
                            '--fw-version 5 '
                            '--private-key SIGNER.key --certificate SIGNER.crt '
                            '--guid 3673B45D-6A7C-46F3-9E60-ADABB03F7937 '
                            'uboot_bin_env.itb Test114'
                       % (data_dir, u_boot_config.build_dir),
                       shell=True)
            # FIT firmware signed with proper key with lower version information
            check_call('cd %s; '
                       '%s/tools/mkeficapsule --index 1 --monotonic-count 1 '
                            '--fw-version 2 '
                            '--private-key SIGNER.key --certificate SIGNER.crt '
                            '--guid 3673B45D-6A7C-46F3-9E60-ADABB03F7937 '
                            'uboot_bin_env.itb Test115'
                       % (data_dir, u_boot_config.build_dir),
                       shell=True)

        # Create a disk image with EFI system partition
        check_call('virt-make-fs --partition=gpt --size=+1M --type=vfat %s %s' %
                   (mnt_point, image_path), shell=True)
        check_call('sgdisk %s -A 1:set:0 -t 1:C12A7328-F81F-11D2-BA4B-00A0C93EC93B' %
                   image_path, shell=True)

    except CalledProcessError as exception:
        pytest.skip('Setup failed: %s' % exception.cmd)
        return
    else:
        yield image_path
    finally:
        call('rm -rf %s' % mnt_point, shell=True)
        call('rm -f %s' % image_path, shell=True)
        call('rm -f ./spi.bin', shell=True)