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: Variable Authentication Test
6
7"""
8This test verifies variable authentication
9"""
10
11import pytest
12
13
14@pytest.mark.boardspec('sandbox')
15@pytest.mark.buildconfigspec('efi_secure_boot')
16@pytest.mark.buildconfigspec('cmd_fat')
17@pytest.mark.buildconfigspec('cmd_nvedit_efi')
18@pytest.mark.slow
19class TestEfiAuthVar(object):
20    def test_efi_var_auth1(self, u_boot_console, efi_boot_env):
21        """
22        Test Case 1 - Install signature database
23        """
24        u_boot_console.restart_uboot()
25        disk_img = efi_boot_env
26        with u_boot_console.log.section('Test Case 1a'):
27            # Test Case 1a, Initial secure state
28            output = u_boot_console.run_command_list([
29                'host bind 0 %s' % disk_img,
30                'printenv -e SecureBoot'])
31            assert '00000000: 00' in ''.join(output)
32
33            output = u_boot_console.run_command(
34                'printenv -e SetupMode')
35            assert '00000000: 01' in output
36
37        with u_boot_console.log.section('Test Case 1b'):
38            # Test Case 1b, PK without AUTHENTICATED_WRITE_ACCESS
39            output = u_boot_console.run_command_list([
40                'fatload host 0:1 4000000 PK.auth',
41                'setenv -e -nv -bs -rt -i 4000000:$filesize PK'])
42            assert 'Failed to set EFI variable' in ''.join(output)
43
44        with u_boot_console.log.section('Test Case 1c'):
45            # Test Case 1c, install PK
46            output = u_boot_console.run_command_list([
47                'fatload host 0:1 4000000 PK.auth',
48                'setenv -e -nv -bs -rt -at -i 4000000:$filesize PK',
49                'printenv -e -n PK'])
50            assert 'PK:' in ''.join(output)
51
52            output = u_boot_console.run_command(
53                'printenv -e SecureBoot')
54            assert '00000000: 01' in output
55            output = u_boot_console.run_command(
56                'printenv -e SetupMode')
57            assert '00000000: 00' in output
58
59        with u_boot_console.log.section('Test Case 1d'):
60            # Test Case 1d, db/dbx without KEK
61            output = u_boot_console.run_command_list([
62                'fatload host 0:1 4000000 db.auth',
63                'setenv -e -nv -bs -rt -at -i 4000000:$filesize db'])
64            assert 'Failed to set EFI variable' in ''.join(output)
65
66            output = u_boot_console.run_command_list([
67                'fatload host 0:1 4000000 db.auth',
68                'setenv -e -nv -bs -rt -at -i 4000000:$filesize dbx'])
69            assert 'Failed to set EFI variable' in ''.join(output)
70
71        with u_boot_console.log.section('Test Case 1e'):
72            # Test Case 1e, install KEK
73            output = u_boot_console.run_command_list([
74                'fatload host 0:1 4000000 KEK.auth',
75                'setenv -e -nv -bs -rt -i 4000000:$filesize KEK'])
76            assert 'Failed to set EFI variable' in ''.join(output)
77
78            output = u_boot_console.run_command_list([
79                'fatload host 0:1 4000000 KEK.auth',
80                'setenv -e -nv -bs -rt -at -i 4000000:$filesize KEK',
81                'printenv -e -n KEK'])
82            assert 'KEK:' in ''.join(output)
83
84            output = u_boot_console.run_command(
85                'printenv -e SecureBoot')
86            assert '00000000: 01' in output
87
88        with u_boot_console.log.section('Test Case 1f'):
89            # Test Case 1f, install db
90            output = u_boot_console.run_command_list([
91                'fatload host 0:1 4000000 db.auth',
92                'setenv -e -nv -bs -rt -i 4000000:$filesize db'])
93            assert 'Failed to set EFI variable' in ''.join(output)
94
95            output = u_boot_console.run_command_list([
96                'fatload host 0:1 4000000 db.auth',
97                'setenv -e -nv -bs -rt -at -i 4000000:$filesize db',
98                'printenv -e -n -guid d719b2cb-3d3a-4596-a3bc-dad00e67656f db'])
99            assert 'Failed to set EFI variable' not in ''.join(output)
100            assert 'db:' in ''.join(output)
101
102            output = u_boot_console.run_command(
103                'printenv -e SecureBoot')
104            assert '00000000: 01' in output
105
106        with u_boot_console.log.section('Test Case 1g'):
107            # Test Case 1g, install dbx
108            output = u_boot_console.run_command_list([
109                'fatload host 0:1 4000000 dbx.auth',
110                'setenv -e -nv -bs -rt -i 4000000:$filesize dbx'])
111            assert 'Failed to set EFI variable' in ''.join(output)
112
113            output = u_boot_console.run_command_list([
114                'fatload host 0:1 4000000 dbx.auth',
115                'setenv -e -nv -bs -rt -at -i 4000000:$filesize dbx',
116                'printenv -e -n -guid d719b2cb-3d3a-4596-a3bc-dad00e67656f dbx'])
117            assert 'Failed to set EFI variable' not in ''.join(output)
118            assert 'dbx:' in ''.join(output)
119
120            output = u_boot_console.run_command(
121                'printenv -e SecureBoot')
122            assert '00000000: 01' in output
123
124    def test_efi_var_auth2(self, u_boot_console, efi_boot_env):
125        """
126        Test Case 2 - Update database by overwriting
127        """
128        u_boot_console.restart_uboot()
129        disk_img = efi_boot_env
130        with u_boot_console.log.section('Test Case 2a'):
131            # Test Case 2a, update without AUTHENTICATED_WRITE_ACCESS
132            output = u_boot_console.run_command_list([
133                'host bind 0 %s' % disk_img,
134                'fatload host 0:1 4000000 PK.auth',
135                'setenv -e -nv -bs -rt -at -i 4000000:$filesize PK',
136                'fatload host 0:1 4000000 KEK.auth',
137                'setenv -e -nv -bs -rt -at -i 4000000:$filesize KEK',
138                'fatload host 0:1 4000000 db.auth',
139                'setenv -e -nv -bs -rt -at -i 4000000:$filesize db',
140                'printenv -e -n -guid d719b2cb-3d3a-4596-a3bc-dad00e67656f db'])
141            assert 'Failed to set EFI variable' not in ''.join(output)
142            assert 'db:' in ''.join(output)
143
144            output = u_boot_console.run_command_list([
145                'fatload host 0:1 4000000 db1.auth',
146                'setenv -e -nv -bs -rt -i 4000000:$filesize db'])
147            assert 'Failed to set EFI variable' in ''.join(output)
148
149        with u_boot_console.log.section('Test Case 2b'):
150            # Test Case 2b, update without correct signature
151            output = u_boot_console.run_command_list([
152                'fatload host 0:1 4000000 db.esl',
153                'setenv -e -nv -bs -rt -at -i 4000000:$filesize db'])
154            assert 'Failed to set EFI variable' in ''.join(output)
155
156        with u_boot_console.log.section('Test Case 2c'):
157            # Test Case 2c, update with correct signature
158            output = u_boot_console.run_command_list([
159                'fatload host 0:1 4000000 db1.auth',
160                'setenv -e -nv -bs -rt -at -i 4000000:$filesize db',
161                'printenv -e -n -guid d719b2cb-3d3a-4596-a3bc-dad00e67656f db'])
162            assert 'Failed to set EFI variable' not in ''.join(output)
163            assert 'db:' in ''.join(output)
164
165    def test_efi_var_auth3(self, u_boot_console, efi_boot_env):
166        """
167        Test Case 3 - Append database
168        """
169        u_boot_console.restart_uboot()
170        disk_img = efi_boot_env
171        with u_boot_console.log.section('Test Case 3a'):
172            # Test Case 3a, update without AUTHENTICATED_WRITE_ACCESS
173            output = u_boot_console.run_command_list([
174                'host bind 0 %s' % disk_img,
175                'fatload host 0:1 4000000 PK.auth',
176                'setenv -e -nv -bs -rt -at -i 4000000:$filesize PK',
177                'fatload host 0:1 4000000 KEK.auth',
178                'setenv -e -nv -bs -rt -at -i 4000000:$filesize KEK',
179                'fatload host 0:1 4000000 db.auth',
180                'setenv -e -nv -bs -rt -at -i 4000000:$filesize db',
181                'printenv -e -n -guid d719b2cb-3d3a-4596-a3bc-dad00e67656f db'])
182            assert 'Failed to set EFI variable' not in ''.join(output)
183            assert 'db:' in ''.join(output)
184
185            output = u_boot_console.run_command_list([
186                'fatload host 0:1 4000000 db1.auth',
187                'setenv -e -nv -bs -rt -a -i 4000000:$filesize db'])
188            assert 'Failed to set EFI variable' in ''.join(output)
189
190        with u_boot_console.log.section('Test Case 3b'):
191            # Test Case 3b, update without correct signature
192            output = u_boot_console.run_command_list([
193                'fatload host 0:1 4000000 db.esl',
194                'setenv -e -nv -bs -rt -at -a -i 4000000:$filesize db'])
195            assert 'Failed to set EFI variable' in ''.join(output)
196
197        with u_boot_console.log.section('Test Case 3c'):
198            # Test Case 3c, update with correct signature
199            output = u_boot_console.run_command_list([
200                'fatload host 0:1 4000000 db1.auth',
201                'setenv -e -nv -bs -rt -at -a -i 4000000:$filesize db',
202                'printenv -e -n -guid d719b2cb-3d3a-4596-a3bc-dad00e67656f db'])
203            assert 'Failed to set EFI variable' not in ''.join(output)
204            assert 'db:' in ''.join(output)
205
206    def test_efi_var_auth4(self, u_boot_console, efi_boot_env):
207        """
208        Test Case 4 - Delete database without authentication
209        """
210        u_boot_console.restart_uboot()
211        disk_img = efi_boot_env
212        with u_boot_console.log.section('Test Case 4a'):
213            # Test Case 4a, update without AUTHENTICATED_WRITE_ACCESS
214            output = u_boot_console.run_command_list([
215                'host bind 0 %s' % disk_img,
216                'fatload host 0:1 4000000 PK.auth',
217                'setenv -e -nv -bs -rt -at -i 4000000:$filesize PK',
218                'fatload host 0:1 4000000 KEK.auth',
219                'setenv -e -nv -bs -rt -at -i 4000000:$filesize KEK',
220                'fatload host 0:1 4000000 db.auth',
221                'setenv -e -nv -bs -rt -at -i 4000000:$filesize db',
222                'printenv -e -n -guid d719b2cb-3d3a-4596-a3bc-dad00e67656f db'])
223            assert 'Failed to set EFI variable' not in ''.join(output)
224            assert 'db:' in ''.join(output)
225
226            output = u_boot_console.run_command_list([
227                'setenv -e -nv -bs -rt db',
228                'printenv -e -n -guid d719b2cb-3d3a-4596-a3bc-dad00e67656f db'])
229            assert 'Failed to set EFI variable' in ''.join(output)
230            assert 'db:' in ''.join(output)
231
232        with u_boot_console.log.section('Test Case 4b'):
233            # Test Case 4b, update without correct signature/data
234            output = u_boot_console.run_command_list([
235                'setenv -e -nv -bs -rt -at db',
236                'printenv -e -n -guid d719b2cb-3d3a-4596-a3bc-dad00e67656f db'])
237            assert 'Failed to set EFI variable' in ''.join(output)
238            assert 'db:' in ''.join(output)
239
240    def test_efi_var_auth5(self, u_boot_console, efi_boot_env):
241        """
242        Test Case 5 - Uninstall(delete) PK
243        """
244        u_boot_console.restart_uboot()
245        disk_img = efi_boot_env
246        with u_boot_console.log.section('Test Case 5a'):
247            # Test Case 5a, Uninstall PK without correct signature
248            output = u_boot_console.run_command_list([
249                'host bind 0 %s' % disk_img,
250                'fatload host 0:1 4000000 PK.auth',
251                'setenv -e -nv -bs -rt -at -i 4000000:$filesize PK',
252                'fatload host 0:1 4000000 KEK.auth',
253                'setenv -e -nv -bs -rt -at -i 4000000:$filesize KEK',
254                'fatload host 0:1 4000000 db.auth',
255                'setenv -e -nv -bs -rt -at -i 4000000:$filesize db',
256                'printenv -e -n PK'])
257            assert 'Failed to set EFI variable' not in ''.join(output)
258            assert 'PK:' in ''.join(output)
259
260            output = u_boot_console.run_command_list([
261                'fatload host 0:1 4000000 PK_null.esl',
262                'setenv -e -nv -bs -rt -at -i 4000000:$filesize PK',
263                'printenv -e -n PK'])
264            assert 'Failed to set EFI variable' in ''.join(output)
265            assert 'PK:' in ''.join(output)
266
267        with u_boot_console.log.section('Test Case 5b'):
268            # Test Case 5b, Uninstall PK with correct signature
269            output = u_boot_console.run_command_list([
270                'fatload host 0:1 4000000 PK_null.auth',
271                'setenv -e -nv -bs -rt -at -i 4000000:$filesize PK',
272                'printenv -e -n PK'])
273            assert 'Failed to set EFI variable' not in ''.join(output)
274            assert '\"PK\" not defined' in ''.join(output)
275
276            output = u_boot_console.run_command(
277                'printenv -e SecureBoot')
278            assert '00000000: 00' in output
279            output = u_boot_console.run_command(
280                'printenv -e SetupMode')
281            assert '00000000: 01' in output
282