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 signed 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 TestEfiSignedImage(object): 21 def test_efi_signed_image_auth1(self, u_boot_console, efi_boot_env): 22 """ 23 Test Case 1 - Secure boot is not in force 24 """ 25 u_boot_console.restart_uboot() 26 disk_img = efi_boot_env 27 with u_boot_console.log.section('Test Case 1a'): 28 # Test Case 1a, run signed image if no PK 29 output = u_boot_console.run_command_list([ 30 'host bind 0 %s' % disk_img, 31 'efidebug boot add 1 HELLO1 host 0:1 /helloworld.efi.signed ""', 32 'efidebug boot next 1', 33 'bootefi bootmgr']) 34 assert 'Hello, world!' in ''.join(output) 35 36 with u_boot_console.log.section('Test Case 1b'): 37 # Test Case 1b, run unsigned image if no PK 38 output = u_boot_console.run_command_list([ 39 'efidebug boot add 2 HELLO2 host 0:1 /helloworld.efi ""', 40 'efidebug boot next 2', 41 'bootefi bootmgr']) 42 assert 'Hello, world!' in ''.join(output) 43 44 def test_efi_signed_image_auth2(self, u_boot_console, efi_boot_env): 45 """ 46 Test Case 2 - Secure boot is in force, 47 authenticated by db (TEST_db certificate in db) 48 """ 49 u_boot_console.restart_uboot() 50 disk_img = efi_boot_env 51 with u_boot_console.log.section('Test Case 2a'): 52 # Test Case 2a, db is not yet installed 53 output = u_boot_console.run_command_list([ 54 'host bind 0 %s' % disk_img, 55 'fatload host 0:1 4000000 KEK.auth', 56 'setenv -e -nv -bs -rt -at -i 4000000:$filesize KEK', 57 'fatload host 0:1 4000000 PK.auth', 58 'setenv -e -nv -bs -rt -at -i 4000000:$filesize PK']) 59 assert 'Failed to set EFI variable' not in ''.join(output) 60 output = u_boot_console.run_command_list([ 61 'efidebug boot add 1 HELLO1 host 0:1 /helloworld.efi.signed ""', 62 'efidebug boot next 1', 63 'efidebug test bootmgr']) 64 assert('\'HELLO1\' failed' in ''.join(output)) 65 assert('efi_start_image() returned: 26' in ''.join(output)) 66 output = u_boot_console.run_command_list([ 67 'efidebug boot add 2 HELLO2 host 0:1 /helloworld.efi ""', 68 'efidebug boot next 2', 69 'efidebug test bootmgr']) 70 assert '\'HELLO2\' failed' in ''.join(output) 71 assert 'efi_start_image() returned: 26' in ''.join(output) 72 73 with u_boot_console.log.section('Test Case 2b'): 74 # Test Case 2b, authenticated by db 75 output = u_boot_console.run_command_list([ 76 'fatload host 0:1 4000000 db.auth', 77 'setenv -e -nv -bs -rt -at -i 4000000:$filesize db']) 78 assert 'Failed to set EFI variable' not in ''.join(output) 79 output = u_boot_console.run_command_list([ 80 'efidebug boot next 2', 81 'efidebug test bootmgr']) 82 assert '\'HELLO2\' failed' in ''.join(output) 83 assert 'efi_start_image() returned: 26' in ''.join(output) 84 output = u_boot_console.run_command_list([ 85 'efidebug boot next 1', 86 'bootefi bootmgr']) 87 assert 'Hello, world!' in ''.join(output) 88 89 def test_efi_signed_image_auth3(self, u_boot_console, efi_boot_env): 90 """ 91 Test Case 3 - rejected by dbx (TEST_db certificate in dbx) 92 """ 93 u_boot_console.restart_uboot() 94 disk_img = efi_boot_env 95 with u_boot_console.log.section('Test Case 3a'): 96 # Test Case 3a, rejected by dbx 97 output = u_boot_console.run_command_list([ 98 'host bind 0 %s' % disk_img, 99 'fatload host 0:1 4000000 db.auth', 100 'setenv -e -nv -bs -rt -at -i 4000000:$filesize dbx', 101 'fatload host 0:1 4000000 KEK.auth', 102 'setenv -e -nv -bs -rt -at -i 4000000:$filesize KEK', 103 'fatload host 0:1 4000000 PK.auth', 104 'setenv -e -nv -bs -rt -at -i 4000000:$filesize PK']) 105 assert 'Failed to set EFI variable' not in ''.join(output) 106 output = u_boot_console.run_command_list([ 107 'efidebug boot add 1 HELLO host 0:1 /helloworld.efi.signed ""', 108 'efidebug boot next 1', 109 'efidebug test bootmgr']) 110 assert '\'HELLO\' failed' in ''.join(output) 111 assert 'efi_start_image() returned: 26' in ''.join(output) 112 113 with u_boot_console.log.section('Test Case 3b'): 114 # Test Case 3b, rejected by dbx even if db allows 115 output = u_boot_console.run_command_list([ 116 'fatload host 0:1 4000000 db.auth', 117 'setenv -e -nv -bs -rt -at -i 4000000:$filesize db']) 118 assert 'Failed to set EFI variable' not in ''.join(output) 119 output = u_boot_console.run_command_list([ 120 'efidebug boot next 1', 121 'efidebug test bootmgr']) 122 assert '\'HELLO\' failed' in ''.join(output) 123 assert 'efi_start_image() returned: 26' in ''.join(output) 124 125 def test_efi_signed_image_auth4(self, u_boot_console, efi_boot_env): 126 """ 127 Test Case 4 - revoked by dbx (digest of TEST_db certificate in dbx) 128 """ 129 u_boot_console.restart_uboot() 130 disk_img = efi_boot_env 131 with u_boot_console.log.section('Test Case 4'): 132 # Test Case 4, rejected by dbx 133 output = u_boot_console.run_command_list([ 134 'host bind 0 %s' % disk_img, 135 'fatload host 0:1 4000000 dbx_hash.auth', 136 'setenv -e -nv -bs -rt -at -i 4000000:$filesize dbx', 137 'fatload host 0:1 4000000 db.auth', 138 'setenv -e -nv -bs -rt -at -i 4000000:$filesize db', 139 'fatload host 0:1 4000000 KEK.auth', 140 'setenv -e -nv -bs -rt -at -i 4000000:$filesize KEK', 141 'fatload host 0:1 4000000 PK.auth', 142 'setenv -e -nv -bs -rt -at -i 4000000:$filesize PK']) 143 assert 'Failed to set EFI variable' not in ''.join(output) 144 output = u_boot_console.run_command_list([ 145 'efidebug boot add 1 HELLO host 0:1 /helloworld.efi.signed ""', 146 'efidebug boot next 1', 147 'efidebug test bootmgr']) 148 assert '\'HELLO\' failed' in ''.join(output) 149 assert 'efi_start_image() returned: 26' in ''.join(output) 150 151 def test_efi_signed_image_auth5(self, u_boot_console, efi_boot_env): 152 """ 153 Test Case 5 - multiple signatures 154 one signed with TEST_db, and 155 one signed with TEST_db1 156 """ 157 u_boot_console.restart_uboot() 158 disk_img = efi_boot_env 159 with u_boot_console.log.section('Test Case 5a'): 160 # Test Case 5a, authenticated even if only one of signatures 161 # is verified 162 output = u_boot_console.run_command_list([ 163 'host bind 0 %s' % disk_img, 164 'fatload host 0:1 4000000 db.auth', 165 'setenv -e -nv -bs -rt -at -i 4000000:$filesize db', 166 'fatload host 0:1 4000000 KEK.auth', 167 'setenv -e -nv -bs -rt -at -i 4000000:$filesize KEK', 168 'fatload host 0:1 4000000 PK.auth', 169 'setenv -e -nv -bs -rt -at -i 4000000:$filesize PK']) 170 assert 'Failed to set EFI variable' not in ''.join(output) 171 output = u_boot_console.run_command_list([ 172 'efidebug boot add 1 HELLO host 0:1 /helloworld.efi.signed_2sigs ""', 173 'efidebug boot next 1', 174 'efidebug test bootmgr']) 175 assert 'Hello, world!' in ''.join(output) 176 177 with u_boot_console.log.section('Test Case 5b'): 178 # Test Case 5b, authenticated if both signatures are verified 179 output = u_boot_console.run_command_list([ 180 'fatload host 0:1 4000000 db1.auth', 181 'setenv -e -nv -bs -rt -at -a -i 4000000:$filesize db']) 182 assert 'Failed to set EFI variable' not in ''.join(output) 183 output = u_boot_console.run_command_list([ 184 'efidebug boot next 1', 185 'efidebug test bootmgr']) 186 assert 'Hello, world!' in ''.join(output) 187 188 with u_boot_console.log.section('Test Case 5c'): 189 # Test Case 5c, not rejected if one of signatures (digest of 190 # certificate) is revoked 191 output = u_boot_console.run_command_list([ 192 'fatload host 0:1 4000000 dbx_hash.auth', 193 'setenv -e -nv -bs -rt -at -i 4000000:$filesize dbx']) 194 assert 'Failed to set EFI variable' not in ''.join(output) 195 output = u_boot_console.run_command_list([ 196 'efidebug boot next 1', 197 'efidebug test bootmgr']) 198 assert 'Hello, world!' in ''.join(output) 199 200 with u_boot_console.log.section('Test Case 5d'): 201 # Test Case 5d, rejected if both of signatures are revoked 202 output = u_boot_console.run_command_list([ 203 'fatload host 0:1 4000000 dbx_hash1.auth', 204 'setenv -e -nv -bs -rt -at -a -i 4000000:$filesize dbx']) 205 assert 'Failed to set EFI variable' not in ''.join(output) 206 output = u_boot_console.run_command_list([ 207 'efidebug boot next 1', 208 'efidebug test bootmgr']) 209 assert '\'HELLO\' failed' in ''.join(output) 210 assert 'efi_start_image() returned: 26' in ''.join(output) 211 212 def test_efi_signed_image_auth6(self, u_boot_console, efi_boot_env): 213 """ 214 Test Case 6 - using digest of signed image in database 215 """ 216 u_boot_console.restart_uboot() 217 disk_img = efi_boot_env 218 with u_boot_console.log.section('Test Case 6a'): 219 # Test Case 6a, verified by image's digest in db 220 output = u_boot_console.run_command_list([ 221 'host bind 0 %s' % disk_img, 222 'fatload host 0:1 4000000 db_hello_signed.auth', 223 'setenv -e -nv -bs -rt -at -i 4000000:$filesize db', 224 'fatload host 0:1 4000000 KEK.auth', 225 'setenv -e -nv -bs -rt -at -i 4000000:$filesize KEK', 226 'fatload host 0:1 4000000 PK.auth', 227 'setenv -e -nv -bs -rt -at -i 4000000:$filesize PK']) 228 assert 'Failed to set EFI variable' not in ''.join(output) 229 output = u_boot_console.run_command_list([ 230 'efidebug boot add 1 HELLO host 0:1 /helloworld.efi.signed ""', 231 'efidebug boot next 1', 232 'bootefi bootmgr']) 233 assert 'Hello, world!' in ''.join(output) 234 235 with u_boot_console.log.section('Test Case 6b'): 236 # Test Case 6b, rejected by TEST_db certificate in dbx 237 output = u_boot_console.run_command_list([ 238 'fatload host 0:1 4000000 dbx_db.auth', 239 'setenv -e -nv -bs -rt -at -i 4000000:$filesize dbx']) 240 assert 'Failed to set EFI variable' not in ''.join(output) 241 output = u_boot_console.run_command_list([ 242 'efidebug boot next 1', 243 'efidebug test bootmgr']) 244 assert '\'HELLO\' failed' in ''.join(output) 245 assert 'efi_start_image() returned: 26' in ''.join(output) 246 247 with u_boot_console.log.section('Test Case 6c'): 248 # Test Case 6c, rejected by image's digest in dbx 249 output = u_boot_console.run_command_list([ 250 'fatload host 0:1 4000000 db.auth', 251 'setenv -e -nv -bs -rt -at -i 4000000:$filesize db', 252 'fatload host 0:1 4000000 dbx_hello_signed.auth', 253 'setenv -e -nv -bs -rt -at -i 4000000:$filesize dbx']) 254 assert 'Failed to set EFI variable' not in ''.join(output) 255 output = u_boot_console.run_command_list([ 256 'efidebug boot next 1', 257 'efidebug test bootmgr']) 258 assert '\'HELLO\' failed' in ''.join(output) 259 assert 'efi_start_image() returned: 26' in ''.join(output) 260