├── README.md ├── classes └── extra_hddimg_populate.bbclass ├── conf └── layer.conf ├── recipes-base ├── images │ └── wrlinux-image-minimal-initramfs.bbappend └── packagegroups │ └── packagegroup-efi-secure-boot.bb ├── recipes-bsp ├── efitools │ ├── efitools-native_git.bb │ ├── efitools.inc │ ├── efitools │ │ ├── Add-static-keyword-for-IsValidVariableHeader.patch │ │ ├── Allow-to-override-tools-for-target-build.patch │ │ ├── Build-DBX-by-default.patch │ │ ├── Don-t-build-PreLoader.efi.patch │ │ ├── Fix-for-the-cross-compilation.patch │ │ ├── Fix-help2man-error.patch │ │ ├── Fix-help2man-failure.patch │ │ ├── Fix-the-wrong-dependency-for-blacklist.esl.patch │ │ ├── Kill-all-the-build-warning-caused-by-implicit-declar.patch │ │ ├── LockDown-disable-the-entrance-into-BIOS-setup-to-re-.patch │ │ ├── LockDown-enable-the-enrollment-for-DBX.patch │ │ ├── LockDown-run-system-warm-reset-after-the-key-provisi.patch │ │ ├── LockDown-show-the-error-message-with-3-sec-timeout.patch │ │ ├── Makefile-do-not-build-signed-efi-image.patch │ │ └── Reuse-xxdi.pl.patch │ └── efitools_git.bb ├── grub │ ├── grub-efi │ │ ├── 0001-pe32.h-add-header-structures-for-TE-and-DOS-executab.patch │ │ ├── 0002-shim-add-needed-data-structures.patch │ │ ├── 0003-efi-chainloader-implement-an-UEFI-Exit-service-for-s.patch │ │ ├── 0004-efi-chainloader-port-shim-to-grub.patch │ │ ├── 0005-efi-chainloader-use-shim-to-load-and-verify-an-image.patch │ │ ├── 0006-efi-chainloader-boot-the-image-using-shim.patch │ │ ├── 0007-efi-chainloader-take-care-of-unload-undershim.patch │ │ ├── Fix-32-bit-build-failures.patch │ │ ├── Grub-get-and-set-efi-variables.patch │ │ ├── boot-menu-hddimg.inc │ │ ├── boot-menu.inc │ │ ├── chainloader-Actually-find-the-relocations-correctly-.patch │ │ ├── chainloader-Don-t-check-empty-section-in-file-like-..patch │ │ ├── chainloader-handle-the-unauthenticated-image-by-shim.patch │ │ ├── efi-secure-boot.inc │ │ ├── grub-efi.cfg │ │ ├── grub-enable-serial-console-by-default.patch │ │ ├── mok2verify-support-to-verify-non-PE-file-with-PKCS-7.patch │ │ ├── password.inc │ │ └── serial-redirect-control-x-fix.patch │ └── grub-efi_2.00.bbappend ├── seloader │ └── seloader_git.bb └── shim │ ├── shim │ ├── 0001-shim-allow-to-verify-sha1-digest-for-Authenticode.patch │ ├── 0005-Fix-signing-failure-due-to-not-finding-certificate.patch │ ├── 0006-Prevent-from-removing-intermediate-.efi.patch │ ├── 0007-Use-sbsign-to-sign-MokManager-and-fallback.patch │ ├── 0008-Fix-the-world-build-failure-due-to-the-missing-rule-.patch │ ├── 0010-Makefile-do-not-sign-the-efi-file.patch │ ├── 0011-Update-verification_method-if-the-loaded-image-is-si.patch │ ├── LICENSE │ └── shimx64.efi.signed │ └── shim_git.bb ├── recipes-core └── systemd │ └── systemd_%.bbappend ├── recipes-devtools ├── libsign │ └── libsign_git.bb └── sbsigntool │ ├── sbsigntool-native_git.bb │ └── sbsigntool │ ├── Fix-for-multi-sign.patch │ ├── ccan.git.tar.bz2 │ ├── disable-man-page-creation.patch │ ├── fix-mixed-implicit-and-normal-rules.patch │ ├── image-fix-the-segment-fault-caused-by-the-uninitiali.patch │ └── sbsign-add-x-option-to-avoid-overwrite-existing-sign.patch ├── recipes-extended └── mokutil │ └── mokutil_git.bb ├── recipes-kernel └── linux │ ├── kernel-initramfs-image.bbappend │ ├── linux-windriver_%.bbappend │ ├── linux-yocto-efi-secure-boot.inc │ ├── linux-yocto-rt_%.bbappend │ └── linux-yocto_%.bbappend ├── recipes-perl └── libfile-slurp │ └── libfile-slurp-perl_9999.19.bb └── recipes-support └── efivar ├── efivar └── Remove-use-of-deprecated-readdir_r.patch └── efivar_0.24.bbappend /README.md: -------------------------------------------------------------------------------- 1 | ### EFI secure boot feature 2 | This feature consists of two widely used secure boot technologies: UEFI Secure 3 | Boot and MOK Secure Boot. 4 | 5 | - UEFI Secure Boot is the industry standard defined in the UEFI spec, allowing the 6 | images loaded by UEFI BIOS to be verified with the certificates corresponding to 7 | the trusted keys. 8 | - MOK (Machine Owner Key) Secure Boot is based on UEFI Secure Boot, adding 9 | the shim bootloader to chainloader the next stage bootloader with the integrity 10 | check using the shim-managed certificates corresponding to another set of 11 | trusted keys which may be different than the trusted keys used by UEFI Secure 12 | Boot. 13 | 14 | In addition, this feature introduces the SELoader as the second-stage bootloader 15 | and eventually chainliader to the third-stage bootloader "grub". With the 16 | extension provided by SELoader, grub configuration files, kernel (even without 17 | EFI stub support) and initrd can be authenticated. This capability is not 18 | available in the shim bootloader. 19 | 20 | Grub bootloader is enhanced to support lockdown mode. In this mode, the 21 | edit, rescue and command line are protected in order to prevent from 22 | tampering the kernel commandline or loading an unsigned boot component. Hence, 23 | this lockdown protection can effectively defeat the attempts to disable the 24 | kernel security mechanisms. The flexibility is also provided if the user 25 | authentication is enabled. The user authenticated by a password check can enter 26 | into edit and command line. 27 | 28 | Therefore, using UEFI Secure Boot, SELoader, and grub lockdown together, the 29 | boot process is completely trustworthy. 30 | 31 | A complete boot flow with this feature is: 32 | 33 | - UEFI BIOS boot manager (UEFI Secure Boot enabled) -> 34 | - shim (verified by a DB certificate) -> 35 | - SELoader (verified by a shim-managed certificate) -> 36 | - grub (verified by a shim-managed certificate) -> 37 | - grub.cfg (verified by a shim-managed certificate) 38 | - kernel (verified by a shim-managed certificate) 39 | - initramfs (verified by a shim-managed certificate) 40 | 41 | ### Quick start for the first boot 42 | - Deploy the rootfs 43 | 44 | - Boot up the target board 45 | 46 | - Enter to BIOS setup and remove the enrolled certificates 47 | * It is recommended to still turn on UEFI Secure Boot option if allowed. 48 | 49 | - Exit BIOS setup and automatically reboot 50 | 51 | - Manually launch a reboot via ctrl + alt + del again 52 | * Otherwise, a misleading error message about the verification failure 53 | will be displayed. 54 | 55 | - Automatically boot to the boot option "Automatic Certificate Provision" in 56 | grub boot menu. 57 | 58 | - (Optional) Enter into BIOS setup to turn on UEFI Secure Boot option 59 | 60 | - Boot to the system with the protection provided by UEFI and MOK Secure Boot 61 | 62 | ### Key Management 63 | Refer to meta-signing-key/README.md for the initial cognition about key 64 | management for UEFI Secure Boot. 65 | 66 | Note that the sample key and user key are the concepts in the key signing 67 | model according to the ownership and secrecy. In UEFI Secure Boot, a policy 68 | object such as PK, KEK, DB and DBX is mapped to a key managed by the key 69 | signing model. 70 | 71 | #### Sample Keys 72 | This feature, by default, use **the sample keys** to sign and verify images for 73 | the purpose of development and demonstration. **Please ensure you know what your 74 | risk is to use the sample keys in your product, because they are completely 75 | public.** 76 | 77 | The sample keys used for UEFI Secure Boot are centrally placed under 78 | meta-signing-key/files/uefi_sb_keys/. 79 | 80 | - PK.pem 81 | The X509 certificate enrolled to UEFI BIOS, used to update/delete PK/KEK. 82 | 83 | - PK.key 84 | The private key corresponding to PK.pem, used to sign the EFI signature 85 | list for PK/KEK enrollment. 86 | 87 | - KEK.pem 88 | The X509 certificate enrolled to UEFI BIOS, used to update/delete 89 | DB/DBX. 90 | 91 | - KEK.key 92 | The private key corresponding to KEK.pem, used to sign the EFI signature 93 | list for DB/DBX enrollment. 94 | 95 | - DB.pem 96 | The X509 certificate enrolled to UEFI BIOS, used to verify the images 97 | directly loaded by UEFI BIOS. 98 | 99 | - DB.key 100 | The private key corresponding to DB.pem, used to sign the images directly 101 | loaded by UEFI BIOS. 102 | 103 | - DBX 104 | This directory contains any number of X509 certificate enrolled to UEFI 105 | BIOS, used to blacklist the revoked certificates. The revoked certificates 106 | must be PEM-formatted. 107 | 108 | The sample keys used for MOK Secure Boot are centrally placed under 109 | `meta-signing-key/files/mok_sb_keys/`. 110 | 111 | - shim_cert.pem 112 | The X509 certificate embedded in shim, used to verify the images either 113 | directly or indirectly loaded by shim. 114 | 115 | - shim_cert.key 116 | The private key corresponding to shim_cert.pem, used to sign the images 117 | either directly or indirectly loaded by shim. 118 | 119 | - vendor_cert.pem 120 | Used in the same way as shim_cert.pem. In addition, vendor certificate 121 | is the switch to enable shim verification protocol, which facilitates 122 | the verification for the SELoader. 123 | 124 | - vendor_cert.key 125 | The private key corresponding to vendor_cert.pem, Same fuction as 126 | shim_cert.key. 127 | 128 | #### User Keys 129 | Refer to meta-signing-key/README.md for the details about how to generate/use 130 | the keys owned by the end user. 131 | 132 | #### Automatic Certificate Provision 133 | The certificate provision is required to enable UEFI Secure Boot. By default, 134 | the target may be provisioned with the default certificates enrolled during the 135 | manufacture. 136 | 137 | In order to use the bootloader and kernel signed by the sample or self-owned 138 | key to boot up the system, this feature provides a process of autmatic 139 | certificate provison for the convenience. Refer to the instructions listed in 140 | the section "Work Flow For The First Boot". The detailed descriptions are 141 | given below. 142 | 143 | ##### Remove the enrolled certificates in BIOS setup 144 | The LockDown.efi application is used to run the provision. However, 145 | LockDown.efi cannot be launched if UEFI Secure Boot is already enabled. In 146 | addition, the enrolled certificates may be not the ones the user hopes to use. 147 | 148 | The provisioned certificates can be removed in BIOS setup. The detailed steps 149 | may vary between the boards. Refer to BIOS manual for the details. 150 | 151 | ##### Launch the automatic provision 152 | Lockdown.efi will automatically provision UEFI Secure Boot after removing the 153 | the provisioned certificates in BIOS setup. More specifically, the PK, KEK, 154 | DB and DBX (if any) will be enrolled and begin to take affect after a reboot. 155 | 156 | ##### Turn on UEFI Secure Boot option 157 | If UEFI Secure Boot option is turned off, the user has to enter into BIOS setup 158 | after provision to manually turn on the option. 159 | 160 | If the option is already enabled when removing the enrolled certificates in 161 | BIOS setup, this step can be ignored. 162 | 163 | ##### Re-trigger automatic provision 164 | By default, the "Automatic Certificate Provision" option is hidden in boot 165 | menu for the first boot. If the user would like to clear the certificates 166 | provisioned by the "Automatic Certificate Provision" option in BIOS setup, this 167 | hidden boot option will be shown in boot menu, allowing to re-trigger it when 168 | necessary. 169 | 170 | ### Signing 171 | By default, the build system uses DB.key to sign shim, and uses vendor_cert.key 172 | to sign SELoader, grub, grub configuration file, kernel and initramfs image 173 | during the build. 174 | 175 | ### Verficiation 176 | 177 | #### UEFI Secure Boot Verification 178 | UEFI BIOS will validate the integrity of shim bootloader with a certificate in 179 | DB before running it. 180 | 181 | #### Bootloader Verification 182 | When the shim loads SELoader and SELoader loads grub, if both UEFI Secure Boot 183 | and MOK Secure Boot are already enabled, the upper bootloader uses a list of 184 | certificate to check the integrity of lower bootloader. 185 | 186 | - Blacklist check 187 | If the lower bootloader is signed with a key corresponding to a certificate 188 | within any of a policy object below, the boot failure will occur. 189 | 190 | * Vendor DBX 191 | * DBX 192 | * MokListX (MOK certificate blacklist) 193 | 194 | - Whitelist check 195 | If the lower bootloader is signed with a key corresponding to a certificate 196 | within any of a policy object below, the boot success will occur. 197 | 198 | * DB 199 | * MokList (MOK certificate whitelist) 200 | * Shim certificate (only for PE image) 201 | * Vendor certificate 202 | 203 | If the lower bootloader is not signed or signed by a key not corresponding to 204 | any policy objects mentioned above, the boot failure will occur. 205 | 206 | The benefit of these behaviors allow the end user to regulate the secure boot 207 | even without the ownership of DB on Microsoft certificated hardware. 208 | 209 | ##### SELoader Verification 210 | The SELoader is designed to authenticate the non-PE files, such as grub.cfg, 211 | kernel (without EFI stub support) and initrd, which cannot be verified by 212 | the verification protocol registered by the shim loader. 213 | 214 | In order to conveniently authenticate the PE file with gBS->LoadImage() 215 | and gBS->StartImage(), the SELoader hooks EFI Security2 Architectural 216 | Protocol and employs verification protocol provided by the shim loader to 217 | verify the PE file. If only UEFI Secure Boot is enabled, the SELoader just 218 | simplily calls gBS->LoadImage() and gBS->StartImage() to allow UEFI BIOS 219 | to verify the PE file. 220 | 221 | The SELoader publishes MOK2 verification protocol which provides a flexible 222 | interface to allow the bootloader to verify the file, file buffer or 223 | memory buffer without knowing the file format. 224 | 225 | In order to establish the chain of trust, the SELoader is required to be 226 | signed by a private key corresponding to a DB certificate, the shim 227 | certificate, the vendor certificate or a MOK certificate. The specific 228 | key is determined by the secure boot scheme you will use. 229 | 230 | See more details about the SELoader in its README file. 231 | 232 | #### Grub Configuration File Verification 233 | Grub can call the MOK2 verification protocol registered by the SELoader 234 | to validate the integrity of grub configuration file before parsing it. 235 | 236 | This protection prevents from tampering the grub configuration file from 237 | disabling certains kernel security mechanism such as selinux, IMA and so on. 238 | 239 | #### Kernel Verification 240 | When SELoader loads the kernel image with the linux command, if both UEFI 241 | Secure Boot and MOK Secure Boot are already enabled, grub will call the 242 | verification protocol installed by SELoader to validate the kernel image. 243 | 244 | Alternately, if grub loads the kernel image with the chainloader command, 245 | if both UEFI Secure Boot and MOK Secure Boot are already enabled, grub will 246 | call the verification protocol installed by shim to validate the kernel image. 247 | 248 | By default, the kernel image is signed by vendor certificate and then signed 249 | again to generate the .p7b signature file. 250 | 251 | #### Initramfs Verification 252 | When SELoader loads the kernel image with the initrd command, if both UEFI 253 | Secure Boot and MOK Secure Boot are already enabled, grub will call the 254 | verification protocol installed by SELoader to validate the initramfs image. 255 | 256 | #### Verification Failure 257 | Either situation will cause a failure of verification. 258 | - A boot component is not signed. 259 | - A boot component is signed by a key which doesn't correspond to any 260 | certificate in whitelists such as DB and shim-managed certificates. 261 | - A boot component is signed by a key which corresponds to a certificate in 262 | blacklist such as DBX and shim-managed certificates in MOKX. 263 | 264 | Each boot component may have different verification failure phenomenon. 265 | - If SELoader fails signature check, UEFI BIOS boot manager will print an error 266 | message about the image authentication failure. 267 | - If grub fails signature check, an image authentication failure message is 268 | printed and the system hangs. 269 | - If a grub configuration file fails the signature check, an authentication 270 | failure message is printed and grub hangs. 271 | - If kernel image fails signature check, grub returns back to the boot menu. 272 | - If initrd fails signature check, grub returns back to the boot menu. 273 | 274 | ### MOK Secure Boot and the shim bootloader 275 | MOK (Machine Owner Key) Secure Boot is based on UEFI Secure Boot, adding 276 | the shim bootloader to chainloader the second-stage bootloader 277 | "SELoader" and eventually chainliader to the third-stage bootloader "grub". 278 | 279 | [ Quoting: https://github.com/rhinstaller/shim ] 280 | shim is a trivial EFI application that, when run, attempts to open and 281 | execute another application. It will initially attempt to do this via the 282 | standard EFI LoadImage() and StartImage() calls. If these fail (because secure 283 | boot is enabled and the binary is not signed with an appropriate key, for 284 | instance) it will then validate the binary against a built-in certificate. If 285 | this succeeds and if the binary or signing key are not blacklisted then shim 286 | will relocate and execute the binary. 287 | 288 | shim will also install a protocol which permits the second-stage bootloader 289 | to perform similar binary validation. This protocol has a GUID as described 290 | in the shim.h header file and provides a single entry point. On 64-bit systems 291 | this entry point expects to be called with SysV ABI rather than MSABI, and 292 | so calls to it should not be wrapped. 293 | [ End of Quote ] 294 | 295 | In most cases, the hardware coming out of the factory is already provisioned 296 | with a default certificate used to verify the bootloader and issued by 297 | Microsoft Corporation UEFI CA 2011. This kind of hardware is so-called 298 | Microsoft certificated hardware. 299 | 300 | Obviously, this requirement needs a bootloader loaded by BIOS must be signed 301 | by Microsoft. Microsoft provides the signing service (not free), but only 302 | accept shim bootloader for Linux world. Refer to [Microsoft's signing policy](http://blogs.msdn.com/b/windows_hardware_certification/archive/2013/12/03/microsoft-uefi-ca-signing-policy-updates.aspx). 303 | 304 | It is allowed to remove all default certificates and use the self-owned keys to 305 | provision UEFI Secure Boot, but this is not practical for ODM/OEM devices 306 | during the manufacture phrase. See the section "Out-of-box Experience". 307 | 308 | For a good user experience, shim + SELoader + grub is an excellent combination 309 | to handle Microsoft certificated hardware. With this model, SELoader and grub 310 | are signed by a shim-managed certificate without being subject to the limit from 311 | Microsoft's signing policy, and the manual provision is thus unnecessary. 312 | 313 | #### mokutil and MOK Manager 314 | mokutil is a tool to import or delete the machines owner keys stored in the 315 | database of shim. mokutil creates the requests and MOK manager will be 316 | automatically launched by shim as long as it detects the pending requests. 317 | The physical present user will be prompted to run the operations corresponding 318 | to the requests. Note the operation is required to be authenticated by MOK 319 | management password set by mokutil. 320 | 321 | Refer to mokutil man page for the detailed usages. 322 | 323 | ##### MOK Management Password 324 | MOK management password is the authentication information to allow MOK manager 325 | to grant the request regarding of MOK management. To set the password, run 326 | mokutil with the option --password. In addition, there are 4 input methods to 327 | provide the password. By default, mokutil prompts the user to input the 328 | password and then wraps the password to sha256 password hash. For other 3 329 | methods, refer to the uses of option --hash-file, --root-pw and --simple-hash. 330 | 331 | ##### Enroll the MOK certificate 332 | Here is an example showing how to enroll a DER formatted X509 certificate to 333 | the database of shim. 334 | ``` 335 | # mokutil --import 336 | ``` 337 | where `` is the MOK certificate corresponding to the private key used 338 | to sign either grub or kernel. 339 | 340 | To convert a PEM, for exmaple, the shim_cert.pem, to a DER formatted X509 341 | certificate, type the command: 342 | ``` 343 | $ openssl x509 -in shim_cert.pem -inform PEM -out shim_cert.cer -outform DER 344 | ``` 345 | 346 | ##### List the enrollment requests 347 | The several enrollment requests can be submitted before system reboot. Run the 348 | following command to check all enrollment requests. 349 | ``` 350 | # mokutil --list-new 351 | ``` 352 | 353 | ##### Revoke the enrollment requests 354 | Note the revocation operation will remove all enrollment requests. 355 | ``` 356 | # mokutil --revoke-import 357 | ``` 358 | 359 | ##### Test the MOK certificate 360 | If you cannot confirm whether a certificate has been enrolled or not, type the 361 | following command for a check: 362 | ``` 363 | # mokutil --test-key 364 | ``` 365 | 366 | ##### Delete the MOK certificate 367 | Removing an useless MOK certificate is also supported. 368 | ``` 369 | # mokutil --delete 370 | ``` 371 | Refer to the options --list-delete and --revoke-delete to list and revoke the 372 | MOKs. 373 | 374 | ##### Reset MOK certificates 375 | This request will clear all enrolled MOK certificates. 376 | ``` 377 | # mokutil --reset 378 | ``` 379 | 380 | ##### Disable/Enable MOK Secure Boot 381 | MOK Secure Boot can be enabled or disabled regardless of the setting of UEFI 382 | Secure Boot. 383 | ``` 384 | # mokutil --disable-validation // disable MOK Secure Boot 385 | # mokutil --enable-validation // enable MOK Secure Boot 386 | ``` 387 | 388 | Note that MOK Secure Boot is based on UEFI Secure Boot. If UEFI Secure Boot 389 | is disabled, MOK Secure Boot will be automatically inactive. Type the 390 | following command to check the status of UEFI Secure Boot. 391 | ``` 392 | # mokutil --sb-state 393 | ``` 394 | 395 | ##### Other options 396 | Refer to the options --import-hash and --delete-hash to manage hash-based 397 | signature. The options --pk, --kek, --db and --dbx are useful to check 398 | the content of the policy objects used in UEFI Secure Boot. 399 | 400 | ##### Manage blacklist 401 | All above mentioned are talking MOK which is acting as whitelist to 402 | authenticate the verified image to launch. Actually, there is a contrary 403 | policy object called MOKX, acting as blacklist to deny the untrusted 404 | image to launch. Also, MOKX as blacklist is handled by shim prior to MOK 405 | as whitelist. 406 | 407 | For the management of blacklist, add the option --mokx with the following 408 | options to change the operation target from MOK to the following options. 409 | 410 | --list-enrolled 411 | --test-key 412 | --list-new 413 | --list-delete 414 | --import 415 | --delete 416 | --import-hash 417 | --delete-hash 418 | --reset 419 | --revoke-import 420 | --revoke-delete 421 | 422 | ##### Handle MOK Secure Boot Failure with MOK Manager 423 | If either grub or SELoader is not signed or signed with an unauthorized 424 | certificate, the shim will prompt the end user a UI called MOK manager to 425 | guide the user to enroll the certificate or hash of the image. 426 | 427 | The policy of the selection between digest and certificate for next step is 428 | decided by whether the unauthorized grub or SELoader is signed or not. 429 | 430 | If the grub or SELoader is not signed at all, you have to always select 431 | the calculation of the digest based on the file. Note that once grub or SELoader 432 | is updated and its digest is changed, you have to relaunch the MOK manager 433 | to enroll the new digests. 434 | 435 | If the grub or SELoader is signed by an unauthorized certificate, enrolling the 436 | signing certificate is the preferred way. Copy the certificate to the boot 437 | drive and then select the certificate in MOK manager. Note that the 438 | certificate for the selection must be **DER formatted**. 439 | 440 | If doing so, the unauthorized grub or SELoader will be verified successfully 441 | after exiting MOK Manager. 442 | 443 | ### Grub Lockdown 444 | In order to prevent from tampering the kernel command line or loading an 445 | unsigned boot component, grub is locked if UEFI Secure Boot is enabled. In this 446 | situation, the end user cannot enter into command or edit line via pressing 'c' 447 | and 'e'. 448 | 449 | If the user authentication is enabled, the access to command or edit line is 450 | protected by a password. In this situation, grub is unlockable. 451 | 452 | Rescue mode is always disabled as long as UEFI Secure Boot is enabled. 453 | 454 | ### Work Flow For The First Boot 455 | - Build a project with this template 456 | 457 | - Deploy the rootfs 458 | 459 | - Boot up the target board 460 | 461 | - Enter to BIOS setup and remove the enrolled certificates 462 | * It is recommended to still turn on UEFI Secure Boot option if allowed. 463 | 464 | - Launch a reboot via ctrl + alt + del 465 | * Otherwise, a misleading error message about the verification failure 466 | will be displayed. 467 | 468 | - Automatically boot to "Automatic Certificate Provision" 469 | 470 | - (Optional) Enter into BIOS setup to turn on UEFI Secure Boot option 471 | 472 | - Boot to the system with the protection provided by UEFI Secure Boot 473 | 474 | ### Known Issues 475 | - The 32-bit MOK Secure Boot is not validated. In other words, loading 32-bit 476 | shim, MOK manager, grub and kernel is not supported. 477 | 478 | ### Reference 479 | [OpenEmbedded layer for EFI secure boot features](https://github.com/jiazhang0/meta-efi-secure-boot) 480 | -------------------------------------------------------------------------------- /classes/extra_hddimg_populate.bbclass: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2017 Wind River Systems, Inc. 3 | # 4 | 5 | inherit grub-efi 6 | # Override the efi_hddimg_populate() from grub-efi.bbclass for copying 7 | # signed efi/kernel images and their *.p7b files to hddimg: 8 | # ${IMAGE_ROOTFS}/boot/efi/EFI/ -> hddimg/ 9 | # ${DEPLOY_DIR_IMAGE}/bzImage -> hddimg/ 10 | # ${DEPLOY_DIR_IMAGE}/bzImage.p7b -> hddimg/ 11 | # ${DEPLOY_DIR_IMAGE}/*initramfs* -> hddimg/initrd 12 | 13 | efi_hddimg_populate() { 14 | DEST=$1 15 | 16 | install -d ${DEST}${EFIDIR} 17 | 18 | bbnote "Trying to install ${IMAGE_ROOTFS}/boot/efi${EFIDIR} as ${DEST}/${EFIDIR}" 19 | if [ -d ${IMAGE_ROOTFS}/boot/efi${EFIDIR} ]; then 20 | cp -af ${IMAGE_ROOTFS}/boot/efi${EFIDIR}/* ${DEST}${EFIDIR} 21 | else 22 | bbwarn "${IMAGE_ROOTFS}/boot/efi${EFIDIR} doesn't exist" 23 | fi 24 | 25 | bbnote "Trying to install ${DEPLOY_DIR_IMAGE}/${VM_DEFAULT_KERNEL} as ${DEST}/${VM_DEFAULT_KERNEL}" 26 | # cleanup vmlinuz that deployed by OE 27 | rm -f ${DEST}/vmlinuz 28 | 29 | if [ -e ${DEPLOY_DIR_IMAGE}/${VM_DEFAULT_KERNEL} ]; then 30 | install -m 0644 ${DEPLOY_DIR_IMAGE}/${VM_DEFAULT_KERNEL} ${DEST}/${VM_DEFAULT_KERNEL} 31 | install -m 0644 ${DEPLOY_DIR_IMAGE}/${VM_DEFAULT_KERNEL}.p7b ${DEST}/${VM_DEFAULT_KERNEL}.p7b 32 | 33 | # create a backup kernel for recovery boot 34 | install -m 0644 ${DEPLOY_DIR_IMAGE}/${VM_DEFAULT_KERNEL} ${DEST}/${VM_DEFAULT_KERNEL}_bakup 35 | install -m 0644 ${DEPLOY_DIR_IMAGE}/${VM_DEFAULT_KERNEL}.p7b ${DEST}/${VM_DEFAULT_KERNEL}_bakup.p7b 36 | else 37 | bbwarn "${DEPLOY_DIR_IMAGE}/${VM_DEFAULT_KERNEL} doesn't exist" 38 | fi 39 | 40 | # allow to copy ${INITRD_IMAGE_LIVE} as initrd if ${INITRAMFS_IMAGE} was not built 41 | if [ -z "${INITRAMFS_IMAGE}" ]; then 42 | INITRAMFS_IMAGE=${INITRD_IMAGE_LIVE} 43 | fi 44 | 45 | if [ -n "${INITRAMFS_IMAGE}" ]; then 46 | initramfs=${INITRAMFS_IMAGE}-${MACHINE}.cpio.gz 47 | bbnote "Trying to install ${DEPLOY_DIR_IMAGE}/${initramfs} as ${DEST}/initrd" 48 | if [ -e ${DEPLOY_DIR_IMAGE}/${initramfs} ]; then 49 | install -m 0644 ${DEPLOY_DIR_IMAGE}/${initramfs} ${DEST}/initrd 50 | install -m 0644 ${DEPLOY_DIR_IMAGE}/${initramfs}.p7b ${DEST}/initrd.p7b 51 | 52 | # create a backup initrd for recovery boot 53 | install -m 0644 ${DEPLOY_DIR_IMAGE}/${initramfs} ${DEST}/initrd_bakup 54 | install -m 0644 ${DEPLOY_DIR_IMAGE}/${initramfs}.p7b ${DEST}/initrd_bakup.p7b 55 | else 56 | bbwarn "${DEPLOY_DIR_IMAGE}/${initramfs} doesn't exist" 57 | fi 58 | fi 59 | 60 | # copy custom boot menu for hddimg: 61 | # - initrd is always needed to mount rootfs from /dev/ram0 (rootfs.img) 62 | if [ -e ${DEPLOY_DIR_IMAGE}/boot-menu-hddimg.inc ]; then 63 | install -m 0644 ${DEPLOY_DIR_IMAGE}/boot-menu-hddimg.inc ${DEST}${EFIDIR}/boot-menu.inc 64 | install -m 0644 ${DEPLOY_DIR_IMAGE}/boot-menu-hddimg.inc.p7b ${DEST}${EFIDIR}/boot-menu.inc.p7b 65 | fi 66 | } 67 | -------------------------------------------------------------------------------- /conf/layer.conf: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2017 Wind River Systems, Inc. 3 | # 4 | 5 | # We have a conf and classes directory, add to BBPATH 6 | BBPATH =. "${LAYERDIR}:" 7 | 8 | # We have a packages directory, add to BBFILES 9 | BBFILES += "${LAYERDIR}/recipes-*/*/*.bb \ 10 | ${LAYERDIR}/recipes-*/*/*.bbappend" 11 | 12 | BBFILE_COLLECTIONS += "meta-efi-secure-boot" 13 | BBFILE_PATTERN_meta-efi-secure-boot = "^${LAYERDIR}/" 14 | BBFILE_PRIORITY_meta-efi-secure-boot = "7" 15 | 16 | # This should only be incremented on significant changes that will 17 | # cause compatibility issues with other layers 18 | LAYERVERSION_meta-efi-secure-boot = "1" 19 | 20 | LAYERDEPENDS_meta-efi-secure-boot = "\ 21 | core \ 22 | openembedded-layer \ 23 | meta-signing-key \ 24 | " 25 | -------------------------------------------------------------------------------- /recipes-base/images/wrlinux-image-minimal-initramfs.bbappend: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2017 Wind River Systems, Inc. 3 | # 4 | 5 | inherit user-key-store deploy 6 | 7 | fakeroot python do_sign() { 8 | if d.expand('${UEFI_SB}') != '1': 9 | return 10 | 11 | initramfs_symlink = d.expand('wrlinux-image-minimal-initramfs-${MACHINE}.cpio.gz') 12 | initramfs = os.path.basename(os.path.realpath(initramfs_symlink)) 13 | 14 | if os.path.exists(initramfs): 15 | uks_sel_sign(initramfs, d) 16 | 17 | import shutil 18 | shutil.copyfile(initramfs + '.p7b', initramfs_symlink + '.p7b') 19 | } 20 | 21 | do_sign[dirs] = "${DEPLOYDIR}-image-complete" 22 | addtask sign after do_image_cpio before do_image_complete 23 | -------------------------------------------------------------------------------- /recipes-base/packagegroups/packagegroup-efi-secure-boot.bb: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2016-2017 Wind River Systems Inc. 3 | # 4 | 5 | DESCRIPTION = "EFI Secure Boot packages for secure-environment." 6 | LICENSE = "MIT" 7 | LIC_FILES_CHKSUM = "file://${COREBASE}/LICENSE;md5=4d92cd373abda3937c2bc47fbc49d690 \ 8 | file://${COREBASE}/meta/COPYING.MIT;md5=3da9cfbcb788c80a0384361b4de20420" 9 | 10 | S = "${WORKDIR}" 11 | 12 | ALLOW_EMPTY_${PN} = "1" 13 | 14 | pkgs = " \ 15 | grub-efi \ 16 | efitools \ 17 | efibootmgr \ 18 | mokutil \ 19 | seloader \ 20 | shim \ 21 | " 22 | 23 | RDEPENDS_${PN}_x86 = "${pkgs}" 24 | RDEPENDS_${PN}_x86-64 = "${pkgs}" 25 | 26 | kmods = " \ 27 | kernel-module-efivarfs \ 28 | kernel-module-efivars \ 29 | " 30 | 31 | RRECOMMENDS_${PN}_x86 += "${kmods}" 32 | RRECOMMENDS_${PN}_x86-64 += "${kmods}" 33 | 34 | # Check and deploy keys to ${DEPLOY_DIR_IMAGE} 35 | inherit user-key-store 36 | do_install[postfuncs] += "check_deploy_keys " 37 | -------------------------------------------------------------------------------- /recipes-bsp/efitools/efitools-native_git.bb: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2016 Wind River Systems, Inc. 3 | # 4 | 5 | require efitools.inc 6 | 7 | inherit native 8 | 9 | DEPENDS_append = " gnu-efi-native" 10 | 11 | EXTRA_OEMAKE_append = " \ 12 | INCDIR_PREFIX='${STAGING_DIR_NATIVE}' \ 13 | CRTPATH_PREFIX='${STAGING_DIR_NATIVE}' \ 14 | EXTRA_LDFLAGS='-Wl,-rpath,${libdir}' \ 15 | " 16 | -------------------------------------------------------------------------------- /recipes-bsp/efitools/efitools.inc: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2016 Wind River Systems, Inc. 3 | # 4 | 5 | SUMMARY = "Tools to support reading and manipulating the UEFI signature database" 6 | DESCRIPTION = "\ 7 | From the EFI Tools package in the Linux user-space, it's now possible \ 8 | to read and manipulate the UEFI signatures database via the new \ 9 | efi-readvar and efi-updatevar commands. Aside from needing efitools \ 10 | 1.4, the EFIVARFS file-system is also needed, which was only introduced \ 11 | in the Linux 3.8 kernel. \ 12 | " 13 | 14 | LICENSE = "GPLv2" 15 | LIC_FILES_CHKSUM = "file://COPYING;md5=e28f66b16cb46be47b20a4cdfe6e99a1" 16 | 17 | SRC_URI = " \ 18 | git://git.kernel.org/pub/scm/linux/kernel/git/jejb/efitools.git \ 19 | file://Fix-for-the-cross-compilation.patch \ 20 | file://Kill-all-the-build-warning-caused-by-implicit-declar.patch \ 21 | file://Fix-the-wrong-dependency-for-blacklist.esl.patch \ 22 | file://LockDown-run-system-warm-reset-after-the-key-provisi.patch \ 23 | file://Allow-to-override-tools-for-target-build.patch \ 24 | file://Fix-help2man-failure.patch \ 25 | file://Don-t-build-PreLoader.efi.patch \ 26 | file://Reuse-xxdi.pl.patch \ 27 | file://Add-static-keyword-for-IsValidVariableHeader.patch \ 28 | " 29 | 30 | SRCREV = "0649468475d20d8ca5634433c4912467cef3ce93" 31 | PV = "1.7.0+git${SRCPV}" 32 | 33 | PARALLEL_MAKE = "" 34 | 35 | inherit perlnative 36 | 37 | DEPENDS_append += "\ 38 | help2man-native openssl-native sbsigntool-native \ 39 | libfile-slurp-perl-native \ 40 | " 41 | 42 | S = "${WORKDIR}/git" 43 | 44 | EXTRA_OEMAKE = " \ 45 | HELP2MAN='${STAGING_BINDIR_NATIVE}/help2man' \ 46 | OPENSSL='${STAGING_BINDIR_NATIVE}/openssl' \ 47 | SBSIGN='${STAGING_BINDIR_NATIVE}/sbsign' \ 48 | OPENSSL_LIB='${STAGING_LIBDIR}' \ 49 | NM='${NM}' AR='${AR}' \ 50 | " 51 | EXTRA_OEMAKE_append_x86 += " ARCH=ia32" 52 | EXTRA_OEMAKE_append_x86-64 += " ARCH=x86_64" 53 | 54 | # LDFLAGS is used by LD not CC, so remove '-Wl,' 55 | LDFLAGS := "${@oe_filter_out('-Wl,', '${LDFLAGS}', d)}" 56 | BUILD_LDFLAGS := "${@oe_filter_out('-Wl,', '${BUILD_LDFLAGS}', d)}" 57 | 58 | do_compile_prepend() { 59 | sed -i -e "1s:#!.*:#!/usr/bin/env nativeperl:" xxdi.pl 60 | } 61 | 62 | EFI_BOOT_PATH = "/boot/efi/EFI/BOOT" 63 | FILES_${PN} += "${EFI_BOOT_PATH}" 64 | 65 | do_install() { 66 | oe_runmake install DESTDIR='${D}${base_prefix}' 67 | } 68 | -------------------------------------------------------------------------------- /recipes-bsp/efitools/efitools/Add-static-keyword-for-IsValidVariableHeader.patch: -------------------------------------------------------------------------------- 1 | From 960a5fc7c58c875827797b6f4afed2684acc2cde Mon Sep 17 00:00:00 2001 2 | From: Lans Zhang 3 | Date: Sun, 12 Jun 2016 13:45:54 +0800 4 | Subject: [PATCH] Add static keyword for IsValidVariableHeader() 5 | 6 | Upstream-Status: Pending 7 | 8 | GCC does not inline any functions when not optimizing (-O0 specified) unless 9 | you specify "always_inline" attribute for the function. 10 | 11 | By default, GCC complies with C89 standard for c code, which means 12 | "inline" equals to "extern inline" and thus the definition is used only for 13 | inlining with the assembly code actually generated. 14 | 15 | Therefore, "static inline" is used for both purposes. If -O0 is specified, 16 | GCC will generate the assembly code as long as the function is referred. 17 | 18 | Signed-off-by: Lans Zhang 19 | --- 20 | include/variableformat.h | 2 +- 21 | 1 files changed, 1 insertions(+), 1 deletions(-) 22 | 23 | diff --git a/include/variableformat.h b/include/variableformat.h 24 | index 32cde05..45d0ebb 100644 25 | --- a/include/variableformat.h 26 | +++ b/include/variableformat.h 27 | @@ -109,7 +109,7 @@ typedef struct { 28 | 29 | #pragma pack() 30 | 31 | -inline BOOLEAN 32 | +static inline BOOLEAN 33 | IsValidVariableHeader (VARIABLE_HEADER *vh) { 34 | if (vh == NULL || vh->StartId != VARIABLE_DATA) 35 | return FALSE; 36 | -- 37 | 1.7.1 38 | 39 | -------------------------------------------------------------------------------- /recipes-bsp/efitools/efitools/Allow-to-override-tools-for-target-build.patch: -------------------------------------------------------------------------------- 1 | From 1613bae3a9760b3cdcbf8f43e750c475d69ad8bb Mon Sep 17 00:00:00 2001 2 | From: Lans Zhang 3 | Date: Wed, 23 Mar 2016 19:05:29 +0800 4 | Subject: [PATCH] Allow to override tools for target build 5 | 6 | Upstream-Status: Pending 7 | 8 | These tools should use the ones from native build. 9 | 10 | Signed-off-by: Lans Zhang 11 | --- 12 | Make.rules | 22 +++++++++++++--------- 13 | Makefile | 4 ++-- 14 | 2 files changed, 15 insertions(+), 11 deletions(-) 15 | 16 | diff --git a/Make.rules b/Make.rules 17 | index 5e8cb82..4aa7650 100644 18 | --- a/Make.rules 19 | +++ b/Make.rules 20 | @@ -34,6 +34,10 @@ AR = ar 21 | OPENSSL = openssl 22 | SBSIGN = sbsign 23 | XXD = xxd 24 | +SIGN_EFI_SIG_LIST ?= ./sign-efi-sig-list 25 | +CERT_TO_EFI_SIG_LIST ?= ./cert-to-efi-sig-list 26 | +CERT_TO_EFI_HASH_LIST ?= ./cert-to-efi-hash-list 27 | +HASH_TO_EFI_SIG_LIST ?= ./hash-to-efi-sig-list 28 | MYGUID = 11111111-2222-3333-4444-123456789abc 29 | INSTALL = install 30 | BINDIR = $(DESTDIR)/usr/bin 31 | @@ -75,34 +79,34 @@ endif 32 | $(XXD) -i $< > $@ 33 | 34 | %.hash: %.efi hash-to-efi-sig-list 35 | - ./hash-to-efi-sig-list $< $@ 36 | + $(HASH_TO_EFI_SIG_LIST) $< $@ 37 | 38 | %-blacklist.esl: %.crt cert-to-efi-sig-list 39 | - ./cert-to-efi-sig-list $< $@ 40 | + $(CERT_TO_EFI_SIG_LIST) $< $@ 41 | 42 | %-hash-blacklist.esl: %.crt cert-to-efi-hash-list 43 | - ./cert-to-efi-hash-list $< $@ 44 | + $(CERT_TO_EFI_HASH_LIST) $< $@ 45 | 46 | %.esl: %.crt cert-to-efi-sig-list 47 | - ./cert-to-efi-sig-list -g $(MYGUID) $< $@ 48 | + $(CERT_TO_EFI_SIG_LIST) -g $(MYGUID) $< $@ 49 | 50 | getcert = $(shell if [ "$(1)" = "PK" -o "$(1)" = "KEK" ]; then echo "-c PK.crt -k PK.key"; else echo "-c KEK.crt -k KEK.key"; fi) 51 | getvar = $(shell if [ "$(1)" = "PK" -o "$(1)" = "KEK" ]; then echo $(1); else echo db; fi) 52 | 53 | %.auth: %.esl PK.crt KEK.crt sign-efi-sig-list 54 | - ./sign-efi-sig-list $(call getcert,$*) $(call getvar,$*) $< $@ 55 | + $(SIGN_EFI_SIG_LIST) $(call getcert,$*) $(call getvar,$*) $< $@ 56 | 57 | %-update.auth: %.esl PK.crt KEK.crt sign-efi-sig-list 58 | - ./sign-efi-sig-list -a $(call getcert,$*) $(call getvar,$*) $< $@ 59 | + $(SIGN_EFI_SIG_LIST) -a $(call getcert,$*) $(call getvar,$*) $< $@ 60 | 61 | %-pkupdate.auth: %.esl PK.crt sign-efi-sig-list 62 | - ./sign-efi-sig-list -a -c PK.crt -k PK.key $(call getvar,$*) $< $@ 63 | + $(SIGN_EFI_SIG_LIST) -a -c PK.crt -k PK.key $(call getvar,$*) $< $@ 64 | 65 | %-blacklist.auth: %-blacklist.esl KEK.crt sign-efi-sig-list 66 | - ./sign-efi-sig-list -a -c KEK.crt -k KEK.key dbx $< $@ 67 | + $(SIGN_EFI_SIG_LIST) -a -c KEK.crt -k KEK.key dbx $< $@ 68 | 69 | %-pkblacklist.auth: %-blacklist.esl PK.crt sign-efi-sig-list 70 | - ./sign-efi-sig-list -a -c PK.crt -k PK.key dbx $< $@ 71 | + $(SIGN_EFI_SIG_LIST) -a -c PK.crt -k PK.key dbx $< $@ 72 | 73 | %.o: %.c 74 | $(CC) $(INCDIR) $(cflags) $(cppflags) -c $< -o $@ 75 | diff --git a/Makefile b/Makefile 76 | index 15fc944..c4e0081 100644 77 | --- a/Makefile 78 | +++ b/Makefile 79 | @@ -66,10 +66,10 @@ noPK.esl: 80 | > noPK.esl 81 | 82 | noPK.auth: noPK.esl PK.crt sign-efi-sig-list 83 | - ./sign-efi-sig-list -t "$(shell date --date='1 second' +'%Y-%m-%d %H:%M:%S')" -c PK.crt -k PK.key PK $< $@ 84 | + $(SIGN_EFI_SIG_LIST) -t "$(shell date --date='1 second' +'%Y-%m-%d %H:%M:%S')" -c PK.crt -k PK.key PK $< $@ 85 | 86 | ms-%.esl: ms-%.crt cert-to-efi-sig-list 87 | - ./cert-to-efi-sig-list -g $(MSGUID) $< $@ 88 | + $(CERT_TO_EFI_SIG_LIST) -g $(MSGUID) $< $@ 89 | 90 | hashlist.h: HashTool.hash 91 | cat $^ > /tmp/tmp.hash 92 | -- 93 | 1.9.1 94 | 95 | -------------------------------------------------------------------------------- /recipes-bsp/efitools/efitools/Build-DBX-by-default.patch: -------------------------------------------------------------------------------- 1 | From e909a2d4777a6fd2644ff89361539db141c0a67f Mon Sep 17 00:00:00 2001 2 | From: Lans Zhang 3 | Date: Sat, 28 Jan 2017 13:42:28 +0800 4 | Subject: [PATCH] Build DBX by default 5 | 6 | Signed-off-by: Lans Zhang 7 | --- 8 | Makefile | 6 +++--- 9 | 1 file changed, 3 insertions(+), 3 deletions(-) 10 | 11 | diff --git a/Makefile b/Makefile 12 | index a1fc538..7f767c8 100644 13 | --- a/Makefile 14 | +++ b/Makefile 15 | @@ -26,7 +26,7 @@ include Make.rules 16 | 17 | EFISIGNED = $(patsubst %.efi,%-signed.efi,$(EFIFILES)) 18 | 19 | -all: $(EFIFILES) $(BINARIES) $(MANPAGES) noPK.auth $(KEYAUTH) \ 20 | +all: $(EFIFILES) $(BINARIES) $(MANPAGES) noPK.auth $(KEYAUTH) DBX.auth \ 21 | $(KEYUPDATEAUTH) $(KEYBLACKLISTAUTH) $(KEYHASHBLACKLISTAUTH) 22 | 23 | 24 | @@ -49,7 +49,7 @@ lib/asn1/libasn1.a lib/asn1/libasn1-efi.a: FORCE 25 | 26 | .SUFFIXES: .crt 27 | 28 | -.KEEP: PK.crt KEK.crt DB.crt PK.key KEK.key DB.key PK.esl DB.esl KEK.esl \ 29 | +.KEEP: PK.crt KEK.crt DB.crt DBX.crt PK.key KEK.key DB.key PK.esl DB.esl KEK.esl DBX.esl \ 30 | $(EFIFILES) 31 | 32 | LockDown.o: PK.h KEK.h DB.h DBX.h 33 | @@ -116,7 +116,7 @@ flash-var: flash-var.o lib/lib.a 34 | $(CC) $(ARCH3264) -o $@ $< lib/lib.a 35 | 36 | clean: 37 | - rm -f PK.* KEK.* DB.* $(EFIFILES) $(EFISIGNED) $(BINARIES) *.o *.so 38 | + rm -f PK.* KEK.* DB.* DBX.* $(EFIFILES) $(EFISIGNED) $(BINARIES) *.o *.so 39 | rm -f noPK.* 40 | rm -f doc/*.1 41 | $(MAKE) -C lib clean 42 | -- 43 | 2.7.4 44 | 45 | -------------------------------------------------------------------------------- /recipes-bsp/efitools/efitools/Don-t-build-PreLoader.efi.patch: -------------------------------------------------------------------------------- 1 | From 95e167f432f1a6d8c96aeca73871122806007c9f Mon Sep 17 00:00:00 2001 2 | From: Lans Zhang 3 | Date: Thu, 28 Apr 2016 11:21:33 +0800 4 | Subject: [PATCH] Don't build PreLoader.efi 5 | 6 | Upstream-Status: Pending 7 | 8 | The upstream has an obvious build failure: 9 | | PreLoader.c:45:2: error: too few arguments to function 'security_policy_install' 10 | | status = security_policy_install(); 11 | | ^ 12 | | In file included from PreLoader.c:14:0: 13 | | /buildarea3/jzhang0/projects/wrl8/intel-x86-64-gwp-scp/bitbake_build/tmp/work/x86_64-linux/efitools-native/1.7.0+gitAUTOINC+20a8fdc4ec-r0/git/include/security_policy.h:4:1: note: declared here 14 | | security_policy_install(BOOLEAN (*override)(void), POLICY_FUNCTION allow, POLICY_FUNCTION deny); 15 | | ^ 16 | 17 | We are waiting for the upstream fix and remove this workaround in next 18 | refresh. 19 | 20 | Signed-off-by: Lans Zhang 21 | --- 22 | Makefile | 2 +- 23 | 1 file changed, 1 insertion(+), 1 deletion(-) 24 | 25 | diff --git a/Makefile b/Makefile 26 | index b3bb73a..da363a6 100644 27 | --- a/Makefile 28 | +++ b/Makefile 29 | @@ -5,7 +5,7 @@ BINARIES = cert-to-efi-sig-list sig-list-to-certs sign-efi-sig-list \ 30 | flash-var 31 | 32 | ifeq ($(ARCH),x86_64) 33 | -EFIFILES += PreLoader.efi 34 | +#EFIFILES += PreLoader.efi 35 | endif 36 | 37 | MSGUID = 77FA9ABD-0359-4D32-BD60-28F4E78F784B 38 | -- 39 | 1.9.1 40 | 41 | -------------------------------------------------------------------------------- /recipes-bsp/efitools/efitools/Fix-for-the-cross-compilation.patch: -------------------------------------------------------------------------------- 1 | From ab2eb06c1271e46e07add5a0b0a444353d45e055 Mon Sep 17 00:00:00 2001 2 | From: Lans Zhang 3 | Date: Tue, 15 Mar 2016 21:28:33 +0800 4 | Subject: [PATCH] Fix for the cross compilation 5 | 6 | Upstream-Status: Pending 7 | 8 | Signed-off-by: Lans Zhang 9 | --- 10 | Make.rules | 52 +++++++++++++++++++++++++++++----------------------- 11 | Makefile | 14 +++++++------- 12 | 2 files changed, 36 insertions(+), 30 deletions(-) 13 | 14 | diff --git a/Make.rules b/Make.rules 15 | index 88d5481..7e89332 100644 16 | --- a/Make.rules 17 | +++ b/Make.rules 18 | @@ -13,21 +13,27 @@ ARCH3264 = 19 | else 20 | $(error unknown architecture $(ARCH)) 21 | endif 22 | -INCDIR = -I$(TOPDIR)include/ -I/usr/include/efi -I/usr/include/efi/$(ARCH) -I/usr/include/efi/protocol 23 | -CPPFLAGS = -DCONFIG_$(ARCH) 24 | -CFLAGS = -O2 $(ARCH3264) -fpic -Wall -fshort-wchar -fno-strict-aliasing -fno-merge-constants -fno-stack-protector -ffreestanding -fno-stack-check 25 | -LDFLAGS = -nostdlib 26 | +INCDIR = -I$(TOPDIR)include/ -I$(INCDIR_PREFIX)/usr/include/efi -I$(INCDIR_PREFIX)/usr/include/efi/$(ARCH) -I$(INCDIR_PREFIX)/usr/include/efi/protocol 27 | +cppflags = -DCONFIG_$(ARCH) 28 | +cflags = -O2 $(ARCH3264) -fpic -Wall -fshort-wchar -fno-strict-aliasing -fno-merge-constants -fno-stack-protector -ffreestanding -fno-stack-check $(CFLAGS) 29 | +ldflags = -nostdlib $(LDFLAGS) 30 | CRTOBJ = crt0-efi-$(ARCH).o 31 | CRTPATHS = /lib /lib64 /lib/efi /lib64/efi /usr/lib /usr/lib64 /usr/lib/efi /usr/lib64/efi 32 | -CRTPATH = $(shell for f in $(CRTPATHS); do if [ -e $$f/$(CRTOBJ) ]; then echo $$f; break; fi; done) 33 | +CRTPATH = $(shell for f in $(CRTPATHS); do if [ -e $(CRTPATH_PREFIX)/$$f/$(CRTOBJ) ]; then echo $(CRTPATH_PREFIX)/$$f; break; fi; done) 34 | CRTOBJS = $(CRTPATH)/$(CRTOBJ) 35 | # there's a bug in the gnu tools ... the .reloc section has to be 36 | # aligned otherwise the file alignment gets screwed up 37 | LDSCRIPT = elf_$(ARCH)_efi.lds 38 | -LDFLAGS += -shared -Bsymbolic $(CRTOBJS) -L $(CRTPATH) -T $(LDSCRIPT) 39 | +ldflags += -shared -Bsymbolic $(CRTOBJS) -L $(CRTPATH) -T $(LDSCRIPT) 40 | +ldflags_openssl = $(addprefix -L$(CRTPATH_PREFIX),$(CRTPATHS)) 41 | LOADLIBES = -lefi -lgnuefi $(shell $(CC) $(ARCH3264) -print-libgcc-file-name) 42 | FORMAT = --target=efi-app-$(ARCH) 43 | OBJCOPY = objcopy 44 | +NM = nm 45 | +AR = ar 46 | +OPENSSL = openssl 47 | +SBSIGN = sbsign 48 | +XXD = xxd 49 | MYGUID = 11111111-2222-3333-4444-123456789abc 50 | INSTALL = install 51 | BINDIR = $(DESTDIR)/usr/bin 52 | @@ -36,23 +42,23 @@ EFIDIR = $(DESTDIR)/usr/share/efitools/efi 53 | DOCDIR = $(DESTDIR)/usr/share/efitools 54 | 55 | # globally use EFI calling conventions (requires gcc >= 4.7) 56 | -CFLAGS += -DGNU_EFI_USE_MS_ABI 57 | +cflags += -DGNU_EFI_USE_MS_ABI 58 | 59 | ifeq ($(ARCH),x86_64) 60 | - CFLAGS += -DEFI_FUNCTION_WRAPPER -mno-red-zone 61 | + cflags += -DEFI_FUNCTION_WRAPPER -mno-red-zone 62 | endif 63 | 64 | ifeq ($(ARCH),ia32) 65 | - CFLAGS += -mno-red-zone 66 | + cflags += -mno-red-zone 67 | endif 68 | 69 | ifeq ($(ARCH),arm) 70 | - LDFLAGS += --defsym=EFI_SUBSYSTEM=0x0a 71 | + ldflags += --defsym=EFI_SUBSYSTEM=0x0a 72 | FORMAT = -O binary 73 | endif 74 | 75 | ifeq ($(ARCH),aarch64) 76 | - LDFLAGS += --defsym=EFI_SUBSYSTEM=0x0a 77 | + ldflags += --defsym=EFI_SUBSYSTEM=0x0a 78 | FORMAT = -O binary 79 | endif 80 | 81 | @@ -61,12 +67,12 @@ endif 82 | -j .rel -j .rela -j .rel.* -j .rela.* -j .rel* -j .rela* \ 83 | -j .reloc $(FORMAT) $*.so $@ 84 | %.so: %.o 85 | - $(LD) $(LDFLAGS) $^ -o $@ $(LOADLIBES) 86 | + $(LD) $(ldflags) $^ -o $@ $(LOADLIBES) 87 | # check we have no undefined symbols 88 | - nm -D $@ | grep ' U ' && exit 1 || exit 0 89 | + ${NM} -D $@ | grep ' U ' && exit 1 || exit 0 90 | 91 | %.h: %.auth 92 | - ./xxdi.pl $< > $@ 93 | + $(XXD) -i $< > $@ 94 | 95 | %.hash: %.efi hash-to-efi-sig-list 96 | ./hash-to-efi-sig-list $< $@ 97 | @@ -99,28 +105,28 @@ getvar = $(shell if [ "$(1)" = "PK" -o "$(1)" = "KEK" ]; then echo $(1); else ec 98 | ./sign-efi-sig-list -a -c PK.crt -k PK.key dbx $< $@ 99 | 100 | %.o: %.c 101 | - $(CC) $(INCDIR) $(CFLAGS) $(CPPFLAGS) -c $< -o $@ 102 | + $(CC) $(INCDIR) $(cflags) $(cppflags) -c $< -o $@ 103 | 104 | %.efi.o: %.c 105 | - $(CC) $(INCDIR) $(CFLAGS) $(CPPFLAGS) -fno-toplevel-reorder -DBUILD_EFI -c $< -o $@ 106 | + $(CC) $(INCDIR) $(cflags) $(cppflags) -fno-toplevel-reorder -DBUILD_EFI -c $< -o $@ 107 | 108 | %.efi.s: %.c 109 | - $(CC) -S $(INCDIR) $(CFLAGS) $(CPPFLAGS) -fno-toplevel-reorder -DBUILD_EFI -c $< -o $@ 110 | + $(CC) -S $(INCDIR) $(cflags) $(cppflags) -fno-toplevel-reorder -DBUILD_EFI -c $< -o $@ 111 | 112 | %.crt: 113 | - openssl req -new -x509 -newkey rsa:2048 -subj "/CN=$*/" -keyout $*.key -out $@ -days 3650 -nodes -sha256 114 | + $(OPENSSL) req -new -x509 -newkey rsa:2048 -subj "/CN=$*/" -keyout $*.key -out $@ -days 3650 -nodes -sha256 115 | 116 | %.cer: %.crt 117 | - openssl x509 -in $< -out $@ -outform DER 118 | + $(OPENSSL) x509 -in $< -out $@ -outform DER 119 | 120 | %-subkey.csr: 121 | - openssl req -new -newkey rsa:2048 -keyout $*-subkey.key -subj "/CN=Subkey $* of KEK/" -out $@ -nodes 122 | + $(OPENSSL) req -new -newkey rsa:2048 -keyout $*-subkey.key -subj "/CN=Subkey $* of KEK/" -out $@ -nodes 123 | 124 | %-subkey.crt: %-subkey.csr KEK.crt 125 | - openssl x509 -req -in $< -CA DB.crt -CAkey DB.key -set_serial 1 -out $@ -days 365 126 | + $(OPENSSL) x509 -req -in $< -CA DB.crt -CAkey DB.key -set_serial 1 -out $@ -days 365 127 | 128 | %-signed.efi: %.efi DB.crt 129 | - sbsign --key DB.key --cert DB.crt --output $@ $< 130 | + $(SBSIGN) --key DB.key --cert DB.crt --output $@ $< 131 | 132 | ## 133 | # No need for KEK signing 134 | @@ -129,7 +135,7 @@ getvar = $(shell if [ "$(1)" = "PK" -o "$(1)" = "KEK" ]; then echo $(1); else ec 135 | # sbsign --key KEK.key --cert KEK.crt --output $@ $< 136 | 137 | %.a: 138 | - ar rcv $@ $^ 139 | + $(AR) rcv $@ $^ 140 | 141 | doc/%.1: doc/%.1.in % 142 | $(HELP2MAN) --no-info -i $< -o $@ ./$* 143 | diff --git a/Makefile b/Makefile 144 | index 774ee0a..46e4620 100644 145 | --- a/Makefile 146 | +++ b/Makefile 147 | @@ -73,7 +73,7 @@ ms-%.esl: ms-%.crt cert-to-efi-sig-list 148 | 149 | hashlist.h: HashTool.hash 150 | cat $^ > /tmp/tmp.hash 151 | - ./xxdi.pl /tmp/tmp.hash > $@ 152 | + $(XXD) -i /tmp/tmp.hash > $@ 153 | rm -f /tmp/tmp.hash 154 | 155 | 156 | @@ -88,28 +88,28 @@ HelloWorld.so: lib/lib-efi.a 157 | ShimReplace.so: lib/lib-efi.a 158 | 159 | cert-to-efi-sig-list: cert-to-efi-sig-list.o lib/lib.a 160 | - $(CC) $(ARCH3264) -o $@ $< -lcrypto lib/lib.a 161 | + $(CC) $(ARCH3264) -o $@ $< $(ldflags_openssl) $(EXTRA_LDFLAGS) -lcrypto lib/lib.a 162 | 163 | sig-list-to-certs: sig-list-to-certs.o lib/lib.a 164 | - $(CC) $(ARCH3264) -o $@ $< -lcrypto lib/lib.a 165 | + $(CC) $(ARCH3264) -o $@ $< $(ldflags_openssl) $(EXTRA_LDFLAGS) -lcrypto lib/lib.a 166 | 167 | sign-efi-sig-list: sign-efi-sig-list.o lib/lib.a 168 | - $(CC) $(ARCH3264) -o $@ $< -lcrypto lib/lib.a 169 | + $(CC) $(ARCH3264) -o $@ $< $(ldflags_openssl) $(EXTRA_LDFLAGS) -lcrypto lib/lib.a 170 | 171 | hash-to-efi-sig-list: hash-to-efi-sig-list.o lib/lib.a 172 | $(CC) $(ARCH3264) -o $@ $< lib/lib.a 173 | 174 | cert-to-efi-hash-list: cert-to-efi-hash-list.o lib/lib.a 175 | - $(CC) $(ARCH3264) -o $@ $< -lcrypto lib/lib.a 176 | + $(CC) $(ARCH3264) -o $@ $< $(ldflags_openssl) $(EXTRA_LDFLAGS) -lcrypto lib/lib.a 177 | 178 | efi-keytool: efi-keytool.o lib/lib.a 179 | $(CC) $(ARCH3264) -o $@ $< lib/lib.a 180 | 181 | efi-readvar: efi-readvar.o lib/lib.a 182 | - $(CC) $(ARCH3264) -o $@ $< -lcrypto lib/lib.a 183 | + $(CC) $(ARCH3264) -o $@ $< $(ldflags_openssl) $(EXTRA_LDFLAGS) -lcrypto lib/lib.a 184 | 185 | efi-updatevar: efi-updatevar.o lib/lib.a 186 | - $(CC) $(ARCH3264) -o $@ $< -lcrypto lib/lib.a 187 | + $(CC) $(ARCH3264) -o $@ $< $(ldflags_openssl) $(EXTRA_LDFLAGS) -lcrypto lib/lib.a 188 | 189 | flash-var: flash-var.o lib/lib.a 190 | $(CC) $(ARCH3264) -o $@ $< lib/lib.a 191 | -- 192 | 1.9.1 193 | 194 | -------------------------------------------------------------------------------- /recipes-bsp/efitools/efitools/Fix-help2man-error.patch: -------------------------------------------------------------------------------- 1 | From f2e4ff4e63f4a5f8a4452c970ca271091eeaec7d Mon Sep 17 00:00:00 2001 2 | From: Lans Zhang 3 | Date: Sun, 18 Jun 2017 23:35:09 +0800 4 | Subject: [PATCH] Fix help2man error 5 | 6 | This issue may be caused by the poky compiler. 7 | 8 | Signed-off-by: Lans Zhang 9 | --- 10 | Make.rules | 4 +++- 11 | 1 file changed, 3 insertions(+), 1 deletion(-) 12 | 13 | diff --git a/Make.rules b/Make.rules 14 | index 38c7a22..bda5518 100644 15 | --- a/Make.rules 16 | +++ b/Make.rules 17 | @@ -140,5 +140,7 @@ getvar = $(shell if [ "$(1)" = "PK" -o "$(1)" = "KEK" ]; then echo $(1); else ec 18 | %.a: 19 | $(AR) rcv $@ $^ 20 | 21 | +HELP2MAN_PROG_PREFIX ?= . 22 | + 23 | doc/%.1: doc/%.1.in % 24 | - $(HELP2MAN) --no-discard-stderr --no-info -i $< -o $@ ./$* 25 | + $(HELP2MAN) --no-discard-stderr --no-info -i $< -o $@ $(HELP2MAN_PROG_PREFIX)/$* 26 | -- 27 | 2.7.5 28 | 29 | -------------------------------------------------------------------------------- /recipes-bsp/efitools/efitools/Fix-help2man-failure.patch: -------------------------------------------------------------------------------- 1 | From 546b8c36301bdcf540b3b027fd25baa9cff2abdc Mon Sep 17 00:00:00 2001 2 | From: Lans Zhang 3 | Date: Wed, 23 Mar 2016 19:44:51 +0800 4 | Subject: [PATCH] Fix help2man failure 5 | 6 | Add --no-discard-stderr to work around the error. 7 | 8 | Signed-off-by: Lans Zhang 9 | --- 10 | Make.rules | 2 +- 11 | 1 file changed, 1 insertion(+), 1 deletion(-) 12 | 13 | diff --git a/Make.rules b/Make.rules 14 | index 4aa7650..21926b0 100644 15 | --- a/Make.rules 16 | +++ b/Make.rules 17 | @@ -142,4 +142,4 @@ getvar = $(shell if [ "$(1)" = "PK" -o "$(1)" = "KEK" ]; then echo $(1); else ec 18 | $(AR) rcv $@ $^ 19 | 20 | doc/%.1: doc/%.1.in % 21 | - $(HELP2MAN) --no-info -i $< -o $@ ./$* 22 | + $(HELP2MAN) --no-discard-stderr --no-info -i $< -o $@ ./$* 23 | -- 24 | 1.9.1 25 | 26 | -------------------------------------------------------------------------------- /recipes-bsp/efitools/efitools/Fix-the-wrong-dependency-for-blacklist.esl.patch: -------------------------------------------------------------------------------- 1 | From 52228c24af681463d73d5bd8454872b3e811855b Mon Sep 17 00:00:00 2001 2 | From: Lans Zhang 3 | Date: Tue, 15 Mar 2016 21:07:31 +0800 4 | Subject: [PATCH] Fix the wrong dependency for %-blacklist.esl 5 | 6 | Upstream-Status: Pending 7 | 8 | Signed-off-by: Lans Zhang 9 | --- 10 | Make.rules | 2 +- 11 | 1 file changed, 1 insertion(+), 1 deletion(-) 12 | 13 | diff --git a/Make.rules b/Make.rules 14 | index 48b02e4..08a2489 100644 15 | --- a/Make.rules 16 | +++ b/Make.rules 17 | @@ -77,7 +77,7 @@ endif 18 | %.hash: %.efi hash-to-efi-sig-list 19 | ./hash-to-efi-sig-list $< $@ 20 | 21 | -%-blacklist.esl: %.crt cert-to-efi-hash-list 22 | +%-blacklist.esl: %.crt cert-to-efi-sig-list 23 | ./cert-to-efi-sig-list $< $@ 24 | 25 | %-hash-blacklist.esl: %.crt cert-to-efi-hash-list 26 | -- 27 | 1.9.1 28 | 29 | -------------------------------------------------------------------------------- /recipes-bsp/efitools/efitools/Kill-all-the-build-warning-caused-by-implicit-declar.patch: -------------------------------------------------------------------------------- 1 | From 872a9d96386b819d2c5fd7581d2bdaf7ea61a5f8 Mon Sep 17 00:00:00 2001 2 | From: Lans Zhang 3 | Date: Tue, 15 Mar 2016 17:12:24 +0800 4 | Subject: [PATCH] Kill all the build warning caused by implicit declaration of 5 | function 6 | 7 | Upstream-Status: Pending 8 | 9 | Signed-off-by: Lans Zhang 10 | --- 11 | Loader.c | 1 + 12 | cert-to-efi-hash-list.c | 2 +- 13 | flash-var.c | 2 ++ 14 | lib/pecoff.c | 1 + 15 | sign-efi-sig-list.c | 2 ++ 16 | 5 files changed, 7 insertions(+), 1 deletion(-) 17 | 18 | diff --git a/Loader.c b/Loader.c 19 | index 1f9201a..044469a 100644 20 | --- a/Loader.c 21 | +++ b/Loader.c 22 | @@ -9,6 +9,7 @@ 23 | #include 24 | #include 25 | 26 | +#include 27 | #include 28 | #include 29 | #include 30 | diff --git a/cert-to-efi-hash-list.c b/cert-to-efi-hash-list.c 31 | index d4484f9..3792553 100644 32 | --- a/cert-to-efi-hash-list.c 33 | +++ b/cert-to-efi-hash-list.c 34 | @@ -3,7 +3,7 @@ 35 | * 36 | * see COPYING file 37 | */ 38 | - 39 | +#define _GNU_SOURCE 40 | 41 | #include 42 | #define __STDC_VERSION__ 199901L 43 | diff --git a/flash-var.c b/flash-var.c 44 | index aa10ae6..10429bc 100644 45 | --- a/flash-var.c 46 | +++ b/flash-var.c 47 | @@ -1,3 +1,5 @@ 48 | +#define _GNU_SOURCE 49 | + 50 | #include 51 | #include 52 | #include 53 | diff --git a/lib/pecoff.c b/lib/pecoff.c 54 | index 26d9dcf..10b898a 100644 55 | --- a/lib/pecoff.c 56 | +++ b/lib/pecoff.c 57 | @@ -59,6 +59,7 @@ 58 | #endif 59 | #endif 60 | 61 | +#include 62 | #include 63 | #include 64 | #include 65 | diff --git a/sign-efi-sig-list.c b/sign-efi-sig-list.c 66 | index e19ef97..5abcf27 100644 67 | --- a/sign-efi-sig-list.c 68 | +++ b/sign-efi-sig-list.c 69 | @@ -3,6 +3,8 @@ 70 | * 71 | * see COPYING file 72 | */ 73 | +#define _GNU_SOURCE 74 | + 75 | #include 76 | #define __STDC_VERSION__ 199901L 77 | #include 78 | -- 79 | 1.9.1 80 | 81 | -------------------------------------------------------------------------------- /recipes-bsp/efitools/efitools/LockDown-disable-the-entrance-into-BIOS-setup-to-re-.patch: -------------------------------------------------------------------------------- 1 | From e259aecc645c6dd4c194a64d607124cd5a714f9a Mon Sep 17 00:00:00 2001 2 | From: Lans Zhang 3 | Date: Wed, 15 Feb 2017 14:52:07 +0800 4 | Subject: [PATCH] LockDown: disable the entrance into BIOS setup to re-enable 5 | secure boot 6 | 7 | In most cases, this step is not necessary. 8 | 9 | Signed-off-by: Lans Zhang 10 | --- 11 | LockDown.c | 9 +++++++-- 12 | 1 file changed, 7 insertions(+), 2 deletions(-) 13 | 14 | diff --git a/LockDown.c b/LockDown.c 15 | index 13c626f..fbde3f2 100644 16 | --- a/LockDown.c 17 | +++ b/LockDown.c 18 | @@ -20,6 +20,11 @@ efi_main (EFI_HANDLE image, EFI_SYSTEM_TABLE *systab) 19 | EFI_STATUS efi_status; 20 | UINT8 SecureBoot, SetupMode; 21 | UINTN DataSize = sizeof(SetupMode); 22 | + /* This controls whether it is required to enter into BIOS setup in 23 | + * order to re-enable UEFI secure boot. This operation is unnecessary 24 | + * in most cases. 25 | + */ 26 | + UINTN NeedSetAttempt = 0; 27 | 28 | InitializeLib(image, systab); 29 | 30 | @@ -110,12 +115,12 @@ efi_main (EFI_HANDLE image, EFI_SYSTEM_TABLE *systab) 31 | * UEFI secure boot in BIOS setup. 32 | */ 33 | Print(L"Prepare to execute system warm reset after 3 seconds ...\n"); 34 | - if (!SecureBoot) 35 | + if (NeedSetAttempt && !SecureBoot) 36 | Print(L"After warm reset, enter to BIOS setup to enable UEFI Secure Boot.\n"); 37 | 38 | BS->Stall(3000000); 39 | 40 | - if (!SecureBoot) 41 | + if (NeedSetAttempt && !SecureBoot) 42 | SETOSIndicationsAndReboot(EFI_OS_INDICATIONS_BOOT_TO_FW_UI); 43 | else 44 | RT->ResetSystem(EfiResetWarm, EFI_SUCCESS, 0, NULL); 45 | -- 46 | 2.7.4 47 | 48 | -------------------------------------------------------------------------------- /recipes-bsp/efitools/efitools/LockDown-enable-the-enrollment-for-DBX.patch: -------------------------------------------------------------------------------- 1 | From 49b6a0bf2b9c69d1fd682fbc9d2ad7a7f6abee77 Mon Sep 17 00:00:00 2001 2 | From: Lans Zhang 3 | Date: Fri, 22 Apr 2016 16:28:05 +0800 4 | Subject: [PATCH] LockDown: enable the enrollment for DBX 5 | 6 | Upstream-Status: Pending 7 | 8 | DBX acting as blacklist now is able to be enrolled. 9 | 10 | Signed-off-by: Lans Zhang 11 | --- 12 | LockDown.c | 16 +++++++++++----- 13 | Makefile | 4 +++- 14 | 2 files changed, 14 insertions(+), 6 deletions(-) 15 | 16 | diff --git a/LockDown.c b/LockDown.c 17 | index 821985c..fec2e79 100644 18 | --- a/LockDown.c 19 | +++ b/LockDown.c 20 | @@ -12,6 +12,7 @@ 21 | #include "PK.h" 22 | #include "KEK.h" 23 | #include "DB.h" 24 | +#include "DBX.h" 25 | 26 | EFI_STATUS 27 | efi_main (EFI_HANDLE image, EFI_SYSTEM_TABLE *systab) 28 | @@ -47,6 +48,7 @@ efi_main (EFI_HANDLE image, EFI_SYSTEM_TABLE *systab) 29 | return efi_status; 30 | } 31 | Print(L"Created KEK Cert\n"); 32 | + 33 | efi_status = RT->SetVariable(L"db", &SIG_DB, 34 | EFI_VARIABLE_NON_VOLATILE 35 | | EFI_VARIABLE_RUNTIME_ACCESS 36 | @@ -58,15 +60,19 @@ efi_main (EFI_HANDLE image, EFI_SYSTEM_TABLE *systab) 37 | return efi_status; 38 | } 39 | Print(L"Created db Cert\n"); 40 | -#if 0 41 | - /* testing revocation ... this will revoke the certificate 42 | - * we just enrolled in db */ 43 | - efi_status = SetSecureVariable(L"dbx", DB_cer, DB_cer_len, SIG_DB, 0); 44 | + 45 | + efi_status = RT->SetVariable(L"dbx", &SIG_DB, 46 | + EFI_VARIABLE_NON_VOLATILE 47 | + | EFI_VARIABLE_RUNTIME_ACCESS 48 | + | EFI_VARIABLE_BOOTSERVICE_ACCESS 49 | + | EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS, 50 | + DBX_auth_len, DBX_auth); 51 | if (efi_status != EFI_SUCCESS) { 52 | Print(L"Failed to enroll dbx: %d\n", efi_status); 53 | return efi_status; 54 | } 55 | -#endif 56 | + Print(L"Created dbx Cert\n"); 57 | + 58 | /* PK must be updated with a signed copy of itself */ 59 | efi_status = RT->SetVariable(L"PK", &GV_GUID, 60 | EFI_VARIABLE_NON_VOLATILE 61 | diff --git a/Makefile b/Makefile 62 | index b3bb73a..e189866 100644 63 | --- a/Makefile 64 | +++ b/Makefile 65 | @@ -53,7 +53,7 @@ lib/asn1/libasn1.a lib/asn1/libasn1-efi.a: FORCE 66 | .KEEP: PK.crt KEK.crt DB.crt PK.key KEK.key DB.key PK.esl DB.esl KEK.esl \ 67 | $(EFIFILES) 68 | 69 | -LockDown.o: PK.h KEK.h DB.h 70 | +LockDown.o: PK.h KEK.h DB.h DBX.h 71 | PreLoader.o: hashlist.h 72 | 73 | PK.h: PK.auth 74 | @@ -62,6 +62,8 @@ KEK.h: KEK.auth 75 | 76 | DB.h: DB.auth 77 | 78 | +DBX.h: DBX.auth 79 | + 80 | noPK.esl: 81 | > noPK.esl 82 | 83 | -- 84 | 1.9.1 85 | 86 | -------------------------------------------------------------------------------- /recipes-bsp/efitools/efitools/LockDown-run-system-warm-reset-after-the-key-provisi.patch: -------------------------------------------------------------------------------- 1 | From b2897e78c7910f0e55f4861542155d2817c15bf4 Mon Sep 17 00:00:00 2001 2 | From: Lans Zhang 3 | Date: Fri, 25 Mar 2016 10:52:34 +0800 4 | Subject: [PATCH] LockDown: run system warm reset after the key provision 5 | success 6 | 7 | Upstream-Status: Pending 8 | 9 | In addition, BIOS would stop at its setup screen. The end user can thus 10 | enable UEFI secure boot immediately. 11 | 12 | Signed-off-by: Lans Zhang 13 | --- 14 | LockDown.c | 15 +++++++++++++++ 15 | 1 file changed, 15 insertions(+) 16 | 17 | diff --git a/LockDown.c b/LockDown.c 18 | index 29df9de..821985c 100644 19 | --- a/LockDown.c 20 | +++ b/LockDown.c 21 | @@ -99,5 +99,20 @@ efi_main (EFI_HANDLE image, EFI_SYSTEM_TABLE *systab) 22 | } 23 | Print(L"Platform %s set to boot securely\n", SecureBoot ? L"is" : L"is not"); 24 | 25 | + /* Reset system to go back the real UEFI secure boot flow. 26 | + * If SecureBoot is still false, the user needs to turn on 27 | + * UEFI secure boot in BIOS setup. 28 | + */ 29 | + Print(L"Prepare to execute system warm reset after 3 seconds ...\n"); 30 | + if (!SecureBoot) 31 | + Print(L"After warm reset, enter to BIOS setup to enable UEFI Secure Boot.\n"); 32 | + 33 | + BS->Stall(3000000); 34 | + 35 | + if (!SecureBoot) 36 | + SETOSIndicationsAndReboot(EFI_OS_INDICATIONS_BOOT_TO_FW_UI); 37 | + else 38 | + RT->ResetSystem(EfiResetWarm, EFI_SUCCESS, 0, NULL); 39 | + 40 | return EFI_SUCCESS; 41 | } 42 | -- 43 | 1.9.1 44 | 45 | -------------------------------------------------------------------------------- /recipes-bsp/efitools/efitools/LockDown-show-the-error-message-with-3-sec-timeout.patch: -------------------------------------------------------------------------------- 1 | From 28eb6a3118c3c843b41732ec3cf5167fe027daba Mon Sep 17 00:00:00 2001 2 | From: Lans Zhang 3 | Date: Tue, 17 Jan 2017 12:48:27 +0800 4 | Subject: [PATCH] LockDown: show the error message with 3-sec timeout 5 | 6 | Signed-off-by: Lans Zhang 7 | --- 8 | LockDown.c | 20 ++++++++++++-------- 9 | 1 file changed, 12 insertions(+), 8 deletions(-) 10 | 11 | diff --git a/LockDown.c b/LockDown.c 12 | index fec2e79..13c626f 100644 13 | --- a/LockDown.c 14 | +++ b/LockDown.c 15 | @@ -27,12 +27,12 @@ efi_main (EFI_HANDLE image, EFI_SYSTEM_TABLE *systab) 16 | 17 | if (efi_status != EFI_SUCCESS) { 18 | Print(L"No SetupMode variable ... is platform secure boot enabled?\n"); 19 | - return EFI_SUCCESS; 20 | + goto out; 21 | } 22 | 23 | if (!SetupMode) { 24 | Print(L"Platform is not in Setup Mode, cannot install Keys\n"); 25 | - return EFI_SUCCESS; 26 | + goto out; 27 | } 28 | 29 | Print(L"Platform is in Setup Mode\n"); 30 | @@ -45,7 +45,7 @@ efi_main (EFI_HANDLE image, EFI_SYSTEM_TABLE *systab) 31 | KEK_auth_len, KEK_auth); 32 | if (efi_status != EFI_SUCCESS) { 33 | Print(L"Failed to enroll KEK: %d\n", efi_status); 34 | - return efi_status; 35 | + goto out; 36 | } 37 | Print(L"Created KEK Cert\n"); 38 | 39 | @@ -57,7 +57,7 @@ efi_main (EFI_HANDLE image, EFI_SYSTEM_TABLE *systab) 40 | DB_auth_len, DB_auth); 41 | if (efi_status != EFI_SUCCESS) { 42 | Print(L"Failed to enroll db: %d\n", efi_status); 43 | - return efi_status; 44 | + goto out; 45 | } 46 | Print(L"Created db Cert\n"); 47 | 48 | @@ -69,7 +69,7 @@ efi_main (EFI_HANDLE image, EFI_SYSTEM_TABLE *systab) 49 | DBX_auth_len, DBX_auth); 50 | if (efi_status != EFI_SUCCESS) { 51 | Print(L"Failed to enroll dbx: %d\n", efi_status); 52 | - return efi_status; 53 | + goto out; 54 | } 55 | Print(L"Created dbx Cert\n"); 56 | 57 | @@ -84,14 +84,14 @@ efi_main (EFI_HANDLE image, EFI_SYSTEM_TABLE *systab) 58 | 59 | if (efi_status != EFI_SUCCESS) { 60 | Print(L"Failed to enroll PK: %d\n", efi_status); 61 | - return efi_status; 62 | + goto out; 63 | } 64 | Print(L"Created PK Cert\n"); 65 | /* enrolling the PK should put us in SetupMode; check this */ 66 | efi_status = RT->GetVariable(L"SetupMode", &GV_GUID, NULL, &DataSize, &SetupMode); 67 | if (efi_status != EFI_SUCCESS) { 68 | Print(L"Failed to get SetupMode variable: %d\n", efi_status); 69 | - return efi_status; 70 | + goto out; 71 | } 72 | Print(L"Platform is in %s Mode\n", SetupMode ? L"Setup" : L"User"); 73 | 74 | @@ -101,7 +101,7 @@ efi_main (EFI_HANDLE image, EFI_SYSTEM_TABLE *systab) 75 | 76 | if (efi_status != EFI_SUCCESS) { 77 | Print(L"Failed to get SecureBoot variable: %d\n", efi_status); 78 | - return efi_status; 79 | + goto out; 80 | } 81 | Print(L"Platform %s set to boot securely\n", SecureBoot ? L"is" : L"is not"); 82 | 83 | @@ -121,4 +121,8 @@ efi_main (EFI_HANDLE image, EFI_SYSTEM_TABLE *systab) 84 | RT->ResetSystem(EfiResetWarm, EFI_SUCCESS, 0, NULL); 85 | 86 | return EFI_SUCCESS; 87 | + 88 | +out: 89 | + BS->Stall(3000000); 90 | + return efi_status; 91 | } 92 | -- 93 | 2.7.4 94 | 95 | -------------------------------------------------------------------------------- /recipes-bsp/efitools/efitools/Makefile-do-not-build-signed-efi-image.patch: -------------------------------------------------------------------------------- 1 | From 923b9cb2bfe81ff29a29d46bfc4e3fe172e0e5ae Mon Sep 17 00:00:00 2001 2 | From: Yunguo Wei 3 | Date: Tue, 17 Jan 2017 17:24:51 +0800 4 | Subject: [PATCH] Makefile: do not build signed efi image 5 | 6 | Signed-off-by: Yunguo Wei 7 | --- 8 | Makefile | 5 ++--- 9 | 1 file changed, 2 insertions(+), 3 deletions(-) 10 | 11 | diff --git a/Makefile b/Makefile 12 | index addb593..a1fc538 100644 13 | --- a/Makefile 14 | +++ b/Makefile 15 | @@ -1,5 +1,4 @@ 16 | -EFIFILES = HelloWorld.efi LockDown.efi Loader.efi ReadVars.efi UpdateVars.efi \ 17 | - KeyTool.efi HashTool.efi SetNull.efi ShimReplace.efi 18 | +EFIFILES = LockDown.efi 19 | BINARIES = cert-to-efi-sig-list sig-list-to-certs sign-efi-sig-list \ 20 | hash-to-efi-sig-list efi-readvar efi-updatevar cert-to-efi-hash-list \ 21 | flash-var 22 | @@ -27,7 +26,7 @@ include Make.rules 23 | 24 | EFISIGNED = $(patsubst %.efi,%-signed.efi,$(EFIFILES)) 25 | 26 | -all: $(EFISIGNED) $(BINARIES) $(MANPAGES) noPK.auth $(KEYAUTH) \ 27 | +all: $(EFIFILES) $(BINARIES) $(MANPAGES) noPK.auth $(KEYAUTH) \ 28 | $(KEYUPDATEAUTH) $(KEYBLACKLISTAUTH) $(KEYHASHBLACKLISTAUTH) 29 | 30 | 31 | -- 32 | 2.7.4 33 | 34 | -------------------------------------------------------------------------------- /recipes-bsp/efitools/efitools/Reuse-xxdi.pl.patch: -------------------------------------------------------------------------------- 1 | From 959e4395b5524babb27c2bf95fa37b990d79b663 Mon Sep 17 00:00:00 2001 2 | From: Lans Zhang 3 | Date: Thu, 28 Apr 2016 12:52:22 +0800 4 | Subject: [PATCH] Reuse xxdi.pl 5 | 6 | The missing File::Slurp required by xxdi.pl is added. To avoid introducing 7 | an extra xxd package, remove the support of using xxd. 8 | 9 | Signed-off-by: Lans Zhang 10 | --- 11 | Make.rules | 3 +-- 12 | Makefile | 2 +- 13 | 2 files changed, 2 insertions(+), 3 deletions(-) 14 | 15 | diff --git a/Make.rules b/Make.rules 16 | index 21926b0..38c7a22 100644 17 | --- a/Make.rules 18 | +++ b/Make.rules 19 | @@ -33,7 +33,6 @@ NM = nm 20 | AR = ar 21 | OPENSSL = openssl 22 | SBSIGN = sbsign 23 | -XXD = xxd 24 | SIGN_EFI_SIG_LIST ?= ./sign-efi-sig-list 25 | CERT_TO_EFI_SIG_LIST ?= ./cert-to-efi-sig-list 26 | CERT_TO_EFI_HASH_LIST ?= ./cert-to-efi-hash-list 27 | @@ -76,7 +75,7 @@ endif 28 | ${NM} -D $@ | grep ' U ' && exit 1 || exit 0 29 | 30 | %.h: %.auth 31 | - $(XXD) -i $< > $@ 32 | + ./xxdi.pl $< > $@ 33 | 34 | %.hash: %.efi hash-to-efi-sig-list 35 | $(HASH_TO_EFI_SIG_LIST) $< $@ 36 | diff --git a/Makefile b/Makefile 37 | index da363a6..2534b47 100644 38 | --- a/Makefile 39 | +++ b/Makefile 40 | @@ -73,7 +73,7 @@ ms-%.esl: ms-%.crt cert-to-efi-sig-list 41 | 42 | hashlist.h: HashTool.hash 43 | cat $^ > /tmp/tmp.hash 44 | - $(XXD) -i /tmp/tmp.hash > $@ 45 | + ./xxdi.pl /tmp/tmp.hash > $@ 46 | rm -f /tmp/tmp.hash 47 | 48 | 49 | -- 50 | 1.9.1 51 | 52 | -------------------------------------------------------------------------------- /recipes-bsp/efitools/efitools_git.bb: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2015-2017 Wind River Systems, Inc. 3 | # 4 | 5 | require efitools.inc 6 | 7 | SRC_URI_append += " \ 8 | file://LockDown-enable-the-enrollment-for-DBX.patch \ 9 | file://LockDown-show-the-error-message-with-3-sec-timeout.patch \ 10 | file://Makefile-do-not-build-signed-efi-image.patch \ 11 | file://Build-DBX-by-default.patch \ 12 | file://LockDown-disable-the-entrance-into-BIOS-setup-to-re-.patch \ 13 | file://Fix-help2man-error.patch \ 14 | " 15 | 16 | COMPATIBLE_HOST = '(i.86|x86_64).*-linux' 17 | 18 | inherit user-key-store deploy 19 | 20 | # The generated native binaries are used during native and target build 21 | DEPENDS += "${BPN}-native gnu-efi openssl" 22 | 23 | RDEPENDS_${PN}_append += " \ 24 | parted mtools coreutils util-linux openssl libcrypto \ 25 | " 26 | 27 | EXTRA_OEMAKE_append += " \ 28 | INCDIR_PREFIX='${STAGING_DIR_TARGET}' \ 29 | CRTPATH_PREFIX='${STAGING_DIR_TARGET}' \ 30 | SIGN_EFI_SIG_LIST='${STAGING_BINDIR_NATIVE}/sign-efi-sig-list' \ 31 | CERT_TO_EFI_SIG_LIST='${STAGING_BINDIR_NATIVE}/cert-to-efi-sig-list' \ 32 | CERT_TO_EFI_HASH_LIST='${STAGING_BINDIR_NATIVE}/cert-to-efi-hash-list' \ 33 | HASH_TO_EFI_SIG_LIST='${STAGING_BINDIR_NATIVE}/hash-to-efi-sig-list' \ 34 | MYGUID='${UEFI_SIG_OWNER_GUID}' \ 35 | HELP2MAN_PROG_PREFIX='${STAGING_BINDIR_NATIVE}' \ 36 | " 37 | 38 | python do_prepare_signing_keys() { 39 | if d.expand('${UEFI_SB}') != '1': 40 | return 41 | 42 | # Prepare PK, KEK and DB for LockDown.efi. 43 | if uks_signing_model(d) in ('sample', 'user'): 44 | dir = uefi_sb_keys_dir(d) 45 | else: 46 | dir = d.expand('${SAMPLE_UEFI_SB_KEYS_DIR}/') 47 | 48 | import shutil 49 | 50 | for _ in ('PK', 'KEK', 'DB'): 51 | shutil.copyfile(dir + _ + '.pem', d.expand('${S}/') + _ + '.crt') 52 | shutil.copyfile(dir + _ + '.key', d.expand('${S}/') + _ + '.key') 53 | 54 | # Make sure LockDown.efi contains the DB and KEK from Microsoft. 55 | if "${@bb.utils.contains('DISTRO_FEATURES', 'msft', '1', '0', d)}" == '1': 56 | shutil.copyfile(d.expand('${MSFT_DB_CERT}'), d.expand('${S}/DB.crt')) 57 | shutil.copyfile(d.expand('${MSFT_KEK_CERT}'), d.expand('${S}/KEK.crt')) 58 | 59 | path = create_uefi_dbx(d) 60 | if path: 61 | with open(d.expand('${S}/DBX.crt'), 'w') as f: 62 | pass 63 | 64 | shutil.copyfile(path, d.expand('${S}/DBX.esl')) 65 | 66 | # Cheat the Makefile to avoid running this rule: 67 | # %.esl: %.crt cert-to-efi-sig-list 68 | # $(CERT_TO_EFI_SIG_LIST) -g $(MYGUID) $< $@ 69 | import time, os 70 | tm = time.strptime('2038-01-01 00:00:00', \ 71 | '%Y-%m-%d %H:%M:%S') 72 | time_stamp = time.mktime(tm) 73 | os.utime(d.expand('${S}/DBX.esl'), (time_stamp, time_stamp)) 74 | } 75 | addtask prepare_signing_keys after do_configure before do_compile 76 | 77 | do_install_append() { 78 | install -d ${D}${EFI_BOOT_PATH} 79 | install -m 0755 ${D}${datadir}/efitools/efi/LockDown.efi ${D}${EFI_BOOT_PATH} 80 | } 81 | 82 | do_deploy() { 83 | install -d ${DEPLOYDIR} 84 | 85 | install -m 0600 ${D}${EFI_BOOT_PATH}/LockDown.efi "${DEPLOYDIR}" 86 | } 87 | addtask deploy after do_install before do_build 88 | -------------------------------------------------------------------------------- /recipes-bsp/grub/grub-efi/0001-pe32.h-add-header-structures-for-TE-and-DOS-executab.patch: -------------------------------------------------------------------------------- 1 | From aecadf65c4d3dea68e55605ff5f0c3eb90206488 Mon Sep 17 00:00:00 2001 2 | From: Ricardo Neri 3 | Date: Fri, 27 Mar 2015 08:01:41 -0700 4 | Subject: [PATCH 1/7] pe32.h: add header structures for TE and DOS executables 5 | 6 | Upstream-Status: Inappropriate [embedded specific] 7 | 8 | Add header structures to describe the Terse Executable format and 9 | the DOS header format for executable images. 10 | 11 | These definitions are needed in subsequent commits to parse and 12 | verify the identity of the executable image when utilizing a shim 13 | to boot LUV. 14 | 15 | Signed-off-by: Ricardo Neri 16 | --- 17 | include/grub/efi/pe32.h | 36 ++++++++++++++++++++++++++++++++++++ 18 | 1 file changed, 36 insertions(+) 19 | 20 | diff --git a/include/grub/efi/pe32.h b/include/grub/efi/pe32.h 21 | index c3efa9b..c1c3483 100644 22 | --- a/include/grub/efi/pe32.h 23 | +++ b/include/grub/efi/pe32.h 24 | @@ -313,4 +313,40 @@ struct grub_pe32_reloc 25 | #define GRUB_PE32_REL_I386_DIR32 0x6 26 | #define GRUB_PE32_REL_I386_REL32 0x14 27 | 28 | +struct grub_te_header 29 | +{ 30 | + grub_uint16_t signature; 31 | + grub_uint16_t machine; 32 | + grub_uint8_t num_sections; 33 | + grub_uint8_t subsystem; 34 | + grub_uint16_t stripped_size; 35 | + grub_uint32_t entry_point; 36 | + grub_uint32_t code_base; 37 | + grub_uint64_t image_base; 38 | + struct grub_pe32_data_directory data_directory[2]; 39 | +}; 40 | + 41 | +struct grub_dos_header 42 | +{ 43 | + grub_uint16_t magic; 44 | + grub_uint16_t cblp; 45 | + grub_uint16_t cp; 46 | + grub_uint16_t crlc; 47 | + grub_uint16_t cparhdr; 48 | + grub_uint16_t minalloc; 49 | + grub_uint16_t maxalloc; 50 | + grub_uint16_t ss; 51 | + grub_uint16_t sp; 52 | + grub_uint16_t csum; 53 | + grub_uint16_t ip; 54 | + grub_uint16_t cs; 55 | + grub_uint16_t lfarlc; 56 | + grub_uint16_t ovno; 57 | + grub_uint16_t res[4]; 58 | + grub_uint16_t oemid; 59 | + grub_uint16_t oeminfo; 60 | + grub_uint16_t res2[10]; 61 | + grub_uint32_t lfanew; 62 | +}; 63 | + 64 | #endif /* ! GRUB_EFI_PE32_HEADER */ 65 | -- 66 | 1.9.1 67 | 68 | -------------------------------------------------------------------------------- /recipes-bsp/grub/grub-efi/0002-shim-add-needed-data-structures.patch: -------------------------------------------------------------------------------- 1 | From 2341c2d2cf2ee67b036d21aa9b12b71bea84495f Mon Sep 17 00:00:00 2001 2 | From: Ricardo Neri 3 | Date: Fri, 27 Mar 2015 08:09:58 -0700 4 | Subject: [PATCH 2/7] shim: add needed data structures 5 | 6 | Upstream-Status: Inappropriate [embedded specific] 7 | 8 | Add the needed data structures for shim to load, parse, relocate and 9 | execute a binary. This includes file-parsing structures, an identifier for 10 | the UEFI protocol for image verification under secure boot provided by shim. 11 | 12 | Shim is thin loader developed by Matthew Garret 13 | (https://github.com/rhinstaller/shim). This code was ported from such project. 14 | 15 | Signed-off-by: Ricardo Neri 16 | --- 17 | include/grub/efi/shim.h | 132 ++++++++++++++++++++++++++++++++++++++++++++++++ 18 | 1 file changed, 132 insertions(+) 19 | create mode 100644 include/grub/efi/shim.h 20 | 21 | diff --git a/include/grub/efi/shim.h b/include/grub/efi/shim.h 22 | new file mode 100644 23 | index 0000000..4b92a00 24 | --- /dev/null 25 | +++ b/include/grub/efi/shim.h 26 | @@ -0,0 +1,132 @@ 27 | +/* 28 | + * shim.h - interface to shim: UEFI first-stage bootloader 29 | + * 30 | + * Copyright 2015 Intel Corporation. 31 | + * 32 | + * Redistribution and use in source and binary forms, with or without 33 | + * modification, are permitted provided that the following conditions 34 | + * are met: 35 | + * 36 | + * Redistributions of source code must retain the above copyright 37 | + * notice, this list of conditions and the following disclaimer. 38 | + * 39 | + * Redistributions in binary form must reproduce the above copyright 40 | + * notice, this list of conditions and the following disclaimer in the 41 | + * documentation and/or other materials provided with the 42 | + * distribution. 43 | + * 44 | + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 45 | + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 46 | + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 47 | + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 48 | + * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 49 | + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 50 | + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 51 | + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 52 | + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 53 | + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 54 | + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 55 | + * OF THE POSSIBILITY OF SUCH DAMAGE. 56 | + * 57 | + * Significant portions of this code are derived from Red Hat shim: UEFI 58 | + * first-stage bootloader. 59 | + * (https://github.com/rhinstaller/shim) and are Copyright 2012 Red Hat, Inc 60 | + */ 61 | + 62 | +#ifndef GRUB_SHIM_HEADER 63 | +#define GRUB_SHIM_HEADER 1 64 | + 65 | +#include 66 | + 67 | +struct grub_nt_headers32 68 | +{ 69 | + grub_efi_uint32_t signature; 70 | + struct grub_pe32_coff_header file_hdr; 71 | + struct grub_pe32_optional_header opt_hdr; 72 | +}; 73 | + 74 | +struct grub_nt_headers64 75 | +{ 76 | + grub_efi_uint32_t signature; 77 | + struct grub_pe32_coff_header file_hdr; 78 | + struct grub_pe64_optional_header opt_hdr; 79 | +}; 80 | + 81 | +struct grub_image_base_relocation 82 | +{ 83 | + grub_efi_uint32_t virtual_address; 84 | + grub_efi_uint32_t block_size; 85 | +}; 86 | + 87 | +struct grub_shim_pe_coff_loader_image_context { 88 | + grub_efi_uint64_t image_address; 89 | + grub_efi_uint64_t image_size; 90 | + grub_efi_uint64_t entry_point; 91 | + grub_efi_uintn_t header_size; 92 | + grub_efi_uint16_t image_type; 93 | + grub_efi_uint16_t num_sections; 94 | + struct grub_pe32_section_table *first_section; 95 | + struct grub_pe32_data_directory *reloc_dir; 96 | + struct grub_pe32_data_directory *sec_dir; 97 | + grub_efi_uint64_t number_of_rva_and_sizes; 98 | + union grub_shim_optional_header_union *pe_hdr; 99 | +}; 100 | + 101 | +struct grub_shim_lock 102 | +{ 103 | + grub_efi_status_t 104 | + (*verify) (void *buffer, 105 | + grub_uint32_t size); 106 | + 107 | + grub_efi_status_t 108 | + (*hash) (grub_int8_t *data, 109 | + grub_int32_t datasize, 110 | + struct grub_shim_pe_coff_loader_image_context *context, 111 | + grub_uint8_t sha256hash, 112 | + grub_uint8_t sha1hash); 113 | + 114 | + grub_efi_status_t 115 | + (*context) (void *data, 116 | + grub_uint32_t datasize, 117 | + struct grub_shim_pe_coff_loader_image_context *context); 118 | +}; 119 | + 120 | +union grub_shim_optional_header_union 121 | +{ 122 | + struct grub_nt_headers32 pe32; 123 | + struct grub_nt_headers64 pe32plus; 124 | + struct grub_te_header te; 125 | +}; 126 | + 127 | +#define GRUB_EFI_SHIM_PROTOCOL_GUID \ 128 | + { 0x605dab50, 0xe046, 0x4300, \ 129 | + { 0xab, 0xb6, 0x3d, 0xd8, 0x10, 0xdd, 0x8b, 0x23 } \ 130 | + } 131 | + 132 | +#define SIGNATURE_16(A, B) ((A) | (B << 8)) 133 | +#define SIGNATURE_32(A, B, C, D) (SIGNATURE_16 (A, B) | (SIGNATURE_16 (C, D) << 16)) 134 | + 135 | +#define EFI_IMAGE_DOS_SIGNATURE SIGNATURE_16('M', 'Z') 136 | +#define EFI_IMAGE_NT_SIGNATURE SIGNATURE_32('P', 'E', '\0', '\0') 137 | + 138 | +#define EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC 5 139 | + 140 | +#define ALIGN_VALUE(Value, Alignment) ((Value) + (((Alignment) - (Value)) & ((Alignment) - 1))) 141 | +#define ALIGN_POINTER(Pointer, Alignment) ((void *) (ALIGN_VALUE ((grub_efi_uintn_t)(Pointer), (Alignment)))) 142 | + 143 | +/* Based relocation types. */ 144 | + 145 | +#define EFI_IMAGE_REL_BASED_ABSOLUTE 0 146 | +#define EFI_IMAGE_REL_BASED_HIGH 1 147 | +#define EFI_IMAGE_REL_BASED_LOW 2 148 | +#define EFI_IMAGE_REL_BASED_HIGHLOW 3 149 | +#define EFI_IMAGE_REL_BASED_HIGHADJ 4 150 | +#define EFI_IMAGE_REL_BASED_MIPS_JMPADDR 5 151 | +#define EFI_IMAGE_REL_BASED_ARM_MOV32A 5 152 | +#define EFI_IMAGE_REL_BASED_ARM_MOV32T 7 153 | +#define EFI_IMAGE_REL_BASED_IA64_IMM64 9 154 | +#define EFI_IMAGE_REL_BASED_MIPS_JMPADDR16 9 155 | +#define EFI_IMAGE_REL_BASED_DIR64 10 156 | + 157 | + 158 | +#endif /* ! GRUB_SHIM_HEADER */ 159 | -- 160 | 1.9.1 161 | 162 | -------------------------------------------------------------------------------- /recipes-bsp/grub/grub-efi/0003-efi-chainloader-implement-an-UEFI-Exit-service-for-s.patch: -------------------------------------------------------------------------------- 1 | From 3b75fa5071e4b1a40510669119791928859b46e7 Mon Sep 17 00:00:00 2001 2 | From: Matt Fleming 3 | Date: Fri, 27 Mar 2015 08:11:19 -0700 4 | Subject: [PATCH 3/7] efi: chainloader: implement an UEFI Exit service for shim 5 | in grub 6 | 7 | Upstream-Status: Inappropriate [embedded specific] 8 | 9 | When exiting, grub will call the UEFI boot-time service Exit. The 10 | effect of this is that UEFI will jump to the entry point of the 11 | UEFI started image. If we execute an image using shim within grub, 12 | shim takes care of loading/parsing/relocating/executing the image. 13 | Under this scenario, we also need to take care of the Exit call. Thus, 14 | we need to reimplement the function to make sure we perform a jump 15 | to the instruction after which shim executed the image. 16 | 17 | Once we have taken care of the exit of the shim-executed image 18 | the system Exit call is restored. 19 | 20 | Signed-off-by: Ricardo Neri 21 | --- 22 | grub-core/kern/x86_64/efi/callwrap.S | 23 +++++++++++++++++++++++ 23 | include/grub/efi/api.h | 4 ++++ 24 | 2 files changed, 27 insertions(+) 25 | 26 | diff --git a/grub-core/kern/x86_64/efi/callwrap.S b/grub-core/kern/x86_64/efi/callwrap.S 27 | index 2df95dd..f0f1dd8 100644 28 | --- a/grub-core/kern/x86_64/efi/callwrap.S 29 | +++ b/grub-core/kern/x86_64/efi/callwrap.S 30 | @@ -48,6 +48,26 @@ FUNCTION(efi_wrap_1) 31 | addq $48, %rsp 32 | ret 33 | 34 | +FUNCTION(efi_call_foo) 35 | + pushq %rbp 36 | + pushq %r12 37 | + pushq %r13 38 | + pushq %r14 39 | + pushq %r15 40 | + movq %rsp, saved_sp(%rip) 41 | + subq $48, %rsp 42 | + mov %rsi, %rcx 43 | + call *%rdi 44 | + 45 | +FUNCTION(efi_shim_exit) 46 | + movq saved_sp(%rip), %rsp 47 | + popq %r15 48 | + popq %r14 49 | + popq %r13 50 | + popq %r12 51 | + popq %rbp 52 | + ret 53 | + 54 | FUNCTION(efi_wrap_2) 55 | subq $48, %rsp 56 | mov %rsi, %rcx 57 | @@ -127,3 +147,6 @@ FUNCTION(efi_wrap_10) 58 | call *%rdi 59 | addq $96, %rsp 60 | ret 61 | + 62 | + .data 63 | +saved_sp: .quad 0 64 | diff --git a/include/grub/efi/api.h b/include/grub/efi/api.h 65 | index 26127de..374d88b 100644 66 | --- a/include/grub/efi/api.h 67 | +++ b/include/grub/efi/api.h 68 | @@ -1437,6 +1437,10 @@ typedef struct grub_efi_block_io grub_efi_block_io_t; 69 | 70 | grub_uint64_t EXPORT_FUNC(efi_wrap_0) (void *func); 71 | grub_uint64_t EXPORT_FUNC(efi_wrap_1) (void *func, grub_uint64_t arg1); 72 | +grub_efi_status_t EXPORT_FUNC(efi_shim_exit) (grub_efi_handle_t handle, grub_efi_status_t exit_status, 73 | + grub_efi_uintn_t exit_data_size, grub_efi_char16_t *exit_data) __attribute__((noreturn)); 74 | +grub_uint64_t EXPORT_FUNC(efi_call_foo) (void *func, grub_uint64_t arg1, 75 | + grub_uint64_t arg2); 76 | grub_uint64_t EXPORT_FUNC(efi_wrap_2) (void *func, grub_uint64_t arg1, 77 | grub_uint64_t arg2); 78 | grub_uint64_t EXPORT_FUNC(efi_wrap_3) (void *func, grub_uint64_t arg1, 79 | -- 80 | 1.9.1 81 | 82 | -------------------------------------------------------------------------------- /recipes-bsp/grub/grub-efi/0004-efi-chainloader-port-shim-to-grub.patch: -------------------------------------------------------------------------------- 1 | From e097b4e25469aabdceac79c45cca27029824c1b5 Mon Sep 17 00:00:00 2001 2 | From: Ricardo Neri 3 | Date: Fri, 27 Mar 2015 08:19:21 -0700 4 | Subject: [PATCH 4/7] efi: chainloader: port shim to grub 5 | 6 | Upstream-Status: Inappropriate [embedded specific] 7 | 8 | Shim is a thin loader to execute signed binaries under the 9 | chain of trust of UEFI secure boot. Before executing the image, 10 | shim verifies that such image is signed with any of the Machine 11 | Owner Keys (MOKs). If the verification is successful, shim will 12 | load, parse, relocate and execute the image. 13 | 14 | Shim is useful in case the user does not want to modify the UEFI 15 | database of valid certificates (DB). 16 | 17 | This commit ports Matthew Garret's code from shim to grub in order 18 | to provide to grub the capability of load and execute trusted 19 | binaries. This is useful in case we need to chainload two bootloaders. 20 | 21 | Shim can be found here: https://github.com/rhinstaller/shim 22 | 23 | Signed-off-by: Ricardo Neri 24 | --- 25 | grub-core/loader/efi/chainloader.c | 534 +++++++++++++++++++++++++++++++++++++ 26 | 1 file changed, 534 insertions(+) 27 | 28 | diff --git a/grub-core/loader/efi/chainloader.c b/grub-core/loader/efi/chainloader.c 29 | index 3f3e6e3..bd83859 100644 30 | --- a/grub-core/loader/efi/chainloader.c 31 | +++ b/grub-core/loader/efi/chainloader.c 32 | @@ -32,6 +32,7 @@ 33 | #include 34 | #include 35 | #include 36 | +#include 37 | #include 38 | #include 39 | #include 40 | @@ -45,6 +46,539 @@ static grub_efi_uintn_t pages; 41 | static grub_efi_device_path_t *file_path; 42 | static grub_efi_handle_t image_handle; 43 | static grub_efi_char16_t *cmdline; 44 | +static grub_int32_t shim_used; 45 | +static grub_efi_physical_address_t shim_buffer; 46 | +static grub_efi_uintn_t shim_pages; 47 | +static grub_efi_loaded_image_t shim_li_bak; 48 | +static grub_efi_status_t (*shim_entry_point) (grub_efi_handle_t image_handle, 49 | + grub_efi_system_table_t *systab); 50 | + 51 | +static const grub_uint16_t 52 | +grub_shim_machine_type = 53 | +#if defined(__x86_64__) 54 | + GRUB_PE32_MACHINE_X86_64; 55 | +#elif defined(__aarch64__) 56 | + IMAGE_FILE_MACHINE_ARM64; 57 | +#elif defined(__arm__) 58 | + IMAGE_FILE_MACHINE_ARMTHUMB_MIXED; 59 | +#elif defined(__i386__) || defined(__i486__) || defined(__i686__) 60 | + GRUB_PE32_MACHINE_I386; 61 | +#elif defined(__ia64__) 62 | + GRUB_PE32_MACHINE_IA64; 63 | +#else 64 | +#error this architecture is not supported by shim chainloader 65 | +#endif 66 | + 67 | +static grub_efi_guid_t grub_shim_protocol_guid = GRUB_EFI_SHIM_PROTOCOL_GUID; 68 | + 69 | +static grub_int32_t 70 | +grub_shim_allow_64_bit (void) 71 | +{ 72 | +/* TODO: what is the definition for aarch64? */ 73 | +#if defined(__x86_64__) 74 | + return 1; 75 | +#elif defined(__i386__) || defined(__i686__) 76 | +/* TODO: find out what to do with in_protocol */ 77 | + return 0; 78 | +#else /* assuming everything else is 32-bit... */ 79 | + return 0; 80 | +#endif 81 | +} 82 | + 83 | +static grub_int32_t 84 | +grub_shim_allow_32_bit (void) 85 | +{ 86 | +/* TODO: what is the definition for aarch64? */ 87 | +#if defined(__x86_64__) 88 | +/* TODO: find out what to do with in_protocol */ 89 | + return 0; 90 | +#elif defined(__i386__) || defined(__i686__) 91 | + return 1; 92 | +#else /* assuming everything else is 32-bit... */ 93 | + return 1; 94 | +#endif 95 | +} 96 | + 97 | +static grub_int32_t 98 | +grub_shim_image_is_64_bit (union grub_shim_optional_header_union *pe_hdr) 99 | +{ 100 | + /* .Magic is the same offset in all cases */ 101 | + if (pe_hdr->pe32plus.opt_hdr.magic == GRUB_PE32_PE64_MAGIC) 102 | + return 1; 103 | + return 0; 104 | +} 105 | + 106 | +static grub_int32_t 107 | +grub_shim_image_is_loadable (union grub_shim_optional_header_union *pe_hdr) 108 | +{ 109 | + /* If the machine type doesn't match the binary, bail, unless 110 | + * we're in an allowed 64-on-32 scenario 111 | + */ 112 | + if (pe_hdr->pe32.file_hdr.machine != grub_shim_machine_type) 113 | + { 114 | + if (!(grub_shim_machine_type == GRUB_PE32_MACHINE_I386 115 | + && pe_hdr->pe32.file_hdr.machine == GRUB_PE32_MACHINE_X86_64 116 | + && grub_shim_allow_64_bit ())) 117 | + return 0; 118 | + } 119 | + 120 | + /* If it's not a header type we recognize at all, bail */ 121 | + switch (pe_hdr->pe32plus.opt_hdr.magic) 122 | + { 123 | + case GRUB_PE32_PE64_MAGIC: 124 | + case GRUB_PE32_PE32_MAGIC: 125 | + break; 126 | + default: 127 | + return 0; 128 | + } 129 | + 130 | + /* and now just check for general 64-vs-32 compatibility */ 131 | + if (grub_shim_image_is_64_bit(pe_hdr)) 132 | + { 133 | + if (grub_shim_allow_64_bit ()) 134 | + return 1; 135 | + } 136 | + else 137 | + { 138 | + if (grub_shim_allow_32_bit ()) 139 | + return 1; 140 | + } 141 | + return 0; 142 | +} 143 | + 144 | +/* 145 | + * Perform basic bounds checking of the intra-image pointers 146 | + */ 147 | +static grub_efi_uint64_t 148 | +grub_shim_image_address (grub_addr_t image, grub_uint32_t size, grub_uint32_t addr) 149 | +{ 150 | + if (addr > size) 151 | + return 0; 152 | + return image + addr; 153 | +} 154 | + 155 | +/* 156 | + * Perform the actual relocation 157 | + */ 158 | +static grub_err_t 159 | +grub_shim_relocate_coff (struct grub_shim_pe_coff_loader_image_context *context, 160 | + void *orig, void *data) 161 | +{ 162 | + struct grub_image_base_relocation *reloc_base, *reloc_base_end; 163 | + grub_efi_uint64_t adjust; 164 | + grub_efi_uint16_t *reloc, *reloc_end; 165 | + grub_uint8_t *fixup, *fixup_base, *fixup_data = NULL; 166 | + grub_efi_uint16_t *fixup16; 167 | + grub_efi_uint32_t *fixup32; 168 | + grub_efi_uint64_t *fixup64; 169 | + grub_int32_t size = context->image_size; 170 | + void *image_end = (char *)orig + size; 171 | + 172 | + if (grub_shim_image_is_64_bit(context->pe_hdr)) 173 | + context->pe_hdr->pe32plus.opt_hdr.image_base = (grub_efi_uint64_t)(unsigned long)data; 174 | + else 175 | + context->pe_hdr->pe32.opt_hdr.image_base = (grub_efi_uint32_t)(unsigned long)data; 176 | + 177 | + reloc_base = (struct grub_image_base_relocation *) 178 | + grub_shim_image_address ((grub_efi_uint64_t)orig, size, 179 | + context->reloc_dir->rva); 180 | + reloc_base_end = (struct grub_image_base_relocation *) 181 | + grub_shim_image_address ((grub_efi_uint64_t)orig, size, 182 | + context->reloc_dir->rva 183 | + + context->reloc_dir->size - 1); 184 | + 185 | + if (!reloc_base || !reloc_base_end) 186 | + { 187 | + grub_printf("Reloc table overflows binary\n"); 188 | + return GRUB_ERR_BAD_FILE_TYPE; 189 | + } 190 | + 191 | + adjust = (grub_efi_uintn_t)data - context->image_address; 192 | + 193 | + if (adjust == 0) 194 | + return GRUB_EFI_SUCCESS; 195 | + 196 | + while (reloc_base < reloc_base_end) 197 | + { 198 | + reloc = (grub_efi_uint16_t *) ((grub_int8_t *) reloc_base 199 | + + sizeof (struct grub_image_base_relocation)); 200 | + 201 | + if ((reloc_base->block_size == 0) 202 | + || (reloc_base->block_size > context->reloc_dir->size)) 203 | + { 204 | + grub_printf("Reloc block size %d is invalid\n", reloc_base->block_size); 205 | + return GRUB_ERR_FILE_READ_ERROR; 206 | + } 207 | + 208 | + reloc_end = (grub_efi_uint16_t *) 209 | + ((grub_uint8_t *) reloc_base + reloc_base->block_size); 210 | + if ((void *)reloc_end < orig || (void *)reloc_end > image_end) 211 | + { 212 | + grub_printf("Reloc entry overflows binary\n"); 213 | + return GRUB_ERR_FILE_READ_ERROR; 214 | + } 215 | + 216 | + fixup_base = (grub_uint8_t *) 217 | + grub_shim_image_address ((grub_efi_uint64_t)data, 218 | + size, 219 | + reloc_base->virtual_address); 220 | + if (!fixup_base) 221 | + { 222 | + grub_printf("Invalid fixup_base\n"); 223 | + return GRUB_ERR_FILE_READ_ERROR; 224 | + } 225 | + 226 | + while (reloc < reloc_end) 227 | + { 228 | + fixup = fixup_base + (*reloc & 0xFFF); 229 | + switch ((*reloc) >> 12) 230 | + { 231 | + case EFI_IMAGE_REL_BASED_ABSOLUTE: 232 | + break; 233 | + 234 | + case EFI_IMAGE_REL_BASED_HIGH: 235 | + fixup16 = (grub_efi_uint16_t *) fixup; 236 | + *fixup16 = (grub_efi_uint16_t) 237 | + (*fixup16 238 | + + ((grub_efi_uint16_t) ((grub_efi_uint32_t) adjust >> 16))); 239 | + if (fixup_data != NULL) 240 | + { 241 | + *(grub_efi_uint16_t *) fixup_data = *fixup16; 242 | + fixup_data = fixup_data + sizeof (grub_efi_uint16_t); 243 | + } 244 | + break; 245 | + 246 | + case EFI_IMAGE_REL_BASED_LOW: 247 | + fixup16 = (grub_efi_uint16_t *) fixup; 248 | + *fixup16 = (grub_efi_uint16_t) 249 | + (*fixup16 + (grub_efi_uint16_t) adjust); 250 | + if (fixup_data != NULL) 251 | + { 252 | + *(grub_efi_uint16_t *) fixup_data = *fixup16; 253 | + fixup_data = fixup_data + sizeof (grub_efi_uint16_t); 254 | + } 255 | + break; 256 | + 257 | + case EFI_IMAGE_REL_BASED_HIGHLOW: 258 | + fixup32 = (grub_efi_uint32_t *) fixup; 259 | + *fixup32 = *fixup32 + (grub_efi_uint32_t) adjust; 260 | + if (fixup_data != NULL) 261 | + { 262 | + fixup_data = ALIGN_POINTER (fixup_data, sizeof (grub_efi_uint32_t)); 263 | + *(grub_efi_uint32_t *)fixup_data = *fixup32; 264 | + fixup_data = fixup_data + sizeof (grub_efi_uint32_t); 265 | + } 266 | + break; 267 | + 268 | + case EFI_IMAGE_REL_BASED_DIR64: 269 | + fixup64 = (grub_efi_uint64_t *) fixup; 270 | + *fixup64 = *fixup64 + (grub_efi_uint64_t) adjust; 271 | + if (fixup_data != NULL) 272 | + { 273 | + fixup_data = ALIGN_POINTER (fixup_data, sizeof(grub_efi_uint64_t)); 274 | + *(grub_efi_uint64_t *)(fixup_data) = *fixup64; 275 | + fixup_data = fixup_data + sizeof(grub_efi_uint64_t); 276 | + } 277 | + break; 278 | + 279 | + default: 280 | + grub_printf("Unknown relocation\n"); 281 | + return GRUB_ERR_FILE_READ_ERROR; 282 | + } 283 | + reloc += 1; 284 | + } 285 | + reloc_base = (struct grub_image_base_relocation *) reloc_end; 286 | + } 287 | + 288 | + return GRUB_EFI_SUCCESS; 289 | +} 290 | + 291 | +/* 292 | + * Read the binary header and grab appropriate information from it 293 | + */ 294 | +static grub_err_t 295 | +grub_shim_read_header(grub_efi_physical_address_t data, grub_uint32_t datasize, 296 | + struct grub_shim_pe_coff_loader_image_context *context) 297 | +{ 298 | + struct grub_dos_header *dos_hdr = (struct grub_dos_header *)data; 299 | + union grub_shim_optional_header_union *pe_hdr = (union grub_shim_optional_header_union *)data; 300 | + grub_uint64_t header_without_data_dir, section_header_offset, opt_hdr_size; 301 | + 302 | + if (datasize < sizeof (pe_hdr->pe32)) 303 | + { 304 | + grub_printf("Invalid image\n"); 305 | + return GRUB_ERR_BAD_FILE_TYPE; 306 | + } 307 | + 308 | + if (dos_hdr->magic == EFI_IMAGE_DOS_SIGNATURE) 309 | + pe_hdr = (union grub_shim_optional_header_union *)((grub_uint8_t *)data 310 | + + dos_hdr->lfanew); 311 | + 312 | + if (!grub_shim_image_is_loadable(pe_hdr)) 313 | + { 314 | + grub_printf("Platform does not support this image\n"); 315 | + return GRUB_ERR_BAD_FILE_TYPE; 316 | + } 317 | + 318 | + if (grub_shim_image_is_64_bit(pe_hdr)) 319 | + { 320 | + context->number_of_rva_and_sizes = pe_hdr->pe32plus.opt_hdr.num_data_directories; 321 | + context->header_size = pe_hdr->pe32plus.opt_hdr.header_size; 322 | + context->image_size = pe_hdr->pe32plus.opt_hdr.image_size; 323 | + opt_hdr_size = sizeof(struct grub_pe64_optional_header); 324 | + } else 325 | + { 326 | + context->number_of_rva_and_sizes = pe_hdr->pe32.opt_hdr.num_data_directories; 327 | + context->header_size = pe_hdr->pe32.opt_hdr.header_size; 328 | + context->image_size = (grub_efi_uint64_t)pe_hdr->pe32.opt_hdr.header_size; 329 | + opt_hdr_size = sizeof(struct grub_pe32_optional_header); 330 | + } 331 | + 332 | + context->num_sections = pe_hdr->pe32.file_hdr.num_sections; 333 | + 334 | + if (GRUB_PE32_NUM_DATA_DIRECTORIES < context->number_of_rva_and_sizes) 335 | + { 336 | + grub_printf("Image header too small\n"); 337 | + return GRUB_ERR_FILE_READ_ERROR; 338 | + } 339 | + 340 | + header_without_data_dir = opt_hdr_size 341 | + - sizeof (struct grub_pe32_data_directory) 342 | + * GRUB_PE32_NUM_DATA_DIRECTORIES; 343 | + if (((grub_efi_uint32_t)pe_hdr->pe32.file_hdr.optional_header_size 344 | + - header_without_data_dir) != 345 | + context->number_of_rva_and_sizes * sizeof (struct grub_pe32_data_directory)) 346 | + { 347 | + grub_printf("Image header overflows data directory\n"); 348 | + return GRUB_ERR_FILE_READ_ERROR; 349 | + } 350 | + 351 | + section_header_offset = dos_hdr->lfanew 352 | + + sizeof (grub_efi_uint32_t) 353 | + + sizeof (struct grub_pe32_coff_header) 354 | + + pe_hdr->pe32.file_hdr.optional_header_size; 355 | + if (((grub_efi_uint32_t)context->image_size - section_header_offset) 356 | + / sizeof (struct grub_pe32_section_table) 357 | + <= context->num_sections) 358 | + { 359 | + grub_printf("Image sections overflow image size\n"); 360 | + return GRUB_ERR_FILE_READ_ERROR; 361 | + } 362 | + 363 | + if ((context->header_size - section_header_offset) 364 | + / sizeof (struct grub_pe32_section_table) 365 | + < (grub_efi_uint32_t)context->num_sections) 366 | + { 367 | + grub_printf("Image sections overflow section headers\n"); 368 | + return GRUB_ERR_FILE_READ_ERROR; 369 | + } 370 | + 371 | + if ((((grub_efi_uint8_t *)pe_hdr 372 | + - (grub_efi_uint8_t *)data) 373 | + + sizeof(union grub_shim_optional_header_union )) > datasize) 374 | + { 375 | + grub_printf("Invalid image\n"); 376 | + return GRUB_ERR_BAD_FILE_TYPE; 377 | + } 378 | + 379 | + if (pe_hdr->te.signature != EFI_IMAGE_NT_SIGNATURE) 380 | + { 381 | + grub_printf("Unsupported image type\n"); 382 | + return GRUB_ERR_BAD_FILE_TYPE; 383 | + } 384 | + 385 | + if (pe_hdr->pe32.file_hdr.characteristics & GRUB_PE32_RELOCS_STRIPPED) 386 | + { 387 | + grub_printf("Unsupported image - Relocations have been stripped\n"); 388 | + return GRUB_ERR_BAD_FILE_TYPE; 389 | + } 390 | + 391 | + context->pe_hdr = pe_hdr; 392 | + 393 | + if (grub_shim_image_is_64_bit(pe_hdr)) 394 | + { 395 | + context->image_address = pe_hdr->pe32plus.opt_hdr.image_base; 396 | + context->entry_point = pe_hdr->pe32plus.opt_hdr.entry_addr; 397 | + context->reloc_dir = &pe_hdr->pe32plus.opt_hdr.base_relocation_table; 398 | + context->sec_dir = &pe_hdr->pe32plus.opt_hdr.certificate_table; 399 | + } else 400 | + { 401 | + context->image_address = pe_hdr->pe32.opt_hdr.image_base; 402 | + context->entry_point = pe_hdr->pe32.opt_hdr.entry_addr; 403 | + context->reloc_dir = &pe_hdr->pe32.opt_hdr.base_relocation_table; 404 | + context->sec_dir = &pe_hdr->pe32.opt_hdr.certificate_table; 405 | + } 406 | + 407 | + context->first_section = (struct grub_pe32_section_table *) 408 | + ((char *)pe_hdr 409 | + + pe_hdr->pe32.file_hdr.optional_header_size 410 | + + sizeof(grub_efi_uint32_t) 411 | + + sizeof(struct grub_pe32_coff_header)); 412 | + 413 | + if (context->image_size < context->header_size) 414 | + { 415 | + grub_printf("Invalid image\n"); 416 | + return GRUB_ERR_BAD_FILE_TYPE; 417 | + } 418 | + 419 | + if ((unsigned long)((grub_efi_uint8_t *)context->sec_dir - (grub_efi_uint8_t *)data) > 420 | + (datasize - sizeof(struct grub_pe32_data_directory))) 421 | + { 422 | + grub_printf("Invalid image\n"); 423 | + return GRUB_ERR_BAD_FILE_TYPE; 424 | + } 425 | + 426 | + if (context->sec_dir->rva >= datasize) 427 | + { 428 | + grub_printf("Malformed security header\n"); 429 | + return GRUB_ERR_BAD_FILE_TYPE; 430 | + } 431 | + return GRUB_ERR_NONE; 432 | +} 433 | + 434 | +static grub_efi_status_t 435 | +grub_shim_verify (grub_addr_t addr, grub_ssize_t size) 436 | +{ 437 | + struct grub_shim_lock *shim_lock; 438 | + shim_lock = grub_efi_locate_protocol (&grub_shim_protocol_guid, 0); 439 | + if (!shim_lock) 440 | + { 441 | + grub_error (GRUB_ERR_BAD_OS, "could not load shim protocol"); 442 | + return GRUB_EFI_UNSUPPORTED; 443 | + } 444 | + 445 | + return shim_lock->verify((void *) addr, size); 446 | +} 447 | + 448 | +static grub_err_t 449 | +grub_shim_load_image(grub_addr_t addr, grub_ssize_t size, 450 | + struct grub_shim_pe_coff_loader_image_context *context) 451 | +{ 452 | + grub_err_t status; 453 | + grub_efi_status_t efi_status; 454 | + grub_uint32_t sect_size; 455 | + /* TODO: can they be unsigned? */ 456 | + grub_int8_t *base, *end; 457 | + grub_int32_t i; 458 | + struct grub_pe32_section_table *section; 459 | + grub_efi_boot_services_t *b; 460 | + 461 | + shim_used = 0; 462 | + shim_buffer = 0; 463 | + 464 | + status = grub_shim_verify (addr, size); 465 | + if (status != GRUB_ERR_NONE) 466 | + { 467 | + grub_error (GRUB_ERR_BAD_OS, "shim verification failed"); 468 | + return GRUB_ERR_BAD_OS; 469 | + } 470 | + 471 | + grub_memset(context, 0, sizeof(*context)); 472 | + status = grub_shim_read_header (addr, size, context); 473 | + if (status != GRUB_ERR_NONE) 474 | + { 475 | + grub_error (GRUB_ERR_BAD_OS, "read header failed"); 476 | + return GRUB_ERR_BAD_OS; 477 | + } 478 | + 479 | + /* TODO: do we need to do this with efi_allocate? */ 480 | + shim_pages = (((grub_efi_uintn_t) context->image_size + ((1 << 12) - 1)) >> 12); 481 | + 482 | + b = grub_efi_system_table->boot_services; 483 | + efi_status = efi_call_4 (b->allocate_pages, GRUB_EFI_ALLOCATE_ANY_PAGES, 484 | + GRUB_EFI_LOADER_CODE, shim_pages, &shim_buffer); 485 | + if (efi_status != GRUB_EFI_SUCCESS) 486 | + { 487 | + grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory for shim buffer")); 488 | + return GRUB_ERR_OUT_OF_MEMORY; 489 | + } 490 | + 491 | + /* TODO: do we need the double cast? */ 492 | + grub_memcpy ((void *) ((grub_efi_physical_address_t) shim_buffer), 493 | + (void *) ((grub_addr_t) addr), context->header_size); 494 | + /* 495 | + * Copy the executable's sections to their desired offsets 496 | + */ 497 | + section = context->first_section; 498 | + for (i = 0; i < context->num_sections; i++, section++) 499 | + { 500 | + if (section->characteristics & 0x02000000) 501 | + /* section has EFI_IMAGE_SCN_MEM_DISCARDABLE attr set */ 502 | + continue; 503 | + 504 | + sect_size = section->virtual_size; 505 | + 506 | + if (sect_size > section->raw_data_size) 507 | + sect_size = section->raw_data_size; 508 | + 509 | + base = (grub_int8_t *) 510 | + grub_shim_image_address (shim_buffer, context->image_size, 511 | + section->virtual_address); 512 | + end = (grub_int8_t *) 513 | + grub_shim_image_address (shim_buffer, context->image_size, 514 | + section->virtual_address 515 | + + sect_size - 1); 516 | + if (!base || !end) 517 | + { 518 | + grub_printf("Invalid section base\n"); 519 | + status = GRUB_ERR_BAD_FILE_TYPE; 520 | + goto fail; 521 | + } 522 | + 523 | + if (section->virtual_address < context->header_size 524 | + || section->raw_data_offset < context->header_size) 525 | + { 526 | + grub_printf("Section is inside image headers\n"); 527 | + status = GRUB_ERR_BAD_FILE_TYPE; 528 | + goto fail; 529 | + } 530 | + 531 | + if (section->raw_data_size > 0) 532 | + /* TODO: do we need the double cast? */ 533 | + grub_memcpy ((void *)base, 534 | + (void *) (((grub_addr_t) addr) 535 | + + section->raw_data_offset), sect_size); 536 | + 537 | + if (sect_size < section->virtual_size) 538 | + grub_memset ((void *)(base + sect_size), 0, 539 | + section->virtual_size - sect_size); 540 | + } 541 | + 542 | + if (context->number_of_rva_and_sizes <= EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC) 543 | + { 544 | + grub_printf("Image has no relocation entry\n"); 545 | + status = GRUB_ERR_BAD_FILE_TYPE; 546 | + goto fail; 547 | + } 548 | + 549 | + if (context->reloc_dir->size) 550 | + { 551 | + status = grub_shim_relocate_coff (context, (void *) addr, 552 | + (void *) shim_buffer); 553 | + if (status != GRUB_ERR_NONE) 554 | + { 555 | + grub_printf("Relocation failed: [%u]\n", status); 556 | + status = GRUB_ERR_BAD_FILE_TYPE; 557 | + goto fail; 558 | + } 559 | + } 560 | + shim_entry_point = (void *)grub_shim_image_address (shim_buffer, 561 | + context->image_size, 562 | + context->entry_point); 563 | + if (!shim_entry_point) 564 | + { 565 | + grub_printf("Invalid entry point\n"); 566 | + status = GRUB_ERR_BAD_FILE_TYPE; 567 | + goto fail; 568 | + } 569 | + 570 | + shim_used = 1; 571 | + return GRUB_ERR_NONE; 572 | +fail: 573 | + efi_call_2 (b->free_pages, shim_buffer, shim_pages); 574 | + shim_buffer = 0; 575 | + return status; 576 | +} 577 | 578 | static grub_err_t 579 | grub_chainloader_unload (void) 580 | -- 581 | 1.9.1 582 | 583 | -------------------------------------------------------------------------------- /recipes-bsp/grub/grub-efi/0005-efi-chainloader-use-shim-to-load-and-verify-an-image.patch: -------------------------------------------------------------------------------- 1 | From f922ac74714d01972a3c291e15f0c316b67e40eb Mon Sep 17 00:00:00 2001 2 | From: Ricardo Neri 3 | Date: Fri, 27 Mar 2015 08:26:08 -0700 4 | Subject: [PATCH 5/7] efi: chainloader: use shim to load and verify an image 5 | 6 | Upstream-Status: Inappropriate [embedded specific] 7 | 8 | The grub chainloader module uses the UEFI LoadImage service 9 | to load a chainloaded binary. However, if such binary is not 10 | signed by the UEFI certification authority, LoadImage will fail. 11 | Under shim, we can use Machine-Owned Keys (MOKs) to verify an 12 | image. Thus, in case LoadImage fails due to a security violation 13 | we rely on the shim verification service. If successful, the 14 | image is parsed and loaded. 15 | 16 | Signed-off-by: Ricardo Neri 17 | --- 18 | grub-core/loader/efi/chainloader.c | 49 +++++++++++++++++++++++++++++++------- 19 | 1 file changed, 40 insertions(+), 9 deletions(-) 20 | 21 | diff --git a/grub-core/loader/efi/chainloader.c b/grub-core/loader/efi/chainloader.c 22 | index bd83859..01d2ebe 100644 23 | --- a/grub-core/loader/efi/chainloader.c 24 | +++ b/grub-core/loader/efi/chainloader.c 25 | @@ -733,6 +733,7 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)), 26 | grub_efi_loaded_image_t *loaded_image; 27 | char *filename; 28 | grub_efi_handle_t dev_handle = 0; 29 | + struct grub_shim_pe_coff_loader_image_context context; 30 | 31 | if (argc == 0) 32 | return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected")); 33 | @@ -827,23 +828,53 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)), 34 | if (status != GRUB_EFI_SUCCESS) 35 | { 36 | if (status == GRUB_EFI_OUT_OF_RESOURCES) 37 | - grub_error (GRUB_ERR_OUT_OF_MEMORY, "out of resources"); 38 | + { 39 | + grub_error (GRUB_ERR_OUT_OF_MEMORY, "out of resources"); 40 | + goto fail; 41 | + } 42 | + /* try with shim */ 43 | + else if (status == GRUB_EFI_SECURITY_VIOLATION) 44 | + { 45 | + status = grub_shim_load_image (address, size, &context); 46 | + if (status != GRUB_EFI_SUCCESS) 47 | + { 48 | + grub_error (GRUB_ERR_BAD_OS, "shim cannot load image"); 49 | + goto fail; 50 | + } 51 | + } 52 | else 53 | - grub_error (GRUB_ERR_BAD_OS, "cannot load image"); 54 | - 55 | - goto fail; 56 | + { 57 | + grub_error (GRUB_ERR_BAD_OS, "cannot load image"); 58 | + goto fail; 59 | + } 60 | } 61 | 62 | - /* LoadImage does not set a device handler when the image is 63 | - loaded from memory, so it is necessary to set it explicitly here. 64 | - This is a mess. */ 65 | - loaded_image = grub_efi_get_loaded_image (image_handle); 66 | + /* if we use shim, the UEFI load_image failed, thus, we borrow 67 | + * grub_efi_image_handle and restore it later 68 | + */ 69 | + if (shim_used) 70 | + /* if we use shim, the UEFI load_image failed, thus, we borrow 71 | + grub_efi_image_handle and restore it later */ 72 | + loaded_image = grub_efi_get_loaded_image (grub_efi_image_handle); 73 | + else 74 | + /* LoadImage does not set a device handler when the image is 75 | + loaded from memory, so it is necessary to set it explicitly here. 76 | + This is a mess. */ 77 | + loaded_image = grub_efi_get_loaded_image (image_handle); 78 | + 79 | if (! loaded_image) 80 | { 81 | grub_error (GRUB_ERR_BAD_OS, "no loaded image available"); 82 | goto fail; 83 | } 84 | - loaded_image->device_handle = dev_handle; 85 | + if (shim_used) 86 | + { 87 | + grub_memcpy(&shim_li_bak, loaded_image, sizeof(shim_li_bak)); 88 | + loaded_image->image_base = (void *)shim_buffer; 89 | + loaded_image->image_size = context.image_size; 90 | + } 91 | + else 92 | + loaded_image->device_handle = dev_handle; 93 | 94 | grub_file_close (file); 95 | 96 | -- 97 | 1.9.1 98 | 99 | -------------------------------------------------------------------------------- /recipes-bsp/grub/grub-efi/0006-efi-chainloader-boot-the-image-using-shim.patch: -------------------------------------------------------------------------------- 1 | From f25778620360ccff55f3d9c1bccba14249978502 Mon Sep 17 00:00:00 2001 2 | From: Ricardo Neri 3 | Date: Fri, 27 Mar 2015 08:29:13 -0700 4 | Subject: [PATCH 6/7] efi: chainloader: boot the image using shim 5 | 6 | Upstream-Status: Inappropriate [embedded specific] 7 | 8 | If the image was loaded using shim, boot the image. Given that 9 | shim loaded the image, the UEFI firmware will not know where to 10 | jump after the execution completes. Thus, replace the UEFI boot 11 | service Exit with our own implementation to make sure we jump 12 | to the instruction after the call to the entry point. 13 | 14 | Replace the system Exit service when done. 15 | 16 | Signed-off-by: Ricardo Neri 17 | --- 18 | grub-core/loader/efi/chainloader.c | 27 ++++++++++++++++++++++++++- 19 | 1 file changed, 26 insertions(+), 1 deletion(-) 20 | 21 | diff --git a/grub-core/loader/efi/chainloader.c b/grub-core/loader/efi/chainloader.c 22 | index 01d2ebe..1c9795c 100644 23 | --- a/grub-core/loader/efi/chainloader.c 24 | +++ b/grub-core/loader/efi/chainloader.c 25 | @@ -605,9 +605,34 @@ grub_chainloader_boot (void) 26 | grub_efi_status_t status; 27 | grub_efi_uintn_t exit_data_size; 28 | grub_efi_char16_t *exit_data = NULL; 29 | + grub_efi_loaded_image_t *loaded_image = NULL; 30 | + grub_efi_status_t 31 | + (*saved_exit) (grub_efi_handle_t image_handle, 32 | + grub_efi_status_t exit_status, 33 | + grub_efi_uintn_t exit_data_size, 34 | + grub_efi_char16_t *exit_data) __attribute__((noreturn)); 35 | 36 | b = grub_efi_system_table->boot_services; 37 | - status = efi_call_3 (b->start_image, image_handle, &exit_data_size, &exit_data); 38 | + 39 | + if (!shim_used) 40 | + status = efi_call_3 (b->start_image, image_handle, &exit_data_size, &exit_data); 41 | + else 42 | + { 43 | + saved_exit = grub_efi_system_table->boot_services->exit; 44 | + grub_efi_system_table->boot_services->exit = efi_shim_exit; 45 | + status = efi_call_foo(shim_entry_point, 46 | + (grub_efi_uint64_t)grub_efi_image_handle, 47 | + (grub_efi_uint64_t)grub_efi_system_table); 48 | + grub_efi_system_table->boot_services->exit = saved_exit; 49 | + 50 | + loaded_image = grub_efi_get_loaded_image (grub_efi_image_handle); 51 | + if (!loaded_image) 52 | + /* TODO: this is serious, what to do? */ 53 | + grub_error (GRUB_ERR_BAD_OS, "GRUB loaded image not found"); 54 | + else 55 | + /* restore loaded image */ 56 | + grub_memcpy(loaded_image, &shim_li_bak, sizeof(shim_li_bak)); 57 | + } 58 | if (status != GRUB_EFI_SUCCESS) 59 | { 60 | if (exit_data) 61 | -- 62 | 1.9.1 63 | 64 | -------------------------------------------------------------------------------- /recipes-bsp/grub/grub-efi/0007-efi-chainloader-take-care-of-unload-undershim.patch: -------------------------------------------------------------------------------- 1 | From 70a30826d1cfb7a90c34760896dfd92b9c396f52 Mon Sep 17 00:00:00 2001 2 | From: Ricardo Neri 3 | Date: Fri, 27 Mar 2015 08:31:27 -0700 4 | Subject: [PATCH 7/7] efi: chainloader: take care of unload undershim 5 | 6 | Upstream-Status: Inappropriate [embedded specific] 7 | 8 | Under shim, we use a custom buffer to put the relocated image, make 9 | sure we free that memory when unloading. 10 | 11 | Signed-off-by: Ricardo Neri 12 | --- 13 | grub-core/loader/efi/chainloader.c | 14 ++++++++++++-- 14 | 1 file changed, 12 insertions(+), 2 deletions(-) 15 | 16 | diff --git a/grub-core/loader/efi/chainloader.c b/grub-core/loader/efi/chainloader.c 17 | index 1c9795c..d0ceb6e 100644 18 | --- a/grub-core/loader/efi/chainloader.c 19 | +++ b/grub-core/loader/efi/chainloader.c 20 | @@ -586,8 +586,18 @@ grub_chainloader_unload (void) 21 | grub_efi_boot_services_t *b; 22 | 23 | b = grub_efi_system_table->boot_services; 24 | - efi_call_1 (b->unload_image, image_handle); 25 | - efi_call_2 (b->free_pages, address, pages); 26 | + if (!shim_used) 27 | + { 28 | + efi_call_1 (b->unload_image, image_handle); 29 | + efi_call_2 (b->free_pages, address, pages); 30 | + } 31 | + else 32 | + { 33 | + if (shim_buffer) 34 | + { 35 | + efi_call_2 (b->free_pages, shim_buffer, shim_pages); 36 | + } 37 | + } 38 | 39 | grub_free (file_path); 40 | grub_free (cmdline); 41 | -- 42 | 1.9.1 43 | 44 | -------------------------------------------------------------------------------- /recipes-bsp/grub/grub-efi/Fix-32-bit-build-failures.patch: -------------------------------------------------------------------------------- 1 | From e7b2efacc2d3acb48761aa2d62f943310fd70100 Mon Sep 17 00:00:00 2001 2 | From: Lans Zhang 3 | Date: Mon, 25 Apr 2016 11:35:14 +0800 4 | Subject: [PATCH] Fix 32-bit build failures 5 | 6 | Upstream-Status: Pending 7 | 8 | For 32-bit build, the 64-bit pointer should be replaced by grub_addr_t 9 | which is compatible between 32-bit and 64-bit build. 10 | 11 | In addition, the functions efi_shim_exit and efi_call_foo should be available 12 | for 32-bit build. 13 | 14 | Signed-off-by: Lans Zhang 15 | --- 16 | grub-core/Makefile.core.def | 1 + 17 | grub-core/kern/i386/efi/callwrap.S | 50 ++++++++++++++++++++++++++++++++++++++ 18 | grub-core/loader/efi/chainloader.c | 30 +++++++++++------------ 19 | include/grub/efi/api.h | 8 +++--- 20 | include/grub/efi/shim.h | 2 +- 21 | 5 files changed, 71 insertions(+), 20 deletions(-) 22 | create mode 100644 grub-core/kern/i386/efi/callwrap.S 23 | 24 | diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def 25 | index 39e77a4..0a78137 100644 26 | --- a/grub-core/Makefile.core.def 27 | +++ b/grub-core/Makefile.core.def 28 | @@ -135,6 +135,7 @@ kernel = { 29 | efi = term/efi/console.c; 30 | 31 | i386_efi = kern/i386/tsc.c; 32 | + i386_efi = kern/i386/efi/callwrap.S; 33 | i386_efi = kern/i386/efi/init.c; 34 | i386_efi = bus/pci.c; 35 | 36 | diff --git a/grub-core/kern/i386/efi/callwrap.S b/grub-core/kern/i386/efi/callwrap.S 37 | new file mode 100644 38 | index 0000000..c683444 39 | --- /dev/null 40 | +++ b/grub-core/kern/i386/efi/callwrap.S 41 | @@ -0,0 +1,50 @@ 42 | +/* callwrap.S - wrapper for i386 efi calls */ 43 | +/* 44 | + * GRUB -- GRand Unified Bootloader 45 | + * Copyright (C) 2006,2007,2009 Free Software Foundation, Inc. 46 | + * 47 | + * GRUB is free software: you can redistribute it and/or modify 48 | + * it under the terms of the GNU General Public License as published by 49 | + * the Free Software Foundation, either version 3 of the License, or 50 | + * (at your option) any later version. 51 | + * 52 | + * GRUB is distributed in the hope that it will be useful, 53 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of 54 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 55 | + * GNU General Public License for more details. 56 | + * 57 | + * You should have received a copy of the GNU General Public License 58 | + * along with GRUB. If not, see . 59 | + */ 60 | + 61 | +#include 62 | +#include 63 | + 64 | + .file "callwrap.S" 65 | + .text 66 | + 67 | +FUNCTION(efi_call_foo) 68 | + movl 12(%esp), %eax 69 | + movl 8(%esp), %edx 70 | + movl 4(%esp), %ecx 71 | + pushl %ebx 72 | + pushl %esi 73 | + pushl %edi 74 | + pushl %ebp 75 | + movl %esp, saved_sp 76 | + subl $40, %esp 77 | + pushl %eax 78 | + pushl %edx 79 | + call *%ecx 80 | + 81 | +FUNCTION(efi_shim_exit) 82 | + addl $48, %esp 83 | + movl saved_sp, %esp 84 | + popl %ebp 85 | + popl %edi 86 | + popl %esi 87 | + popl %ebx 88 | + ret 89 | + 90 | + .data 91 | +saved_sp: .long 0 92 | diff --git a/grub-core/loader/efi/chainloader.c b/grub-core/loader/efi/chainloader.c 93 | index 83769a2..e3d1138 100644 94 | --- a/grub-core/loader/efi/chainloader.c 95 | +++ b/grub-core/loader/efi/chainloader.c 96 | @@ -149,7 +149,7 @@ grub_shim_image_is_loadable (union grub_shim_optional_header_union *pe_hdr) 97 | /* 98 | * Perform basic bounds checking of the intra-image pointers 99 | */ 100 | -static grub_efi_uint64_t 101 | +static grub_addr_t 102 | grub_shim_image_address (grub_addr_t image, grub_uint32_t size, grub_uint32_t addr) 103 | { 104 | if (addr > size) 105 | @@ -208,12 +208,12 @@ grub_shim_relocate_coff (struct grub_shim_pe_coff_loader_image_context *context, 106 | * yield the next entry in the array. 107 | */ 108 | reloc_base = (struct grub_image_base_relocation *) 109 | - grub_shim_image_address ((grub_efi_uint64_t)orig, size, 110 | + grub_shim_image_address ((grub_addr_t)orig, size, 111 | section->raw_data_offset); 112 | /* reloc_base_end is the address of the first entry /past/ the 113 | * table. */ 114 | reloc_base_end = (struct grub_image_base_relocation *) 115 | - grub_shim_image_address ((grub_efi_uint64_t)orig, size, 116 | + grub_shim_image_address ((grub_addr_t)orig, size, 117 | section->raw_data_offset 118 | + section->virtual_size - 1); 119 | 120 | @@ -254,7 +254,7 @@ grub_shim_relocate_coff (struct grub_shim_pe_coff_loader_image_context *context, 121 | } 122 | 123 | fixup_base = (grub_uint8_t *) 124 | - grub_shim_image_address ((grub_efi_uint64_t)data, 125 | + grub_shim_image_address ((grub_addr_t)data, 126 | size, 127 | reloc_base->virtual_address); 128 | if (!fixup_base) 129 | @@ -333,12 +333,12 @@ grub_shim_relocate_coff (struct grub_shim_pe_coff_loader_image_context *context, 130 | * Read the binary header and grab appropriate information from it 131 | */ 132 | static grub_err_t 133 | -grub_shim_read_header(grub_efi_physical_address_t data, grub_uint32_t datasize, 134 | +grub_shim_read_header(grub_addr_t data, grub_uint32_t datasize, 135 | struct grub_shim_pe_coff_loader_image_context *context) 136 | { 137 | struct grub_dos_header *dos_hdr = (struct grub_dos_header *)data; 138 | union grub_shim_optional_header_union *pe_hdr = (union grub_shim_optional_header_union *)data; 139 | - grub_uint64_t header_without_data_dir, section_header_offset, opt_hdr_size; 140 | + grub_efi_uintn_t header_without_data_dir, section_header_offset, opt_hdr_size; 141 | 142 | if (datasize < sizeof (pe_hdr->pe32)) 143 | { 144 | @@ -393,7 +393,7 @@ grub_shim_read_header(grub_efi_physical_address_t data, grub_uint32_t datasize, 145 | + sizeof (grub_efi_uint32_t) 146 | + sizeof (struct grub_pe32_coff_header) 147 | + pe_hdr->pe32.file_hdr.optional_header_size; 148 | - if (((grub_efi_uint32_t)context->image_size - section_header_offset) 149 | + if ((context->image_size - section_header_offset) 150 | / sizeof (struct grub_pe32_section_table) 151 | <= context->num_sections) 152 | { 153 | @@ -530,7 +530,7 @@ grub_shim_load_image(grub_addr_t addr, grub_ssize_t size, 154 | } 155 | 156 | /* TODO: do we need the double cast? */ 157 | - grub_memcpy ((void *) ((grub_efi_physical_address_t) shim_buffer), 158 | + grub_memcpy ((void *) ((grub_addr_t) shim_buffer), 159 | (void *) ((grub_addr_t) addr), context->header_size); 160 | 161 | reloc_base = (grub_int8_t *) grub_shim_image_address (shim_buffer, size, 162 | @@ -553,10 +553,10 @@ grub_shim_load_image(grub_addr_t addr, grub_ssize_t size, 163 | sect_size = section->raw_data_size; 164 | 165 | base = (grub_int8_t *) 166 | - grub_shim_image_address (shim_buffer, context->image_size, 167 | + grub_shim_image_address ((grub_addr_t) shim_buffer, context->image_size, 168 | section->virtual_address); 169 | end = (grub_int8_t *) 170 | - grub_shim_image_address (shim_buffer, context->image_size, 171 | + grub_shim_image_address ((grub_addr_t) shim_buffer, context->image_size, 172 | section->virtual_address 173 | + sect_size - 1); 174 | 175 | @@ -619,7 +619,7 @@ grub_shim_load_image(grub_addr_t addr, grub_ssize_t size, 176 | if (context->reloc_dir->size && reloc_section) 177 | { 178 | status = grub_shim_relocate_coff (context, reloc_section, 179 | - (void *) addr, (void *) shim_buffer); 180 | + (void *) addr, (void *) ((grub_addr_t) shim_buffer)); 181 | if (status != GRUB_ERR_NONE) 182 | { 183 | grub_printf("Relocation failed: [%u]\n", status); 184 | @@ -627,7 +627,7 @@ grub_shim_load_image(grub_addr_t addr, grub_ssize_t size, 185 | goto fail; 186 | } 187 | } 188 | - shim_entry_point = (void *)grub_shim_image_address (shim_buffer, 189 | + shim_entry_point = (void *)grub_shim_image_address ((grub_addr_t) shim_buffer, 190 | context->image_size, 191 | context->entry_point); 192 | if (!shim_entry_point) 193 | @@ -696,8 +696,8 @@ grub_chainloader_boot (void) 194 | saved_exit = grub_efi_system_table->boot_services->exit; 195 | grub_efi_system_table->boot_services->exit = efi_shim_exit; 196 | status = efi_call_foo(shim_entry_point, 197 | - (grub_efi_uint64_t)grub_efi_image_handle, 198 | - (grub_efi_uint64_t)grub_efi_system_table); 199 | + grub_efi_image_handle, 200 | + grub_efi_system_table); 201 | grub_efi_system_table->boot_services->exit = saved_exit; 202 | 203 | loaded_image = grub_efi_get_loaded_image (grub_efi_image_handle); 204 | @@ -970,7 +970,7 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)), 205 | if (shim_used) 206 | { 207 | grub_memcpy(&shim_li_bak, loaded_image, sizeof(shim_li_bak)); 208 | - loaded_image->image_base = (void *)shim_buffer; 209 | + loaded_image->image_base = (void *)(grub_addr_t) shim_buffer; 210 | loaded_image->image_size = context.image_size; 211 | } 212 | else 213 | diff --git a/include/grub/efi/api.h b/include/grub/efi/api.h 214 | index 374d88b..22b3543 100644 215 | --- a/include/grub/efi/api.h 216 | +++ b/include/grub/efi/api.h 217 | @@ -1437,10 +1437,6 @@ typedef struct grub_efi_block_io grub_efi_block_io_t; 218 | 219 | grub_uint64_t EXPORT_FUNC(efi_wrap_0) (void *func); 220 | grub_uint64_t EXPORT_FUNC(efi_wrap_1) (void *func, grub_uint64_t arg1); 221 | -grub_efi_status_t EXPORT_FUNC(efi_shim_exit) (grub_efi_handle_t handle, grub_efi_status_t exit_status, 222 | - grub_efi_uintn_t exit_data_size, grub_efi_char16_t *exit_data) __attribute__((noreturn)); 223 | -grub_uint64_t EXPORT_FUNC(efi_call_foo) (void *func, grub_uint64_t arg1, 224 | - grub_uint64_t arg2); 225 | grub_uint64_t EXPORT_FUNC(efi_wrap_2) (void *func, grub_uint64_t arg1, 226 | grub_uint64_t arg2); 227 | grub_uint64_t EXPORT_FUNC(efi_wrap_3) (void *func, grub_uint64_t arg1, 228 | @@ -1467,4 +1463,8 @@ grub_uint64_t EXPORT_FUNC(efi_wrap_10) (void *func, grub_uint64_t arg1, 229 | grub_uint64_t arg10); 230 | #endif 231 | 232 | +grub_efi_status_t EXPORT_FUNC(efi_shim_exit) (grub_efi_handle_t handle, grub_efi_status_t exit_status, 233 | + grub_efi_uintn_t exit_data_size, grub_efi_char16_t *exit_data) __attribute__((noreturn)); 234 | +grub_efi_status_t EXPORT_FUNC(efi_call_foo) (void *func, void *arg1, void *arg2); 235 | + 236 | #endif /* ! GRUB_EFI_API_HEADER */ 237 | diff --git a/include/grub/efi/shim.h b/include/grub/efi/shim.h 238 | index 4b92a00..9fac90b 100644 239 | --- a/include/grub/efi/shim.h 240 | +++ b/include/grub/efi/shim.h 241 | @@ -60,7 +60,7 @@ struct grub_image_base_relocation 242 | 243 | struct grub_shim_pe_coff_loader_image_context { 244 | grub_efi_uint64_t image_address; 245 | - grub_efi_uint64_t image_size; 246 | + grub_efi_uintn_t image_size; 247 | grub_efi_uint64_t entry_point; 248 | grub_efi_uintn_t header_size; 249 | grub_efi_uint16_t image_type; 250 | -- 251 | 1.9.1 252 | 253 | -------------------------------------------------------------------------------- /recipes-bsp/grub/grub-efi/Grub-get-and-set-efi-variables.patch: -------------------------------------------------------------------------------- 1 | --- 2 | grub-core/Makefile.core.def | 8 + 3 | grub-core/commands/efi/efivar.c | 238 ++++++++++++++++++++++++++++++++++++++++ 4 | 2 files changed, 246 insertions(+) 5 | 6 | --- /dev/null 7 | +++ b/grub-core/commands/efi/efivar.c 8 | @@ -0,0 +1,238 @@ 9 | +/* efivar.c - Read EFI global variables. */ 10 | +/* 11 | + * GRUB -- GRand Unified Bootloader 12 | + * Copyright (C) 2015 Free Software Foundation, Inc. 13 | + * Copyright (C) 2015 CloudFlare, Inc. 14 | + * 15 | + * GRUB is free software: you can redistribute it and/or modify 16 | + * it under the terms of the GNU General Public License as published by 17 | + * the Free Software Foundation, either version 3 of the License, or 18 | + * (at your option) any later version. 19 | + * 20 | + * GRUB is distributed in the hope that it will be useful, 21 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of 22 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 23 | + * GNU General Public License for more details. 24 | + * 25 | + * You should have received a copy of the GNU General Public License 26 | + * along with GRUB. If not, see . 27 | + */ 28 | + 29 | +#include 30 | +#include 31 | +#include 32 | +#include 33 | +#include 34 | +#include 35 | +#include 36 | +#include 37 | + 38 | +GRUB_MOD_LICENSE ("GPLv3+"); 39 | + 40 | +static const struct grub_arg_option options[] = { 41 | + {"format", 'f', GRUB_ARG_OPTION_OPTIONAL, N_("Parse EFI_VAR in specific format (hex, uint8, ascii, dump). Default: hex."), N_("FORMAT"), ARG_TYPE_STRING}, 42 | + {"set", 's', GRUB_ARG_OPTION_OPTIONAL, N_("Save parsed result to environment variable (does not work with dump)."), N_("ENV_VAR"), ARG_TYPE_STRING}, 43 | + {0, 0, 0, 0, 0, 0} 44 | +}; 45 | + 46 | +enum efi_var_type 47 | + { 48 | + EFI_VAR_ASCII = 0, 49 | + EFI_VAR_UINT8, 50 | + EFI_VAR_HEX, 51 | + EFI_VAR_DUMP, 52 | + EFI_VAR_INVALID = -1 53 | + }; 54 | + 55 | +static enum efi_var_type 56 | +parse_efi_var_type (const char *type) 57 | +{ 58 | + if (!grub_strncmp (type, "ascii", sizeof("ascii"))) 59 | + return EFI_VAR_ASCII; 60 | + 61 | + if (!grub_strncmp (type, "uint8", sizeof("uint8"))) 62 | + return EFI_VAR_UINT8; 63 | + 64 | + if (!grub_strncmp (type, "hex", sizeof("hex"))) 65 | + return EFI_VAR_HEX; 66 | + 67 | + if (!grub_strncmp (type, "dump", sizeof("dump"))) 68 | + return EFI_VAR_DUMP; 69 | + 70 | + return EFI_VAR_INVALID; 71 | +} 72 | + 73 | +static int 74 | +grub_print_ascii (char *str, char c) 75 | +{ 76 | + if (grub_iscntrl (c)) 77 | + { 78 | + switch (c) 79 | + { 80 | + case '\0': 81 | + str[0] = '\\'; 82 | + str[1] = '0'; 83 | + return 2; 84 | + 85 | + case '\a': 86 | + str[0] = '\\'; 87 | + str[1] = 'a'; 88 | + return 2; 89 | + 90 | + case '\b': 91 | + str[0] = '\\'; 92 | + str[1] = 'b'; 93 | + return 2; 94 | + 95 | + case '\f': 96 | + str[0] = '\\'; 97 | + str[1] = 'f'; 98 | + return 2; 99 | + 100 | + case '\n': 101 | + str[0] = '\\'; 102 | + str[1] = 'n'; 103 | + return 2; 104 | + 105 | + case '\r': 106 | + str[0] = '\\'; 107 | + str[1] = 'r'; 108 | + return 2; 109 | + 110 | + case '\t': 111 | + str[0] = '\\'; 112 | + str[1] = 't'; 113 | + return 2; 114 | + 115 | + case '\v': 116 | + str[0] = '\\'; 117 | + str[1] = 'v'; 118 | + return 2; 119 | + 120 | + default: 121 | + str[0] = '.'; /* as in hexdump -C */ 122 | + return 1; 123 | + } 124 | + } 125 | + 126 | + str[0] = c; 127 | + return 1; 128 | +} 129 | + 130 | +static grub_err_t 131 | +grub_cmd_get_efi_var (struct grub_extcmd_context *ctxt, 132 | + int argc, char **args) 133 | +{ 134 | + struct grub_arg_list *state = ctxt->state; 135 | + grub_err_t status; 136 | + void *efi_var = NULL; 137 | + grub_size_t efi_var_size = 0; 138 | + enum efi_var_type efi_type = EFI_VAR_HEX; 139 | + grub_efi_guid_t global = GRUB_EFI_GLOBAL_VARIABLE_GUID; 140 | + char *env_var = NULL; 141 | + grub_size_t i; 142 | + char *ptr; 143 | + 144 | + if (1 != argc) 145 | + return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("one argument expected")); 146 | + 147 | + if (state[0].set) 148 | + efi_type = parse_efi_var_type (state[0].arg); 149 | + 150 | + if (EFI_VAR_INVALID == efi_type) 151 | + return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("invalid format specifier")); 152 | + 153 | + efi_var = grub_efi_get_variable (args[0], &global, &efi_var_size); 154 | + if (!efi_var || !efi_var_size) 155 | + { 156 | + status = grub_error (GRUB_ERR_READ_ERROR, N_("cannot read variable")); 157 | + goto err; 158 | + } 159 | + 160 | + switch (efi_type) 161 | + { 162 | + case EFI_VAR_ASCII: 163 | + env_var = grub_malloc (efi_var_size * 2 + 1); 164 | + if (!env_var) 165 | + { 166 | + status = grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory")); 167 | + break; 168 | + } 169 | + 170 | + ptr = env_var; 171 | + 172 | + for (i = 0; i < efi_var_size; i++) 173 | + ptr += grub_print_ascii (ptr, ((const char *)efi_var)[i]); 174 | + *ptr = '\0'; 175 | + break; 176 | + 177 | + case EFI_VAR_UINT8: 178 | + env_var = grub_malloc (4); 179 | + if (!env_var) 180 | + { 181 | + status = grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory")); 182 | + break; 183 | + } 184 | + grub_snprintf (env_var, 4, "%u", *((grub_uint8_t *)efi_var)); 185 | + break; 186 | + 187 | + case EFI_VAR_HEX: 188 | + env_var = grub_malloc (efi_var_size * 2 + 1); 189 | + if (!env_var) 190 | + { 191 | + status = grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory")); 192 | + break; 193 | + } 194 | + for (i = 0; i < efi_var_size; i++) 195 | + grub_snprintf (env_var + (i * 2), 3, "%02x", ((grub_uint8_t *)efi_var)[i]); 196 | + break; 197 | + 198 | + case EFI_VAR_DUMP: 199 | + if (state[1].set) 200 | + status = grub_error (GRUB_ERR_BAD_ARGUMENT, N_("cannot set variable with dump format specifier")); 201 | + else 202 | + { 203 | + hexdump (0, (char *)efi_var, efi_var_size); 204 | + status = GRUB_ERR_NONE; 205 | + } 206 | + break; 207 | + 208 | + default: 209 | + status = grub_error (GRUB_ERR_BUG, N_("should not happen (bug in module?)")); 210 | + } 211 | + 212 | + if (efi_type != EFI_VAR_DUMP) 213 | + { 214 | + if (state[1].set) 215 | + status = grub_env_set (state[1].arg, env_var); 216 | + else 217 | + { 218 | + grub_printf ("%s\n", (const char *)env_var); 219 | + status = GRUB_ERR_NONE; 220 | + } 221 | + } 222 | + 223 | +err: 224 | + 225 | + if (env_var) 226 | + grub_free (env_var); 227 | + 228 | + if (efi_var) 229 | + grub_free (efi_var); 230 | + 231 | + return status; 232 | +} 233 | + 234 | +static grub_extcmd_t cmd = NULL; 235 | + 236 | +GRUB_MOD_INIT (efivar) 237 | +{ 238 | + cmd = grub_register_extcmd ("get_efivar", grub_cmd_get_efi_var, 0, N_("[-f FORMAT] [-s ENV_VAR] EFI_VAR"), 239 | + N_("Read EFI variable and print it or save its contents to environment variable."), options); 240 | +} 241 | + 242 | +GRUB_MOD_FINI (efivar) 243 | +{ 244 | + if (cmd) 245 | + grub_unregister_extcmd (cmd); 246 | +} 247 | --- a/grub-core/Makefile.core.def 248 | +++ b/grub-core/Makefile.core.def 249 | @@ -539,6 +539,14 @@ module = { 250 | }; 251 | 252 | module = { 253 | + name = efivar; 254 | + 255 | + common = commands/efi/efivar.c; 256 | + 257 | + enable = efi; 258 | +}; 259 | + 260 | +module = { 261 | name = lsacpi; 262 | 263 | common = commands/lsacpi.c; 264 | -------------------------------------------------------------------------------- /recipes-bsp/grub/grub-efi/boot-menu-hddimg.inc: -------------------------------------------------------------------------------- 1 | # Note the initrd command becomes not working if the command for 2 | # loading image is changed to the chainloader command instead of 3 | # the linux command. 4 | 5 | menuentry "Sample EFI boot" --unrestricted { 6 | savedefault 7 | set fallback=1 8 | linux /bzImage root=/dev/ram0 ro rootwait 9 | initrd /initrd 10 | } 11 | 12 | menuentry "Sample EFI boot (Recovery)" --unrestricted { 13 | linux /bzImage_bakup root=/dev/ram0 ro rootwait 14 | initrd /initrd_bakup 15 | } 16 | -------------------------------------------------------------------------------- /recipes-bsp/grub/grub-efi/boot-menu.inc: -------------------------------------------------------------------------------- 1 | # Note the initrd command becomes not working if the command for 2 | # loading image is changed to the chainloader command instead of 3 | # the linux command. 4 | 5 | menuentry "Sample EFI boot" --unrestricted { 6 | savedefault 7 | set fallback=1 8 | linux /bzImage root=/dev/sda2 ro rootwait 9 | initrd /initrd 10 | } 11 | 12 | menuentry "Sample EFI boot (Recovery)" --unrestricted { 13 | linux /bzImage_bakup root=/dev/sda2 ro rootwait 14 | initrd /initrd_bakup 15 | } 16 | -------------------------------------------------------------------------------- /recipes-bsp/grub/grub-efi/chainloader-Actually-find-the-relocations-correctly-.patch: -------------------------------------------------------------------------------- 1 | From f6c412a240312a2be28b85905a0866288db9ffc8 Mon Sep 17 00:00:00 2001 2 | From: Lans Zhang 3 | Date: Sun, 24 Apr 2016 19:02:28 +0800 4 | Subject: [PATCH] chainloader: Actually find the relocations correctly and 5 | process them that way. 6 | 7 | Upstream-Status: Pending 8 | 9 | Refer to a846aedd0e9dfe26ca6afaf6a1db8a54c20363c1 in shim. 10 | 11 | Find the relocations based on the *file* address in the old binary, 12 | because it's only the same as the virtual address some of the time. 13 | 14 | Also perform some extra validation before processing it, and don't bail 15 | out in /error/ if both ReloceBase and RelocEnd are null - that condition 16 | is fine. 17 | 18 | Signed-off-by: Lans Zhang 19 | --- 20 | grub-core/loader/efi/chainloader.c | 97 +++++++++++++++++++++++++++++++------- 21 | 1 file changed, 81 insertions(+), 16 deletions(-) 22 | 23 | diff --git a/grub-core/loader/efi/chainloader.c b/grub-core/loader/efi/chainloader.c 24 | index 0e84100..83769a2 100644 25 | --- a/grub-core/loader/efi/chainloader.c 26 | +++ b/grub-core/loader/efi/chainloader.c 27 | @@ -162,6 +162,7 @@ grub_shim_image_address (grub_addr_t image, grub_uint32_t size, grub_uint32_t ad 28 | */ 29 | static grub_err_t 30 | grub_shim_relocate_coff (struct grub_shim_pe_coff_loader_image_context *context, 31 | + struct grub_pe32_section_table *section, 32 | void *orig, void *data) 33 | { 34 | struct grub_image_base_relocation *reloc_base, *reloc_base_end; 35 | @@ -173,19 +174,53 @@ grub_shim_relocate_coff (struct grub_shim_pe_coff_loader_image_context *context, 36 | grub_efi_uint64_t *fixup64; 37 | grub_int32_t size = context->image_size; 38 | void *image_end = (char *)orig + size; 39 | + int n = 0; 40 | 41 | if (grub_shim_image_is_64_bit(context->pe_hdr)) 42 | context->pe_hdr->pe32plus.opt_hdr.image_base = (grub_efi_uint64_t)(unsigned long)data; 43 | else 44 | context->pe_hdr->pe32.opt_hdr.image_base = (grub_efi_uint32_t)(unsigned long)data; 45 | 46 | + 47 | + /* Alright, so here's how this works: 48 | + * 49 | + * context->RelocDir gives us two things: 50 | + * - the VA the table of base relocation blocks are (maybe) to be 51 | + * mapped at (RelocDir->VirtualAddress) 52 | + * - the virtual size (RelocDir->Size) 53 | + * 54 | + * The .reloc section (Section here) gives us some other things: 55 | + * - the name! kind of. (Section->Name) 56 | + * - the virtual size (Section->VirtualSize), which should be the same 57 | + * as RelocDir->Size 58 | + * - the virtual address (Section->VirtualAddress) 59 | + * - the file section size (Section->SizeOfRawData), which is 60 | + * a multiple of OptHdr->FileAlignment. Only useful for image 61 | + * validation, not really useful for iteration bounds. 62 | + * - the file address (Section->PointerToRawData) 63 | + * - a bunch of stuff we don't use that's 0 in our binaries usually 64 | + * - Flags (Section->Characteristics) 65 | + * 66 | + * and then the thing that's actually at the file address is an array 67 | + * of EFI_IMAGE_BASE_RELOCATION structs with some values packed behind 68 | + * them. The SizeOfBlock field of this structure includes the 69 | + * structure itself, and adding it to that structure's address will 70 | + * yield the next entry in the array. 71 | + */ 72 | reloc_base = (struct grub_image_base_relocation *) 73 | grub_shim_image_address ((grub_efi_uint64_t)orig, size, 74 | - context->reloc_dir->rva); 75 | + section->raw_data_offset); 76 | + /* reloc_base_end is the address of the first entry /past/ the 77 | + * table. */ 78 | reloc_base_end = (struct grub_image_base_relocation *) 79 | grub_shim_image_address ((grub_efi_uint64_t)orig, size, 80 | - context->reloc_dir->rva 81 | - + context->reloc_dir->size - 1); 82 | + section->raw_data_offset 83 | + + section->virtual_size - 1); 84 | + 85 | + if (!reloc_base && !reloc_base_end) 86 | + { 87 | + return GRUB_EFI_SUCCESS; 88 | + } 89 | 90 | if (!reloc_base || !reloc_base_end) 91 | { 92 | @@ -206,7 +241,7 @@ grub_shim_relocate_coff (struct grub_shim_pe_coff_loader_image_context *context, 93 | if ((reloc_base->block_size == 0) 94 | || (reloc_base->block_size > context->reloc_dir->size)) 95 | { 96 | - grub_printf("Reloc block size %d is invalid\n", reloc_base->block_size); 97 | + grub_printf("Reloc %d block size %d is invalid\n", n, reloc_base->block_size); 98 | return GRUB_ERR_FILE_READ_ERROR; 99 | } 100 | 101 | @@ -214,7 +249,7 @@ grub_shim_relocate_coff (struct grub_shim_pe_coff_loader_image_context *context, 102 | ((grub_uint8_t *) reloc_base + reloc_base->block_size); 103 | if ((void *)reloc_end < orig || (void *)reloc_end > image_end) 104 | { 105 | - grub_printf("Reloc entry overflows binary\n"); 106 | + grub_printf("Reloc %d entry overflows binary\n", n); 107 | return GRUB_ERR_FILE_READ_ERROR; 108 | } 109 | 110 | @@ -224,7 +259,7 @@ grub_shim_relocate_coff (struct grub_shim_pe_coff_loader_image_context *context, 111 | reloc_base->virtual_address); 112 | if (!fixup_base) 113 | { 114 | - grub_printf("Invalid fixup_base\n"); 115 | + grub_printf("Reloc %d invalid fixup_base\n", n); 116 | return GRUB_ERR_FILE_READ_ERROR; 117 | } 118 | 119 | @@ -282,12 +317,13 @@ grub_shim_relocate_coff (struct grub_shim_pe_coff_loader_image_context *context, 120 | break; 121 | 122 | default: 123 | - grub_printf("Unknown relocation\n"); 124 | + grub_printf("Reloc %d unknown relocation\n", n); 125 | return GRUB_ERR_FILE_READ_ERROR; 126 | } 127 | reloc += 1; 128 | } 129 | reloc_base = (struct grub_image_base_relocation *) reloc_end; 130 | + n++; 131 | } 132 | 133 | return GRUB_EFI_SUCCESS; 134 | @@ -458,9 +494,9 @@ grub_shim_load_image(grub_addr_t addr, grub_ssize_t size, 135 | grub_efi_status_t efi_status; 136 | grub_uint32_t sect_size; 137 | /* TODO: can they be unsigned? */ 138 | - grub_int8_t *base, *end; 139 | + grub_int8_t *base, *end, *reloc_base, *reloc_base_end; 140 | grub_int32_t i; 141 | - struct grub_pe32_section_table *section; 142 | + struct grub_pe32_section_table *section, *reloc_section; 143 | grub_efi_boot_services_t *b; 144 | 145 | shim_used = 0; 146 | @@ -496,16 +532,21 @@ grub_shim_load_image(grub_addr_t addr, grub_ssize_t size, 147 | /* TODO: do we need the double cast? */ 148 | grub_memcpy ((void *) ((grub_efi_physical_address_t) shim_buffer), 149 | (void *) ((grub_addr_t) addr), context->header_size); 150 | + 151 | + reloc_base = (grub_int8_t *) grub_shim_image_address (shim_buffer, size, 152 | + context->reloc_dir->rva); 153 | + /* reloc_base_end here is the address of the last byte of the table */ 154 | + reloc_base_end = (grub_int8_t *) grub_shim_image_address (shim_buffer, size, 155 | + context->reloc_dir->rva + 156 | + context->reloc_dir->size - 1); 157 | + reloc_section = NULL; 158 | + 159 | /* 160 | * Copy the executable's sections to their desired offsets 161 | */ 162 | section = context->first_section; 163 | for (i = 0; i < context->num_sections; i++, section++) 164 | { 165 | - if (section->characteristics & 0x02000000) 166 | - /* section has EFI_IMAGE_SCN_MEM_DISCARDABLE attr set */ 167 | - continue; 168 | - 169 | sect_size = section->virtual_size; 170 | 171 | if (sect_size > section->raw_data_size) 172 | @@ -518,6 +559,30 @@ grub_shim_load_image(grub_addr_t addr, grub_ssize_t size, 173 | grub_shim_image_address (shim_buffer, context->image_size, 174 | section->virtual_address 175 | + sect_size - 1); 176 | + 177 | + /* We do want to process .reloc, but it's often marked 178 | + * discardable, so we don't want to memcpy it. */ 179 | + if (grub_memcmp (section->name, ".reloc\0\0", 8) == 0) { 180 | + if (reloc_section) { 181 | + grub_printf("Image has multiple relocation sections\n"); 182 | + status = GRUB_ERR_BAD_FILE_TYPE; 183 | + goto fail; 184 | + } 185 | + /* If it has nonzero sizes, and our bounds check 186 | + * made sense, and the VA and size match RelocDir's 187 | + * versions, then we believe in this section table. */ 188 | + if (section->raw_data_size && section->virtual_size && 189 | + base && end && 190 | + reloc_base == base && 191 | + reloc_base_end == end) { 192 | + reloc_section = section; 193 | + } 194 | + } 195 | + 196 | + if (section->characteristics & 0x02000000) 197 | + /* section has EFI_IMAGE_SCN_MEM_DISCARDABLE attr set */ 198 | + continue; 199 | + 200 | if (!base || !end) 201 | { 202 | grub_printf("Invalid section base\n"); 203 | @@ -551,10 +616,10 @@ grub_shim_load_image(grub_addr_t addr, grub_ssize_t size, 204 | goto fail; 205 | } 206 | 207 | - if (context->reloc_dir->size) 208 | + if (context->reloc_dir->size && reloc_section) 209 | { 210 | - status = grub_shim_relocate_coff (context, (void *) addr, 211 | - (void *) shim_buffer); 212 | + status = grub_shim_relocate_coff (context, reloc_section, 213 | + (void *) addr, (void *) shim_buffer); 214 | if (status != GRUB_ERR_NONE) 215 | { 216 | grub_printf("Relocation failed: [%u]\n", status); 217 | -- 218 | 1.9.1 219 | 220 | -------------------------------------------------------------------------------- /recipes-bsp/grub/grub-efi/chainloader-Don-t-check-empty-section-in-file-like-..patch: -------------------------------------------------------------------------------- 1 | From d3a1198bfc671530ed77ad2b81b0ae4582f9378e Mon Sep 17 00:00:00 2001 2 | From: Lans Zhang 3 | Date: Sun, 24 Apr 2016 15:56:38 +0800 4 | Subject: [PATCH] chainloader: Don't check empty section in file like .bss 5 | 6 | Upstream-Status: Pending 7 | 8 | Because this kind of section always has a zeroed PointerToRawData denoting 9 | the offset to file and a valid VirtualSize denoting the real size in the 10 | memory. 11 | 12 | Signed-off-by: Lans Zhang 13 | --- 14 | grub-core/loader/efi/chainloader.c | 2 +- 15 | 1 file changed, 1 insertion(+), 1 deletion(-) 16 | 17 | diff --git a/grub-core/loader/efi/chainloader.c b/grub-core/loader/efi/chainloader.c 18 | index 2d8edc0..0e84100 100644 19 | --- a/grub-core/loader/efi/chainloader.c 20 | +++ b/grub-core/loader/efi/chainloader.c 21 | @@ -526,7 +526,7 @@ grub_shim_load_image(grub_addr_t addr, grub_ssize_t size, 22 | } 23 | 24 | if (section->virtual_address < context->header_size 25 | - || section->raw_data_offset < context->header_size) 26 | + || (section->raw_data_offset && section->raw_data_offset < context->header_size)) 27 | { 28 | grub_printf("Section is inside image headers\n"); 29 | status = GRUB_ERR_BAD_FILE_TYPE; 30 | -- 31 | 1.9.1 32 | 33 | -------------------------------------------------------------------------------- /recipes-bsp/grub/grub-efi/chainloader-handle-the-unauthenticated-image-by-shim.patch: -------------------------------------------------------------------------------- 1 | From b945262cdbad67e59f0d13725181862aa8a29561 Mon Sep 17 00:00:00 2001 2 | From: Lans Zhang 3 | Date: Sun, 24 Apr 2016 12:58:10 +0800 4 | Subject: [PATCH] chainloader: handle the unauthenticated image by shim 5 | 6 | Upstream-Status: Pending 7 | 8 | EFI_ACCESS_DENIED is another case whenever an unauthenticated image is loaded 9 | by UEFI LoadImage() boot service. Shim verification protocol should handle 10 | this case as EFI_SECURITY_VIOLATION. 11 | 12 | Signed-off-by: Lans Zhang 13 | --- 14 | grub-core/loader/efi/chainloader.c | 2 +- 15 | 1 file changed, 1 insertion(+), 1 deletion(-) 16 | 17 | diff --git a/grub-core/loader/efi/chainloader.c b/grub-core/loader/efi/chainloader.c 18 | index 9f908c3..2850627 100644 19 | --- a/grub-core/loader/efi/chainloader.c 20 | +++ b/grub-core/loader/efi/chainloader.c 21 | @@ -868,7 +868,7 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)), 22 | goto fail; 23 | } 24 | /* try with shim */ 25 | - else if (status == GRUB_EFI_SECURITY_VIOLATION) 26 | + else if ((status == GRUB_EFI_ACCESS_DENIED) || (status == GRUB_EFI_SECURITY_VIOLATION)) 27 | { 28 | status = grub_shim_load_image (address, size, &context); 29 | if (status != GRUB_EFI_SUCCESS) 30 | -- 31 | 1.9.1 32 | 33 | -------------------------------------------------------------------------------- /recipes-bsp/grub/grub-efi/efi-secure-boot.inc: -------------------------------------------------------------------------------- 1 | get_efivar -f uint8 -s secured SecureBoot 2 | 3 | if [ "${secured}" = "1" ]; then 4 | if [ -s "${prefix}/password.inc" ]; then 5 | source "${prefix}/password.inc" 6 | fi 7 | fi 8 | 9 | get_efivar -f uint8 -s unprovisioned SetupMode 10 | 11 | if [ "${unprovisioned}" = "1" ]; then 12 | # Create a boot entry for Automatic Certificate Provision. 13 | # This is especially useful for certain hardware, e.g, 14 | # Intel NUC5i3MYHE, doedn't support to display a customized 15 | # BIOS boot option used to launch LockDown.efi. 16 | 17 | if [ ! "${provision_failed}" ]; then 18 | # Secure boot was disabled in BIOS setup. Overwrite the 19 | # behavior of normal boot. 20 | set timeout=0 21 | set default="Automatic Certificate Provision" 22 | elif [ "${provision_failed}" = "0" ]; then 23 | # The auto provision was reset in BIOS setup. 24 | set default="Automatic Certificate Provision" 25 | fi 26 | 27 | # This menu will be hidden as long as the provision succeeds. 28 | menuentry "Automatic Certificate Provision" --unrestricted { 29 | set provision_failed="0" 30 | save_env provision_failed 31 | 32 | chainloader "${prefix}/LockDown.efi" 33 | 34 | # Refuse to unlimitedly run into auto provision if failed. 35 | set provision_failed="1" 36 | save_env provision_failed 37 | } 38 | fi 39 | -------------------------------------------------------------------------------- /recipes-bsp/grub/grub-efi/grub-efi.cfg: -------------------------------------------------------------------------------- 1 | set timeout=3 2 | set color_normal="light-gray/black" 3 | set color_highlight="light-green/blue" 4 | 5 | # The first boot entry in normal boot. 6 | set first_boot="0" 7 | 8 | # The default boot entry after the first boot. 9 | set default_boot="0" 10 | 11 | function savedefault { 12 | if [ "${chosen}" ]; then 13 | next_boot="${chosen}" 14 | save_env next_boot 15 | fi 16 | } 17 | 18 | if [ -s "${prefix}/grubenv" ]; then 19 | load_env 20 | fi 21 | 22 | if [ "${next_boot}" ]; then 23 | set default="${next_boot}" 24 | else 25 | set default="${first_boot}" 26 | set next_boot="${default_boot}" 27 | save_env next_boot 28 | fi 29 | 30 | if [ -s "${prefix}/efi-secure-boot.inc" ]; then 31 | source "${prefix}/efi-secure-boot.inc" 32 | fi 33 | 34 | if [ -s "${prefix}/boot-menu.inc" ]; then 35 | source "${prefix}/boot-menu.inc" 36 | fi 37 | -------------------------------------------------------------------------------- /recipes-bsp/grub/grub-efi/grub-enable-serial-console-by-default.patch: -------------------------------------------------------------------------------- 1 | From cd9fbf5dc00733f8e46966e67be85ff6f9d36e6e Mon Sep 17 00:00:00 2001 2 | From: Paul Gortmaker 3 | Date: Fri, 10 Apr 2015 18:38:23 -0400 4 | Subject: [PATCH] grub: enable serial console by default 5 | 6 | Have grub go to the serial console and the default VGA console. 7 | 8 | Signed-off-by: Paul Gortmaker 9 | --- 10 | util/grub.d/00_header.in | 4 ++++ 11 | 1 file changed, 4 insertions(+) 12 | 13 | diff --git a/util/grub.d/00_header.in b/util/grub.d/00_header.in 14 | index 765bfdcd30e3..86b260a2c380 100644 15 | --- a/util/grub.d/00_header.in 16 | +++ b/util/grub.d/00_header.in 17 | @@ -27,6 +27,10 @@ grub_lang=`echo $LANG | cut -d . -f 1` 18 | export TEXTDOMAIN=@PACKAGE@ 19 | export TEXTDOMAINDIR="@localedir@" 20 | 21 | +export GRUB_TERMINAL_INPUT="console serial" 22 | +export GRUB_TERMINAL_OUTPUT="console serial" 23 | +export GRUB_SERIAL_COMMAND="serial --speed=115200 --unit=0 --word=8 --parity=no --stop=1" 24 | + 25 | . "@datadir@/@PACKAGE@/grub-mkconfig_lib" 26 | 27 | # Do this as early as possible, since other commands might depend on it. 28 | -- 29 | 2.3.1 30 | 31 | -------------------------------------------------------------------------------- /recipes-bsp/grub/grub-efi/mok2verify-support-to-verify-non-PE-file-with-PKCS-7.patch: -------------------------------------------------------------------------------- 1 | From 46873e2c5514bf6460a2f0f39ad8f8feb8f18f68 Mon Sep 17 00:00:00 2001 2 | From: Lans Zhang 3 | Date: Thu, 16 Mar 2017 14:49:41 +0800 4 | Subject: [PATCH] mok2verify: support to verify non-PE file with PKCS#7 5 | signature 6 | 7 | MOK2 Verify Protocol is designed to verify non-PE file which cannot be 8 | verified by the MOK verify protocol supplied by shim loader, such as grub 9 | configuration, initrd, grub modules and so on. 10 | 11 | Each signed file has a .p7b PKCS#7 signature file for verification. For 12 | more details about signature format and singing tool, refer to 13 | https://github.com/jiazhang0/SELoader and https://github.com/jiazhang0/libsign 14 | 15 | If either kernel or initrd is not authenticated, just go to the failover 16 | boot to avoid a much worse failure. 17 | 18 | If any of grub config files is not authenticated, the boot process just 19 | stops there. 20 | 21 | In addition, the editor, rescue and cmdline modes are protected by the 22 | combination of settings of secure boot and user authentication in order 23 | to prevent from tampering the kernel commandline or booting unsigned 24 | kernel. 25 | 26 | Signed-off-by: Lans Zhang 27 | --- 28 | grub-core/Makefile.core.def | 6 ++ 29 | grub-core/commands/boot.c | 14 +++- 30 | grub-core/gfxmenu/gui_label.c | 39 ++++++++-- 31 | grub-core/lib/efi/mok2verify.c | 172 +++++++++++++++++++++++++++++++++++++++++ 32 | grub-core/loader/i386/linux.c | 80 +++++++++++++++++++ 33 | grub-core/normal/main.c | 55 ++++++++++++- 34 | grub-core/normal/menu.c | 29 +++++-- 35 | grub-core/normal/menu_text.c | 32 ++++++-- 36 | include/grub/efi/mok2verify.h | 48 ++++++++++++ 37 | 9 files changed, 447 insertions(+), 28 deletions(-) 38 | create mode 100644 grub-core/lib/efi/mok2verify.c 39 | create mode 100644 include/grub/efi/mok2verify.h 40 | 41 | diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def 42 | index e9e1483..8e72251 100644 43 | --- a/grub-core/Makefile.core.def 44 | +++ b/grub-core/Makefile.core.def 45 | @@ -1434,6 +1434,12 @@ module = { 46 | }; 47 | 48 | module = { 49 | + name = mok2verify; 50 | + efi = lib/efi/mok2verify.c; 51 | + enable = efi; 52 | +}; 53 | + 54 | +module = { 55 | name = mmap; 56 | common = mmap/mmap.c; 57 | x86 = mmap/i386/uppermem.c; 58 | diff --git a/grub-core/commands/boot.c b/grub-core/commands/boot.c 59 | index 91ec87d..5cddbb6 100644 60 | --- a/grub-core/commands/boot.c 61 | +++ b/grub-core/commands/boot.c 62 | @@ -24,6 +24,9 @@ 63 | #include 64 | #include 65 | #include 66 | +#ifdef GRUB_MACHINE_EFI 67 | +#include 68 | +#endif 69 | 70 | GRUB_MOD_LICENSE ("GPLv3+"); 71 | 72 | @@ -143,8 +146,15 @@ grub_loader_boot (void) 73 | struct grub_preboot *cur; 74 | 75 | if (! grub_loader_loaded) 76 | - return grub_error (GRUB_ERR_NO_KERNEL, 77 | - N_("you need to load the kernel first")); 78 | + { 79 | +#ifdef GRUB_MACHINE_EFI 80 | + if (grub_is_secured () == 1) 81 | + return grub_error (GRUB_ERR_BAD_OS, 82 | + N_("you need to load the authenticated boot components")); 83 | +#endif 84 | + return grub_error (GRUB_ERR_NO_KERNEL, 85 | + N_("you need to load the kernel first")); 86 | + } 87 | 88 | if (grub_loader_flags & GRUB_LOADER_FLAG_NORETURN) 89 | grub_machine_fini (); 90 | diff --git a/grub-core/gfxmenu/gui_label.c b/grub-core/gfxmenu/gui_label.c 91 | index 637578f..84bf7d4 100644 92 | --- a/grub-core/gfxmenu/gui_label.c 93 | +++ b/grub-core/gfxmenu/gui_label.c 94 | @@ -23,6 +23,9 @@ 95 | #include 96 | #include 97 | #include 98 | +#ifdef GRUB_MACHINE_EFI 99 | +#include 100 | +#endif 101 | 102 | static const char *align_options[] = 103 | { 104 | @@ -180,15 +183,37 @@ label_set_property (void *vself, const char *name, const char *value) 105 | else 106 | { 107 | if (grub_strcmp (value, "@KEYMAP_LONG@") == 0) 108 | - value = _("Press enter to boot the selected OS, " 109 | - "`e' to edit the commands before booting " 110 | - "or `c' for a command-line. ESC to return previous menu."); 111 | + { 112 | +#ifdef GRUB_MACHINE_EFI 113 | + if (grub_is_locked () == 1) 114 | + value = _("Press enter to boot the selected OS. " 115 | + "ESC to return previous menu."); 116 | + else 117 | +#endif 118 | + value = _("Press enter to boot the selected OS, " 119 | + "`e' to edit the commands before booting " 120 | + "or `c' for a command-line. ESC to return previous menu."); 121 | + } 122 | else if (grub_strcmp (value, "@KEYMAP_MIDDLE@") == 0) 123 | - value = _("Press enter to boot the selected OS, " 124 | - "`e' to edit the commands before booting " 125 | - "or `c' for a command-line."); 126 | + { 127 | +#ifdef GRUB_MACHINE_EFI 128 | + if (grub_is_locked () == 1) 129 | + value = _("Press enter to boot the selected OS."); 130 | + else 131 | +#endif 132 | + value = _("Press enter to boot the selected OS, " 133 | + "`e' to edit the commands before booting " 134 | + "or `c' for a command-line."); 135 | + } 136 | else if (grub_strcmp (value, "@KEYMAP_SHORT@") == 0) 137 | - value = _("enter: boot, `e': options, `c': cmd-line"); 138 | + { 139 | +#ifdef GRUB_MACHINE_EFI 140 | + if (grub_is_locked () == 1) 141 | + value = _("enter: boot"); 142 | + else 143 | +#endif 144 | + value = _("enter: boot, `e': options, `c': cmd-line"); 145 | + } 146 | /* FIXME: Add more templates here if needed. */ 147 | self->template = grub_strdup (value); 148 | self->text = grub_xasprintf (value, self->value); 149 | diff --git a/grub-core/lib/efi/mok2verify.c b/grub-core/lib/efi/mok2verify.c 150 | new file mode 100644 151 | index 0000000..2e48ef9 152 | --- /dev/null 153 | +++ b/grub-core/lib/efi/mok2verify.c 154 | @@ -0,0 +1,172 @@ 155 | +/* mok2verify.c - MOK2 Verify Protocol support 156 | + * 157 | + * BSD 2-clause "Simplified" License 158 | + * 159 | + * Copyright (c) 2017, Lans Zhang 160 | + * All rights reserved. 161 | + * 162 | + * Redistribution and use in source and binary forms, with or without 163 | + * modification, are permitted provided that the following conditions are met: 164 | + * 165 | + * * Redistributions of source code must retain the above copyright notice, this 166 | + * list of conditions and the following disclaimer. 167 | + * 168 | + * * Redistributions in binary form must reproduce the above copyright notice, 169 | + * this list of conditions and the following disclaimer in the documentation 170 | + * and/or other materials provided with the distribution. 171 | + * 172 | + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 173 | + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 174 | + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 175 | + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 176 | + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 177 | + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 178 | + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 179 | + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 180 | + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 181 | + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 182 | + */ 183 | + 184 | +#include 185 | +#include 186 | +#include 187 | +#include 188 | +#include 189 | +#include 190 | +#include 191 | +#include 192 | +#include 193 | +#include 194 | +#include 195 | + 196 | +GRUB_MOD_LICENSE ("GPLv2+"); 197 | + 198 | +#define EFI_MOK2_VERIFY_PROTOCOL_GUID \ 199 | + { 0x4eda73ad, 0x07aa, 0x4b7a, \ 200 | + { 0xa1, 0x91, 0xd4, 0xd4, 0x10, 0xfb, 0x8c, 0xb4 } \ 201 | + } 202 | + 203 | +typedef struct efi_mok2_verify_protocol efi_mok2_verify_protocol_t; 204 | + 205 | +typedef grub_efi_status_t 206 | +(*grub_efi_mok2_verify_signature) (efi_mok2_verify_protocol_t *this, 207 | + void *signature, 208 | + grub_efi_uintn_t signature_size, 209 | + void *data, grub_efi_uintn_t data_size); 210 | + 211 | +typedef grub_efi_status_t 212 | +(*grub_efi_mok2_verify_file_buffer) (efi_mok2_verify_protocol_t *this, 213 | + void **data, grub_efi_uintn_t *data_size, 214 | + const grub_efi_char16_t *path); 215 | + 216 | +typedef grub_efi_status_t 217 | +(*grub_efi_mok2_verify_file) (efi_mok2_verify_protocol_t *this, 218 | + const grub_efi_char16_t *path); 219 | + 220 | +struct efi_mok2_verify_protocol { 221 | + grub_efi_uint8_t revision; 222 | + grub_efi_mok2_verify_signature verify_signature; 223 | + grub_efi_mok2_verify_file_buffer verify_file_buffer; 224 | + grub_efi_mok2_verify_file verify_file; 225 | +}; 226 | + 227 | +static grub_efi_guid_t grub_efi_mok2_verify_protoco_guid = EFI_MOK2_VERIFY_PROTOCOL_GUID; 228 | + 229 | +int 230 | +grub_is_secured (void) 231 | +{ 232 | + grub_efi_guid_t global = GRUB_EFI_GLOBAL_VARIABLE_GUID; 233 | + void *efi_var; 234 | + grub_size_t efi_var_size = 0; 235 | + int secured = 0; 236 | + 237 | + efi_var = grub_efi_get_variable ("SecureBoot", &global, &efi_var_size); 238 | + if (!efi_var) 239 | + return grub_error (GRUB_ERR_READ_ERROR, N_("cannot read variable")); 240 | + 241 | + if (efi_var_size == 1 && *(grub_uint8_t *) efi_var == 1) 242 | + secured = 1; 243 | + 244 | + grub_free (efi_var); 245 | + 246 | + return secured; 247 | +} 248 | + 249 | +int 250 | +grub_is_unlockable (void) 251 | +{ 252 | + return !! grub_env_get ("superusers"); 253 | +} 254 | + 255 | +int 256 | +grub_is_locked (void) 257 | +{ 258 | + return ! grub_is_unlockable () && grub_is_secured (); 259 | +} 260 | + 261 | +grub_err_t 262 | +grub_verify_file (const char *path) 263 | +{ 264 | + efi_mok2_verify_protocol_t *mok2; 265 | + grub_efi_char16_t *p; 266 | + grub_size_t len = grub_strlen (path); 267 | + grub_efi_char16_t file_path[(len + 1) * GRUB_MAX_UTF16_PER_UTF8]; 268 | + const char *root; 269 | + const char *real_path; 270 | + grub_efi_status_t status; 271 | + 272 | + mok2 = grub_efi_locate_protocol (&grub_efi_mok2_verify_protoco_guid, 0); 273 | + if (!mok2) 274 | + { 275 | + grub_dprintf ("mok2verify", "unable to load mok2 verify protocol\n"); 276 | + return GRUB_ERR_NONE; 277 | + } 278 | + 279 | + grub_dprintf ("mok2verify", "attempting to verify the file %s ...\n", path); 280 | + 281 | + real_path = path; 282 | + root = grub_env_get ("root"); 283 | + if (root) 284 | + { 285 | + char *pattern; 286 | + 287 | + pattern = grub_xasprintf ("(%s)", root); 288 | + if (!pattern) 289 | + return grub_errno; 290 | + 291 | + if (grub_strstr (path, pattern) == path) 292 | + { 293 | + real_path = path + grub_strlen (pattern); 294 | + len -= grub_strlen (pattern); 295 | + } 296 | + 297 | + grub_free (pattern); 298 | + } 299 | + 300 | + len = grub_utf8_to_utf16 (file_path, len * GRUB_MAX_UTF16_PER_UTF8, 301 | + (const grub_uint8_t *) real_path, len, 0); 302 | + file_path[len] = 0; 303 | + for (p = file_path; p < file_path + len; ++p) 304 | + if (*p == '/') 305 | + *p = '\\'; 306 | + 307 | + status = efi_call_2 (mok2->verify_file, mok2, file_path); 308 | + if (status != GRUB_EFI_SUCCESS) 309 | + { 310 | + if (status == GRUB_EFI_NOT_FOUND) 311 | + return grub_error (GRUB_ERR_FILE_NOT_FOUND, "the specified file %s is not found", 312 | + path); 313 | + else 314 | + { 315 | + grub_printf ("failed to verify file %s (err: 0x%lx)\n", 316 | + path, status); 317 | + 318 | + return grub_error (GRUB_ERR_ACCESS_DENIED, "the file %s is not verified", 319 | + path); 320 | + } 321 | + } 322 | + 323 | + grub_dprintf ("mok2verify", "succeeded to verify file %s\n", path); 324 | + 325 | + return GRUB_ERR_NONE; 326 | +} 327 | diff --git a/grub-core/loader/i386/linux.c b/grub-core/loader/i386/linux.c 328 | index e2425c8..5a12444 100644 329 | --- a/grub-core/loader/i386/linux.c 330 | +++ b/grub-core/loader/i386/linux.c 331 | @@ -34,6 +34,9 @@ 332 | #include 333 | #include 334 | #include 335 | +#ifdef GRUB_MACHINE_EFI 336 | +#include 337 | +#endif 338 | 339 | GRUB_MOD_LICENSE ("GPLv3+"); 340 | 341 | @@ -664,6 +667,55 @@ grub_linux_unload (void) 342 | return GRUB_ERR_NONE; 343 | } 344 | 345 | +#ifdef GRUB_MACHINE_EFI 346 | +static grub_err_t 347 | +grub_verify_linux (const char *path) 348 | +{ 349 | + grub_file_t file; 350 | + grub_ssize_t size; 351 | + grub_uint8_t *buf = NULL; 352 | + 353 | + grub_dprintf ("linux", "Verifying kernel %s\n", path); 354 | + 355 | + file = grub_file_open (path); 356 | + if (!file) 357 | + return grub_errno; 358 | + 359 | + size = grub_file_size (file); 360 | + 361 | + buf = grub_malloc (size); 362 | + if (!buf) 363 | + goto fail; 364 | + 365 | + if (grub_file_read (file, buf, size) != size) 366 | + { 367 | + if (!grub_errno) 368 | + grub_error (GRUB_ERR_BAD_OS, N_("premature end of kernel file %s"), 369 | + path); 370 | + goto fail; 371 | + } 372 | + 373 | + if (grub_verify_file (path) == GRUB_ERR_NONE) 374 | + grub_dprintf ("linux", "kernel %s verified\n", path); 375 | + else 376 | + grub_error (grub_errno, N_("failed to verify kernel %s"), path); 377 | + 378 | +fail: 379 | + if (buf) 380 | + grub_free (buf); 381 | + 382 | + grub_file_close (file); 383 | + 384 | + return grub_errno; 385 | +} 386 | +#else 387 | +static grub_err_t 388 | +grub_verify_linux (const char *path) 389 | +{ 390 | + return GRUB_ERR_NONE; 391 | +} 392 | +#endif 393 | + 394 | static grub_err_t 395 | grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), 396 | int argc, char *argv[]) 397 | @@ -687,6 +739,9 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), 398 | goto fail; 399 | } 400 | 401 | + if (grub_verify_linux (argv[0])) 402 | + goto fail; 403 | + 404 | file = grub_file_open (argv[0]); 405 | if (! file) 406 | goto fail; 407 | @@ -1132,6 +1187,26 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)), 408 | argv[i]); 409 | goto fail; 410 | } 411 | + 412 | +#ifdef GRUB_MACHINE_EFI 413 | + grub_dprintf ("linux", "Verifying initrd %s, addr=0x%lx, size=0x%lx\n", 414 | + argv[i], (unsigned long) ptr, (unsigned long) cursize); 415 | + 416 | + /* 417 | + * XXX: use grub_verify_file_buffer (argv[i], ptr, cursize) in future 418 | + */ 419 | + err = grub_verify_file (argv[i]); 420 | + if (err == GRUB_ERR_NONE) 421 | + { 422 | + grub_dprintf ("linux", "initrd %s verified\n", argv[i]); 423 | + } 424 | + else 425 | + { 426 | + grub_error (err, N_("failed to verify initrd %s"), argv[i]); 427 | + goto fail; 428 | + } 429 | +#endif 430 | + 431 | ptr += cursize; 432 | grub_memset (ptr, 0, ALIGN_UP_OVERHEAD (cursize, 4)); 433 | ptr += ALIGN_UP_OVERHEAD (cursize, 4); 434 | @@ -1149,6 +1224,11 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)), 435 | grub_file_close (files[i]); 436 | grub_free (files); 437 | 438 | +#ifdef GRUB_MACHINE_EFI 439 | + /* An unauthenticated initrd always causes a complete boot failure. */ 440 | + if (grub_is_secured () == 1 && grub_errno != GRUB_ERR_NONE) 441 | + grub_loader_unset(); 442 | +#endif 443 | return grub_errno; 444 | } 445 | 446 | diff --git a/grub-core/normal/main.c b/grub-core/normal/main.c 447 | index 13473ec..f11ce2a 100644 448 | --- a/grub-core/normal/main.c 449 | +++ b/grub-core/normal/main.c 450 | @@ -32,6 +32,9 @@ 451 | #include 452 | #include 453 | #include 454 | +#ifdef GRUB_MACHINE_EFI 455 | +#include 456 | +#endif 457 | 458 | GRUB_MOD_LICENSE ("GPLv3+"); 459 | 460 | @@ -233,6 +236,16 @@ grub_normal_init_page (struct grub_term_output *term) 461 | 462 | grub_term_cls (term); 463 | 464 | +#ifdef GRUB_MACHINE_EFI 465 | + if (grub_is_secured () == 1) 466 | + { 467 | + if (grub_is_unlockable () == 1) 468 | + msg = _("GNU GRUB version %s (UNLOCKABLE)"); 469 | + else 470 | + msg = _("GNU GRUB version %s (LOCKED)"); 471 | + } 472 | +#endif 473 | + 474 | msg_formatted = grub_xasprintf (msg, PACKAGE_VERSION); 475 | if (!msg_formatted) 476 | return; 477 | @@ -294,6 +307,24 @@ grub_normal_execute (const char *config, int nested, int batch) 478 | 479 | if (config) 480 | { 481 | +#ifdef GRUB_MACHINE_EFI 482 | + grub_err_t err; 483 | + 484 | + err = grub_verify_file (config); 485 | + if (err != GRUB_ERR_NONE) 486 | + { 487 | + grub_error (err, "Security Violation: grub.cfg failed to load"); 488 | + grub_print_error (); 489 | + 490 | + /* System halt. */ 491 | + asm volatile ("cli"); 492 | + while (1) 493 | + { 494 | + asm volatile ("hlt"); 495 | + } 496 | + } 497 | +#endif 498 | + 499 | menu = read_config_file (config); 500 | 501 | /* Ignore any error. */ 502 | @@ -317,7 +348,10 @@ grub_enter_normal_mode (const char *config) 503 | { 504 | nested_level++; 505 | grub_normal_execute (config, 0, 0); 506 | - grub_cmdline_run (0); 507 | +#ifdef GRUB_MACHINE_EFI 508 | + if (grub_is_locked () == 0) 509 | +#endif 510 | + grub_cmdline_run (0); 511 | nested_level--; 512 | if (grub_normal_exit_level) 513 | grub_normal_exit_level--; 514 | @@ -352,6 +386,18 @@ grub_cmd_normal (struct grub_command *cmd __attribute__ ((unused)), 515 | grub_enter_normal_mode (argv[0]); 516 | 517 | quit: 518 | +#ifdef GRUB_MACHINE_EFI 519 | + if (grub_is_secured () == 1) 520 | + { 521 | + /* Never return back to the rescue mode */ 522 | + asm volatile ("cli"); 523 | + 524 | + while (1) 525 | + { 526 | + asm volatile ("hlt"); 527 | + } 528 | + } 529 | +#endif 530 | return 0; 531 | } 532 | 533 | @@ -527,8 +573,11 @@ GRUB_MOD_INIT(normal) 534 | /* Register a command "normal" for the rescue mode. */ 535 | grub_register_command ("normal", grub_cmd_normal, 536 | 0, N_("Enter normal mode.")); 537 | - grub_register_command ("normal_exit", grub_cmd_normal_exit, 538 | - 0, N_("Exit from normal mode.")); 539 | +#ifdef GRUB_MACHINE_EFI 540 | + if (grub_is_secured () == 0) 541 | +#endif 542 | + grub_register_command ("normal_exit", grub_cmd_normal_exit, 543 | + 0, N_("Exit from normal mode.")); 544 | 545 | /* Reload terminal colors when these variables are written to. */ 546 | grub_register_variable_hook ("color_normal", NULL, grub_env_write_color_normal); 547 | diff --git a/grub-core/normal/menu.c b/grub-core/normal/menu.c 548 | index 7e0a158..5ed9670 100644 549 | --- a/grub-core/normal/menu.c 550 | +++ b/grub-core/normal/menu.c 551 | @@ -32,6 +32,9 @@ 552 | #include 553 | #include 554 | #include 555 | +#ifdef GRUB_MACHINE_EFI 556 | +#include 557 | +#endif 558 | 559 | /* Time to delay after displaying an error message about a default/fallback 560 | entry failing to boot. */ 561 | @@ -633,18 +636,28 @@ run_menu (grub_menu_t menu, int nested, int *auto_boot) 562 | break; 563 | 564 | case 'c': 565 | - menu_fini (); 566 | - grub_cmdline_run (1); 567 | - goto refresh; 568 | +#ifdef GRUB_MACHINE_EFI 569 | + if (grub_is_locked () == 0) 570 | +#endif 571 | + { 572 | + menu_fini (); 573 | + grub_cmdline_run (1); 574 | + goto refresh; 575 | + } 576 | 577 | case 'e': 578 | - menu_fini (); 579 | +#ifdef GRUB_MACHINE_EFI 580 | + if (grub_is_locked () == 0) 581 | +#endif 582 | { 583 | - grub_menu_entry_t e = grub_menu_get_entry (menu, current_entry); 584 | - if (e) 585 | - grub_menu_entry_run (e); 586 | + menu_fini (); 587 | + { 588 | + grub_menu_entry_t e = grub_menu_get_entry (menu, current_entry); 589 | + if (e) 590 | + grub_menu_entry_run (e); 591 | + } 592 | + goto refresh; 593 | } 594 | - goto refresh; 595 | 596 | default: 597 | { 598 | diff --git a/grub-core/normal/menu_text.c b/grub-core/normal/menu_text.c 599 | index 1687c28..6e4fbfb 100644 600 | --- a/grub-core/normal/menu_text.c 601 | +++ b/grub-core/normal/menu_text.c 602 | @@ -27,6 +27,9 @@ 603 | #include 604 | #include 605 | #include 606 | +#ifdef GRUB_MACHINE_EFI 607 | +#include 608 | +#endif 609 | 610 | static grub_uint8_t grub_color_menu_normal; 611 | static grub_uint8_t grub_color_menu_highlight; 612 | @@ -179,19 +182,32 @@ command-line or ESC to discard edits and return to the GRUB menu."), 613 | 614 | if (nested) 615 | { 616 | +#ifdef GRUB_MACHINE_EFI 617 | + if (grub_is_locked () == 1) 618 | + msg = _("Press enter to boot the selected OS. " 619 | + "ESC to return previous menu."); 620 | + else 621 | +#endif 622 | + msg = _("Press enter to boot the selected OS, " 623 | + "`e' to edit the commands before booting " 624 | + "or `c' for a command-line. ESC to return previous menu."); 625 | + 626 | ret += grub_print_message_indented_real 627 | - (_("Press enter to boot the selected OS, " 628 | - "`e' to edit the commands before booting " 629 | - "or `c' for a command-line. ESC to return previous menu."), 630 | - STANDARD_MARGIN, STANDARD_MARGIN, term, dry_run); 631 | + (msg, STANDARD_MARGIN, STANDARD_MARGIN, term, dry_run); 632 | } 633 | else 634 | { 635 | +#ifdef GRUB_MACHINE_EFI 636 | + if (grub_is_locked () == 1) 637 | + msg = _("Press enter to boot the selected OS."); 638 | + else 639 | +#endif 640 | + msg = _("Press enter to boot the selected OS, " 641 | + "`e' to edit the commands before booting " 642 | + "or `c' for a command-line."); 643 | + 644 | ret += grub_print_message_indented_real 645 | - (_("Press enter to boot the selected OS, " 646 | - "`e' to edit the commands before booting " 647 | - "or `c' for a command-line."), 648 | - STANDARD_MARGIN, STANDARD_MARGIN, term, dry_run); 649 | + (msg, STANDARD_MARGIN, STANDARD_MARGIN, term, dry_run); 650 | } 651 | } 652 | return ret; 653 | diff --git a/include/grub/efi/mok2verify.h b/include/grub/efi/mok2verify.h 654 | new file mode 100644 655 | index 0000000..98ef2d4 656 | --- /dev/null 657 | +++ b/include/grub/efi/mok2verify.h 658 | @@ -0,0 +1,48 @@ 659 | +/* 660 | + * mok2verify.h - interface to MOK2 Verify Protocol 661 | + * 662 | + * BSD 2-clause "Simplified" License 663 | + * 664 | + * Copyright (c) 2017, Lans Zhang 665 | + * All rights reserved. 666 | + * 667 | + * Redistribution and use in source and binary forms, with or without 668 | + * modification, are permitted provided that the following conditions are met: 669 | + * 670 | + * * Redistributions of source code must retain the above copyright notice, this 671 | + * list of conditions and the following disclaimer. 672 | + * 673 | + * * Redistributions in binary form must reproduce the above copyright notice, 674 | + * this list of conditions and the following disclaimer in the documentation 675 | + * and/or other materials provided with the distribution. 676 | + * 677 | + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 678 | + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 679 | + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 680 | + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 681 | + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 682 | + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 683 | + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 684 | + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 685 | + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 686 | + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 687 | + */ 688 | + 689 | +#ifndef GRUB_EFI_MOK2_VERIFY_HEADER 690 | +#define GRUB_EFI_MOK2_VERIFY_HEADER 1 691 | + 692 | +#include 693 | + 694 | +int 695 | +EXPORT_FUNC (grub_is_secured) (void); 696 | + 697 | +int 698 | +EXPORT_FUNC (grub_is_locked) (void); 699 | + 700 | +int 701 | +EXPORT_FUNC (grub_is_unlockable) (void); 702 | + 703 | +grub_err_t 704 | +EXPORT_FUNC (grub_verify_file) (const char *path); 705 | + 706 | +#endif /* ! GRUB_EFI_MOK2_VERIFY_HEADER */ 707 | -- 708 | 2.7.4 709 | 710 | -------------------------------------------------------------------------------- /recipes-bsp/grub/grub-efi/password.inc: -------------------------------------------------------------------------------- 1 | set superusers="root" 2 | password_pbkdf2 root grub.pbkdf2.sha512.10000.4039B6F2AC3D0E349479D2573BC4B206E022E9308DBCBA8F42FBBBF64B699B79A5426CE58503ACBB37CA4116CA1B95C89BEC5F804CB91C8ED5A7381C9E03EDE8.69E763E475CF993A6B4954F9BA863E45E8DFAF2BCEBEAAB21319DC766287FA1A621807F6E2AAD9277A6BA3B9B56A14C0918C441EE47BE304D23ADA562CA018E9 3 | -------------------------------------------------------------------------------- /recipes-bsp/grub/grub-efi/serial-redirect-control-x-fix.patch: -------------------------------------------------------------------------------- 1 | --- 2 | grub-core/term/efi/console.c | 9 ++++++--- 3 | 1 file changed, 6 insertions(+), 3 deletions(-) 4 | 5 | --- a/grub-core/term/efi/console.c 6 | +++ b/grub-core/term/efi/console.c 7 | @@ -124,9 +124,12 @@ grub_console_getkey (struct grub_term_in 8 | if (status != GRUB_EFI_SUCCESS) 9 | return GRUB_TERM_NO_KEY; 10 | 11 | - if (key.scan_code == 0) 12 | - return key.unicode_char; 13 | - else if (key.scan_code < ARRAY_SIZE (efi_codes)) 14 | + if (key.scan_code == 0) { 15 | + if (key.unicode_char < 0x20 && key.unicode_char != 0 && key.unicode_char != '\t' && key.unicode_char != '\b' && key.unicode_char != '\n' && key.unicode_char != '\r') 16 | + return GRUB_TERM_CTRL | (key.unicode_char - 1 + 'a'); 17 | + else 18 | + return key.unicode_char; 19 | + } else if (key.scan_code < ARRAY_SIZE (efi_codes)) 20 | return efi_codes[key.scan_code]; 21 | 22 | return GRUB_TERM_NO_KEY; 23 | -------------------------------------------------------------------------------- /recipes-bsp/grub/grub-efi_2.00.bbappend: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2016-2017 Wind River Systems, Inc. 3 | # 4 | 5 | FILESEXTRAPATHS_prepend := "${THISDIR}/grub-efi:" 6 | 7 | EXTRA_SRC_URI = " \ 8 | ${@'file://efi-secure-boot.inc file://password.inc' if d.getVar('UEFI_SB', True) == '1' else ''} \ 9 | " 10 | 11 | SRC_URI += " \ 12 | file://0001-pe32.h-add-header-structures-for-TE-and-DOS-executab.patch \ 13 | file://0002-shim-add-needed-data-structures.patch \ 14 | file://0003-efi-chainloader-implement-an-UEFI-Exit-service-for-s.patch \ 15 | file://0004-efi-chainloader-port-shim-to-grub.patch \ 16 | file://0005-efi-chainloader-use-shim-to-load-and-verify-an-image.patch \ 17 | file://0006-efi-chainloader-boot-the-image-using-shim.patch \ 18 | file://0007-efi-chainloader-take-care-of-unload-undershim.patch \ 19 | file://chainloader-handle-the-unauthenticated-image-by-shim.patch \ 20 | file://chainloader-Don-t-check-empty-section-in-file-like-..patch \ 21 | file://chainloader-Actually-find-the-relocations-correctly-.patch \ 22 | file://Fix-32-bit-build-failures.patch \ 23 | file://Grub-get-and-set-efi-variables.patch \ 24 | file://grub-efi.cfg \ 25 | file://boot-menu.inc \ 26 | file://boot-menu-hddimg.inc \ 27 | file://serial-redirect-control-x-fix.patch \ 28 | file://mok2verify-support-to-verify-non-PE-file-with-PKCS-7.patch \ 29 | ${EXTRA_SRC_URI} \ 30 | " 31 | 32 | GRUB_BUILDIN_append = " chain ${@'efivar mok2verify password_pbkdf2' if d.getVar('UEFI_SB', True) == '1' else ''}" 33 | 34 | # For efi_call_foo and efi_shim_exit 35 | CFLAGS_append = " -fno-toplevel-reorder" 36 | 37 | # Set a default root specifier. 38 | inherit user-key-store 39 | 40 | python __anonymous () { 41 | if d.getVar('UEFI_SB', True) != "1": 42 | return 43 | 44 | # Override the default filename if efi-secure-boot enabled. 45 | # grub-efi must be renamed as grub${arch}.efi for working with shim 46 | # or SELoader. 47 | import re 48 | 49 | target = d.getVar('TARGET_ARCH', True) 50 | if target == "x86_64": 51 | grubimage = "grubx64.efi" 52 | elif re.match('i.86', target): 53 | grubimage = "grubia32.efi" 54 | else: 55 | raise bb.parse.SkipPackage("grub-efi is incompatible with target %s" % target) 56 | 57 | d.setVar("GRUB_IMAGE", grubimage) 58 | } 59 | 60 | do_compile_append_class-native() { 61 | make grub-editenv 62 | } 63 | 64 | do_install_append_class-native() { 65 | install -m 0755 grub-editenv "${D}${bindir}" 66 | } 67 | 68 | do_install_append_class-target() { 69 | local menu="${WORKDIR}/boot-menu.inc" 70 | 71 | # Enable the default IMA rules if IMA is enabled and encrypted-storage is 72 | # disabled. This is because unseal operation will fail when any PCR is 73 | # extended due to updating the aggregate integrity value by the default 74 | # IMA rules. 75 | [ x"${IMA}" = x"1" -a x"${@bb.utils.contains('DISTRO_FEATURES', 'encrypted-storage', '1', '0', d)}" != x"1" ] && { 76 | ! grep -q "ima_policy=tcb" "$menu" && 77 | sed -i 's/^\s*linux\s\+.*bzImage.*/& ima_policy=tcb/g' "$menu" 78 | } 79 | 80 | [ x"${UEFI_SB}" = x"1" ] && { 81 | # Don't allow to load the detached initramfs if the bundled kernel used. 82 | [ x"${INITRAMFS_IMAGE_BUNDLE}" = x"1" ] && 83 | sed -i '/^\s*initrd\s\+.*initrd.*/d' "$menu" 84 | 85 | # Don't allow to load the detached initramfs if it was not built or signed properly. 86 | [ x"${INITRAMFS_IMAGE}" = x ] && 87 | sed -i '/^\s*initrd\s\+.*initrd.*/d' "$menu" 88 | } 89 | 90 | # Install the stacked grub configs. 91 | install -d "${D}${EFI_BOOT_PATH}" 92 | install -m 0600 "${WORKDIR}/grub-efi.cfg" "${D}${EFI_BOOT_PATH}/grub.cfg" 93 | install -m 0600 "$menu" "${D}${EFI_BOOT_PATH}" 94 | [ x"${UEFI_SB}" = x"1" ] && { 95 | install -m 0600 "${WORKDIR}/efi-secure-boot.inc" "${D}${EFI_BOOT_PATH}" 96 | install -m 0600 "${WORKDIR}/password.inc" "${D}${EFI_BOOT_PATH}" 97 | } 98 | 99 | # Create the initial environment block with empty item. 100 | grub-editenv "${D}${EFI_BOOT_PATH}/grubenv" create 101 | } 102 | 103 | fakeroot python do_sign_class-target() { 104 | image_dir = d.getVar('D', True) 105 | efi_boot_path = d.getVar('EFI_BOOT_PATH', True) 106 | grub_image = d.getVar('GRUB_IMAGE', True) 107 | dir = image_dir + efi_boot_path + '/' 108 | 109 | sb_sign(dir + grub_image, dir + grub_image, d) 110 | uks_sel_sign(dir + 'grub.cfg', d) 111 | uks_sel_sign(dir + 'boot-menu.inc', d) 112 | uks_sel_sign(image_dir + '/../boot-menu-hddimg.inc', d) 113 | 114 | if d.getVar('UEFI_SB', True) == "1": 115 | uks_sel_sign(dir + 'efi-secure-boot.inc', d) 116 | uks_sel_sign(dir + 'password.inc', d) 117 | } 118 | 119 | fakeroot python do_sign() { 120 | } 121 | addtask sign after do_install before do_deploy do_package 122 | 123 | do_deploy_append_class-target() { 124 | install -d "${DEPLOYDIR}/efi-unsigned" 125 | 126 | install -m 0600 "${B}/${GRUB_IMAGE}" "${DEPLOYDIR}/efi-unsigned" 127 | cp -af "${D}${EFI_BOOT_PATH}/${GRUB_TARGET}-efi" "${DEPLOYDIR}/efi-unsigned" 128 | 129 | if [ x"${UEFI_SB}" = x"1" ]; then 130 | cp -f "${WORKDIR}/boot-menu-hddimg.inc" "${DEPLOYDIR}" 131 | cp -f "${WORKDIR}/boot-menu-hddimg.inc.p7b" "${DEPLOYDIR}" 132 | fi 133 | } 134 | 135 | CONFFILES_${PN} += " \ 136 | ${EFI_BOOT_PATH}/grubenv \ 137 | ${EFI_BOOT_PATH}/boot-menu.inc \ 138 | ${EFI_BOOT_PATH}/efi-secure-boot.inc \ 139 | " 140 | -------------------------------------------------------------------------------- /recipes-bsp/seloader/seloader_git.bb: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2017 Wind River Systems, Inc. 3 | # 4 | 5 | SUMMARY = "The bootloader capable of authenticating the PE and non-PE files." 6 | DESCRIPTION = "The SELoader is designed to authenticate the non-PE files, \ 7 | such as grub configuration, initrd, grub modules, which cannot be verified \ 8 | by the MOK Verify Protocol registered by shim loader. \ 9 | \ 10 | In order to conveniently authenticate the PE file with gBS->LoadImage() \ 11 | and gBS->StartImage(), the SELoader hooks EFI Security2 Architectural \ 12 | Protocol and employs MOK Verify Protocol to verify the PE file. If only \ 13 | UEFI Secure Boot is enabled, the SELoader just simplily calls \ 14 | gBS->LoadImage() and gBS->StartImage() to allow BIOS to verify PE file. \ 15 | \ 16 | The SELoader publishes MOK2 Verify Protocol which provides a flexible \ 17 | interface to allow the bootloader to verify the file, file buffer or \ 18 | memory buffer without knowing the file format. \ 19 | " 20 | HOMEPAGE = "https://github.com/jiazhang0/SELoader.git" 21 | SECTION = "bootloaders" 22 | 23 | LICENSE = "BSD-3-Clause" 24 | LIC_FILES_CHKSUM = "file://LICENSE;md5=d9bf404642f21afb4ad89f95d7bc91ee" 25 | PR = "r0" 26 | SRC_URI = " \ 27 | git://github.com/jiazhang0/SELoader.git \ 28 | " 29 | SRCREV = "e6c6cbe6405f01d58f9e9cbb0115a12ae49454a0" 30 | PV = "0.4.5+git${SRCPV}" 31 | 32 | COMPATIBLE_HOST = '(i.86|x86_64).*-linux' 33 | 34 | inherit deploy user-key-store 35 | 36 | S = "${WORKDIR}/git" 37 | DEPENDS += " \ 38 | gnu-efi sbsigntool-native \ 39 | " 40 | 41 | EFI_ARCH_x86 = "ia32" 42 | EFI_ARCH_x86-64 = "x64" 43 | 44 | EXTRA_OEMAKE = " \ 45 | CROSS_COMPILE="${TARGET_PREFIX}" \ 46 | SBSIGN=${STAGING_BINDIR_NATIVE}/sbsign \ 47 | gnuefi_libdir=${STAGING_LIBDIR} \ 48 | LIB_GCC="`${CC} -print-libgcc-file-name`" \ 49 | GNU_EFI_VERSION=303 \ 50 | " 51 | 52 | PARALLEL_MAKE = "" 53 | 54 | EFI_TARGET = "/boot/efi/EFI/BOOT" 55 | FILES_${PN} += "${EFI_TARGET}" 56 | 57 | python do_sign() { 58 | sb_sign(d.expand('${B}/Src/Efi/SELoader.efi'), d.expand('${B}/Src/Efi/SELoader.efi.signed'), d) 59 | sb_sign(d.expand('${B}/Bin/Hash2DxeCrypto.efi'), d.expand('${B}/Bin/Hash2DxeCrypto.efi.signed'), d) 60 | sb_sign(d.expand('${B}/Bin/Pkcs7VerifyDxe.efi'), d.expand('${B}/Bin/Pkcs7VerifyDxe.efi.signed'), d) 61 | } 62 | addtask sign after do_compile before do_install 63 | 64 | do_install() { 65 | install -d ${D}${EFI_TARGET} 66 | 67 | oe_runmake install EFI_DESTDIR=${D}${EFI_TARGET} 68 | 69 | if [ x"${UEFI_SB}" = x"1" ]; then 70 | if [ x"${MOK_SB}" != x"1" ]; then 71 | mv ${D}${EFI_TARGET}/SELoader${EFI_ARCH}.efi \ 72 | ${D}${EFI_TARGET}/boot${EFI_ARCH}.efi 73 | fi 74 | fi 75 | } 76 | 77 | do_deploy() { 78 | # Deploy the unsigned images for manual signing 79 | install -d ${DEPLOYDIR}/efi-unsigned 80 | 81 | install -m 0600 ${B}/Src/Efi/SELoader.efi \ 82 | ${DEPLOYDIR}/efi-unsigned/SELoader${EFI_ARCH}.efi 83 | install -m 0600 ${B}/Bin/Hash2DxeCrypto.efi ${DEPLOYDIR}/efi-unsigned/ 84 | install -m 0600 ${B}/Bin/Pkcs7VerifyDxe.efi ${DEPLOYDIR}/efi-unsigned/ 85 | 86 | # Deploy the signed images 87 | if [ x"${UEFI_SB}" = x"1" -a x"${MOK_SB}" != x"1" ]; then 88 | SEL_NAME=boot 89 | else 90 | SEL_NAME=SELoader 91 | fi 92 | install -m 0600 ${D}${EFI_TARGET}/${SEL_NAME}${EFI_ARCH}.efi \ 93 | ${DEPLOYDIR}/${SEL_NAME}${EFI_ARCH}.efi 94 | install -m 0600 ${D}${EFI_TARGET}/Hash2DxeCrypto.efi \ 95 | ${DEPLOYDIR}/Hash2DxeCrypto.efi 96 | install -m 0600 ${D}${EFI_TARGET}/Pkcs7VerifyDxe.efi \ 97 | ${DEPLOYDIR}/Pkcs7VerifyDxe.efi 98 | } 99 | addtask deploy after do_install before do_build 100 | -------------------------------------------------------------------------------- /recipes-bsp/shim/shim/0001-shim-allow-to-verify-sha1-digest-for-Authenticode.patch: -------------------------------------------------------------------------------- 1 | From 88806eaf9f1726d06eb4e88f12ca86537dbaab75 Mon Sep 17 00:00:00 2001 2 | From: Lans Zhang 3 | Date: Fri, 16 Jun 2017 15:16:35 +0800 4 | Subject: [PATCH] shim: allow to verify sha1 digest for Authenticode 5 | 6 | Upstream-Status: Pending 7 | 8 | The EV code signing cert sometimes doesn't comply the Authenticode spec to 9 | employ a sha256 digest. 10 | 11 | Signed-off-by: Lans Zhang 12 | --- 13 | shim.c | 48 +++++++++++++++++++++++++++++++++++------------- 14 | 1 file changed, 35 insertions(+), 13 deletions(-) 15 | 16 | diff --git a/shim.c b/shim.c 17 | index 6e040c4..384ccd7 100644 18 | --- a/shim.c 19 | +++ b/shim.c 20 | @@ -428,7 +428,8 @@ static BOOLEAN verify_eku(UINT8 *Cert, UINTN CertSize) 21 | static CHECK_STATUS check_db_cert_in_ram(EFI_SIGNATURE_LIST *CertList, 22 | UINTN dbsize, 23 | WIN_CERTIFICATE_EFI_PKCS *data, 24 | - UINT8 *hash) 25 | + UINT8 *hash, 26 | + UINTN hashsize) 27 | { 28 | EFI_SIGNATURE_DATA *Cert; 29 | UINTN CertSize; 30 | @@ -445,7 +446,7 @@ static CHECK_STATUS check_db_cert_in_ram(EFI_SIGNATURE_LIST *CertList, 31 | data->Hdr.dwLength - sizeof(data->Hdr), 32 | Cert->SignatureData, 33 | CertSize, 34 | - hash, SHA256_DIGEST_SIZE); 35 | + hash, hashsize); 36 | if (IsFound) 37 | return DATA_FOUND; 38 | } 39 | @@ -462,7 +463,7 @@ static CHECK_STATUS check_db_cert_in_ram(EFI_SIGNATURE_LIST *CertList, 40 | } 41 | 42 | static CHECK_STATUS check_db_cert(CHAR16 *dbname, EFI_GUID guid, 43 | - WIN_CERTIFICATE_EFI_PKCS *data, UINT8 *hash) 44 | + WIN_CERTIFICATE_EFI_PKCS *data, UINT8 *hash, UINTN hashsize) 45 | { 46 | CHECK_STATUS rc; 47 | EFI_STATUS efi_status; 48 | @@ -477,7 +478,7 @@ static CHECK_STATUS check_db_cert(CHAR16 *dbname, EFI_GUID guid, 49 | 50 | CertList = (EFI_SIGNATURE_LIST *)db; 51 | 52 | - rc = check_db_cert_in_ram(CertList, dbsize, data, hash); 53 | + rc = check_db_cert_in_ram(CertList, dbsize, data, hash, hashsize); 54 | 55 | FreePool(db); 56 | 57 | @@ -571,7 +572,8 @@ static EFI_STATUS check_blacklist (WIN_CERTIFICATE_EFI_PKCS *cert, 58 | DATA_FOUND) 59 | return EFI_SECURITY_VIOLATION; 60 | if (cert && check_db_cert_in_ram(dbx, vendor_dbx_size, cert, 61 | - sha256hash) == DATA_FOUND) 62 | + sha256hash, SHA256_DIGEST_SIZE) == 63 | + DATA_FOUND) 64 | return EFI_SECURITY_VIOLATION; 65 | 66 | if (check_db_hash(L"dbx", secure_var, sha256hash, SHA256_DIGEST_SIZE, 67 | @@ -580,14 +582,14 @@ static EFI_STATUS check_blacklist (WIN_CERTIFICATE_EFI_PKCS *cert, 68 | if (check_db_hash(L"dbx", secure_var, sha1hash, SHA1_DIGEST_SIZE, 69 | EFI_CERT_SHA1_GUID) == DATA_FOUND) 70 | return EFI_SECURITY_VIOLATION; 71 | - if (cert && check_db_cert(L"dbx", secure_var, cert, sha256hash) == 72 | + if (cert && check_db_cert(L"dbx", secure_var, cert, sha256hash, SHA256_DIGEST_SIZE) == 73 | DATA_FOUND) 74 | return EFI_SECURITY_VIOLATION; 75 | if (check_db_hash(L"MokListX", shim_var, sha256hash, SHA256_DIGEST_SIZE, 76 | EFI_CERT_SHA256_GUID) == DATA_FOUND) { 77 | return EFI_SECURITY_VIOLATION; 78 | } 79 | - if (cert && check_db_cert(L"MokListX", shim_var, cert, sha256hash) == 80 | + if (cert && check_db_cert(L"MokListX", shim_var, cert, sha256hash, SHA256_DIGEST_SIZE) == 81 | DATA_FOUND) { 82 | return EFI_SECURITY_VIOLATION; 83 | } 84 | @@ -622,7 +624,7 @@ static EFI_STATUS check_whitelist (WIN_CERTIFICATE_EFI_PKCS *cert, 85 | update_verification_method(VERIFIED_BY_HASH); 86 | return EFI_SUCCESS; 87 | } 88 | - if (cert && check_db_cert(L"db", secure_var, cert, sha256hash) 89 | + if (cert && check_db_cert(L"db", secure_var, cert, sha256hash, SHA256_DIGEST_SIZE) 90 | == DATA_FOUND) { 91 | verification_method = VERIFIED_BY_CERT; 92 | update_verification_method(VERIFIED_BY_CERT); 93 | @@ -636,7 +638,7 @@ static EFI_STATUS check_whitelist (WIN_CERTIFICATE_EFI_PKCS *cert, 94 | update_verification_method(VERIFIED_BY_HASH); 95 | return EFI_SUCCESS; 96 | } 97 | - if (cert && check_db_cert(L"MokList", shim_var, cert, sha256hash) == 98 | + if (cert && check_db_cert(L"MokList", shim_var, cert, sha256hash, SHA256_DIGEST_SIZE) == 99 | DATA_FOUND) { 100 | verification_method = VERIFIED_BY_CERT; 101 | update_verification_method(VERIFIED_BY_CERT); 102 | @@ -1020,27 +1022,47 @@ static EFI_STATUS verify_buffer (char *data, int datasize, 103 | /* 104 | * Check against the shim build key 105 | */ 106 | - if (sizeof(shim_cert) && 107 | - AuthenticodeVerify(cert->CertData, 108 | + if (sizeof(shim_cert)) { 109 | + if (AuthenticodeVerify(cert->CertData, 110 | cert->Hdr.dwLength - sizeof(cert->Hdr), 111 | shim_cert, sizeof(shim_cert), sha256hash, 112 | SHA256_DIGEST_SIZE)) { 113 | update_verification_method(VERIFIED_BY_CERT); 114 | status = EFI_SUCCESS; 115 | return status; 116 | + } 117 | + 118 | + if (AuthenticodeVerify(cert->CertData, 119 | + cert->Hdr.dwLength - sizeof(cert->Hdr), 120 | + shim_cert, sizeof(shim_cert), sha1hash, 121 | + SHA1_DIGEST_SIZE)) { 122 | + update_verification_method(VERIFIED_BY_CERT); 123 | + status = EFI_SUCCESS; 124 | + return status; 125 | + } 126 | } 127 | 128 | /* 129 | * And finally, check against shim's built-in key 130 | */ 131 | - if (vendor_cert_size && 132 | - AuthenticodeVerify(cert->CertData, 133 | + if (vendor_cert_size) { 134 | + if (AuthenticodeVerify(cert->CertData, 135 | cert->Hdr.dwLength - sizeof(cert->Hdr), 136 | vendor_cert, vendor_cert_size, 137 | sha256hash, SHA256_DIGEST_SIZE)) { 138 | update_verification_method(VERIFIED_BY_CERT); 139 | status = EFI_SUCCESS; 140 | return status; 141 | + } 142 | + 143 | + if (AuthenticodeVerify(cert->CertData, 144 | + cert->Hdr.dwLength - sizeof(cert->Hdr), 145 | + vendor_cert, vendor_cert_size, 146 | + sha1hash, SHA1_DIGEST_SIZE)) { 147 | + update_verification_method(VERIFIED_BY_CERT); 148 | + status = EFI_SUCCESS; 149 | + return status; 150 | + } 151 | } 152 | } 153 | 154 | -- 155 | 2.7.5 156 | 157 | -------------------------------------------------------------------------------- /recipes-bsp/shim/shim/0005-Fix-signing-failure-due-to-not-finding-certificate.patch: -------------------------------------------------------------------------------- 1 | From 85e74fa95094175753e39acdd694f9c639069abf Mon Sep 17 00:00:00 2001 2 | From: Lans Zhang 3 | Date: Fri, 18 Mar 2016 12:30:08 +0800 4 | Subject: [PATCH 05/11] Fix signing failure due to not finding certificate 5 | 6 | Upstream-Status: Pending 7 | 8 | The shim.p12 containing private sample key should be imported after 9 | importing the corresponding certificate shim.crt. Otherwise, the 10 | nick name of shim certificate cannot be used. 11 | 12 | Signed-off-by: Lans Zhang 13 | --- 14 | Makefile | 4 ++-- 15 | 1 file changed, 2 insertions(+), 2 deletions(-) 16 | 17 | diff --git a/Makefile b/Makefile 18 | index dcfa357..efab050 100644 19 | --- a/Makefile 20 | +++ b/Makefile 21 | @@ -124,10 +124,10 @@ version.c : version.c.in 22 | -e "s,@@COMMIT@@,$(shell if [ -d .git ] ; then git log -1 --pretty=format:%H ; elif [ -f commit ]; then cat commit ; else echo commit id not available; fi)," \ 23 | < version.c.in > version.c 24 | 25 | -certdb/secmod.db: shim.crt 26 | +certdb/secmod.db: shim.crt shim.p12 27 | -mkdir certdb 28 | - $(PK12UTIL) -d certdb/ -i shim.p12 -W "" -K "" 29 | $(CERTUTIL) -d certdb/ -A -i shim.crt -n shim -t u 30 | + $(PK12UTIL) -d certdb/ -i shim.p12 -W "" -K "" 31 | 32 | shim.o: $(SOURCES) shim_cert.h 33 | shim.o: $(wildcard *.h) 34 | -- 35 | 2.11.0 36 | 37 | -------------------------------------------------------------------------------- /recipes-bsp/shim/shim/0006-Prevent-from-removing-intermediate-.efi.patch: -------------------------------------------------------------------------------- 1 | From 1f03018aa0b7df2eab576d410ec88e8cf66b06e0 Mon Sep 17 00:00:00 2001 2 | From: Lans Zhang 3 | Date: Wed, 21 Sep 2016 11:25:14 +0800 4 | Subject: [PATCH 06/11] Prevent from removing intermediate .efi 5 | 6 | Upstream-Status: Pending 7 | 8 | Otherwise Make will delete the .efi during the build: 9 | sysroots/x86_64-linux/usr/bin/pesign -n certdb -i MokManager.efi -c "shim" -s -o MokManager.efi.signed -f 10 | rm fallback.efi MokManager.efi 11 | DEBUG: Shell function do_compile finished 12 | 13 | Signed-off-by: Lans Zhang 14 | --- 15 | Makefile | 2 ++ 16 | 1 file changed, 2 insertions(+) 17 | 18 | diff --git a/Makefile b/Makefile 19 | index efab050..7c71993 100644 20 | --- a/Makefile 21 | +++ b/Makefile 22 | @@ -100,6 +100,8 @@ MOK_SOURCES = MokManager.c shim.h include/console.h PasswordCrypt.c PasswordCryp 23 | FALLBACK_OBJS = fallback.o 24 | FALLBACK_SRCS = fallback.c 25 | 26 | +.PRECIOUS: $(MMNAME).efi $(FBNAME).efi 27 | + 28 | ifneq ($(origin ENABLE_HTTPBOOT), undefined) 29 | OBJS += httpboot.o 30 | SOURCES += httpboot.c httpboot.h 31 | -- 32 | 2.11.0 33 | 34 | -------------------------------------------------------------------------------- /recipes-bsp/shim/shim/0007-Use-sbsign-to-sign-MokManager-and-fallback.patch: -------------------------------------------------------------------------------- 1 | From 04da6c928d5f15b7adb6c51e55b9aa0a8126063d Mon Sep 17 00:00:00 2001 2 | From: Lans Zhang 3 | Date: Wed, 21 Sep 2016 11:31:02 +0800 4 | Subject: [PATCH 07/11] Use sbsign to sign MokManager and fallback 5 | 6 | Upstream-Status: Pending 7 | 8 | pesign is written with -std=gnu11 and thus the host gcc version lower 9 | than 4.7 cannot build out pesign. 10 | 11 | sbsign is another alternate used to sign efi binary and it works well. 12 | Therefore, drop to use sbsign to sign efi binary. 13 | 14 | Signed-off-by: Lans Zhang 15 | --- 16 | Makefile | 5 +++-- 17 | 1 file changed, 3 insertions(+), 2 deletions(-) 18 | 19 | diff --git a/Makefile b/Makefile 20 | index 7c71993..58b4b4c 100644 21 | --- a/Makefile 22 | +++ b/Makefile 23 | @@ -12,6 +12,7 @@ HEXDUMP ?= hexdump 24 | PK12UTIL ?= pk12util 25 | CERTUTIL ?= certutil 26 | PESIGN ?= pesign 27 | +SBSIGN ?= sbsign 28 | 29 | ARCH = $(shell $(CC) -dumpmachine | cut -f1 -d- | sed s,i[3456789]86,ia32,) 30 | OBJCOPY_GTE224 = $(shell expr `$(OBJCOPY) --version |grep ^"GNU objcopy" | sed 's/^.*\((.*)\|version\) //g' | cut -f1-2 -d.` \>= 2.24) 31 | @@ -190,8 +191,8 @@ endif 32 | -j .note.gnu.build-id \ 33 | $(FORMAT) $^ $@.debug 34 | 35 | -%.efi.signed: %.efi certdb/secmod.db 36 | - $(PESIGN) -n certdb -i $< -c "shim" -s -o $@ -f 37 | +%.efi.signed: %.efi shim.key shim.crt 38 | + $(SBSIGN) --key shim.key --cert shim.crt --output $@ $< 39 | 40 | clean: 41 | $(MAKE) -C Cryptlib clean 42 | -- 43 | 2.11.0 44 | 45 | -------------------------------------------------------------------------------- /recipes-bsp/shim/shim/0008-Fix-the-world-build-failure-due-to-the-missing-rule-.patch: -------------------------------------------------------------------------------- 1 | From 508a31905aff2d271f1b82a5a36a614113b7fe85 Mon Sep 17 00:00:00 2001 2 | From: Lans Zhang 3 | Date: Mon, 6 Jun 2016 16:28:09 +0800 4 | Subject: [PATCH 08/11] Fix the world build failure due to the missing rule of 5 | generating shim.key 6 | 7 | Upstream-Status: Pending 8 | 9 | shim.key is not given without feature/mok-secure-boot, the script 10 | make-certs already integrated in shim is able to generate it and shim.crt 11 | for signing. However, the commit 79c0d3ab3964ff03483277a515aaf50016bbe786 12 | forgets to add the rule of generating shim.key, causing the world build 13 | failure. 14 | 15 | Signed-off-by: Lans Zhang 16 | --- 17 | Makefile | 2 +- 18 | 1 file changed, 1 insertion(+), 1 deletion(-) 19 | 20 | diff --git a/Makefile b/Makefile 21 | index 58b4b4c..0da5e6c 100644 22 | --- a/Makefile 23 | +++ b/Makefile 24 | @@ -110,7 +110,7 @@ endif 25 | 26 | all: $(TARGET) 27 | 28 | -shim.crt: 29 | +shim.crt shim.key: 30 | ./make-certs shim shim@xn--u4h.net all codesign 1.3.6.1.4.1.311.10.3.1 3 | Date: Wed, 28 Dec 2016 11:08:37 +0800 4 | Subject: [PATCH 10/11] Makefile: do not sign the efi file 5 | 6 | Shim tries to sign all the efi binaries at build time, but is not 7 | suitable for us. Because the private key has to be supplied, and this 8 | doesn't make sense to EDSS key. 9 | 10 | We will use a seperated function in bitbake file to 11 | sign these efi binaries, so that we can freely use EDSS key, Wind 12 | River sample key or user key. 13 | 14 | Signed-off-by: Yunguo Wei 15 | Signed-off-by: Lans Zhang 16 | --- 17 | Makefile | 2 +- 18 | 1 file changed, 1 insertion(+), 1 deletion(-) 19 | 20 | diff --git a/Makefile b/Makefile 21 | index 24e21a8..0912cd0 100644 22 | --- a/Makefile 23 | +++ b/Makefile 24 | @@ -92,7 +92,7 @@ endif 25 | 26 | LDFLAGS = --hash-style=sysv -nostdlib -znocombreloc -T $(EFI_LDS) -shared -Bsymbolic -L$(EFI_PATH) -L$(LIB_PATH) -LCryptlib -LCryptlib/OpenSSL $(EFI_CRT_OBJS) --build-id=sha1 27 | 28 | -TARGET = $(SHIMNAME).efi $(MMNAME).efi.signed $(FBNAME).efi.signed 29 | +TARGET = $(SHIMNAME).efi $(MMNAME).efi $(FBNAME).efi 30 | OBJS = shim.o netboot.o cert.o replacements.o tpm.o version.o 31 | KEYS = shim_cert.h ocsp.* ca.* shim.crt shim.csr shim.p12 shim.pem shim.key shim.cer 32 | SOURCES = shim.c shim.h netboot.c include/PeImage.h include/wincert.h include/console.h replacements.c replacements.h tpm.c tpm.h version.c version.h 33 | -- 34 | 2.11.0 35 | 36 | -------------------------------------------------------------------------------- /recipes-bsp/shim/shim/0011-Update-verification_method-if-the-loaded-image-is-si.patch: -------------------------------------------------------------------------------- 1 | From 62489adc36c5177f90ed16af936a4c0a992cea7e Mon Sep 17 00:00:00 2001 2 | From: Lans Zhang 3 | Date: Wed, 21 Sep 2016 11:17:29 +0800 4 | Subject: [PATCH 11/11] Update verification_method if the loaded image is 5 | signed by shim/vendor cert 6 | 7 | Upstream-Status: Pending 8 | 9 | Also, if the loaded image is not verfied by cert, the validation process 10 | should be allowed as well. 11 | 12 | Signed-off-by: Lans Zhang 13 | --- 14 | replacements.c | 2 +- 15 | shim.c | 4 ++++ 16 | 2 files changed, 5 insertions(+), 1 deletion(-) 17 | 18 | diff --git a/replacements.c b/replacements.c 19 | index 01eda0e..9ed5a5d 100644 20 | --- a/replacements.c 21 | +++ b/replacements.c 22 | @@ -144,7 +144,7 @@ start_image(EFI_HANDLE image_handle, UINTN *exit_data_size, CHAR16 **exit_data) 23 | static EFI_STATUS EFIAPI 24 | exit_boot_services(EFI_HANDLE image_key, UINTN map_key) 25 | { 26 | - if (loader_is_participating || verification_method == VERIFIED_BY_HASH) { 27 | + if (loader_is_participating || verification_method != VERIFIED_BY_NOTHING) { 28 | unhook_system_services(); 29 | EFI_STATUS status; 30 | status = systab->BootServices->ExitBootServices(image_key, map_key); 31 | diff --git a/shim.c b/shim.c 32 | index 364784b..ef62145 100644 33 | --- a/shim.c 34 | +++ b/shim.c 35 | @@ -1029,6 +1029,7 @@ static EFI_STATUS verify_buffer (char *data, int datasize, 36 | cert->Hdr.dwLength - sizeof(cert->Hdr), 37 | shim_cert, sizeof(shim_cert), sha256hash, 38 | SHA256_DIGEST_SIZE)) { 39 | + update_verification_method(VERIFIED_BY_CERT); 40 | status = EFI_SUCCESS; 41 | return status; 42 | } 43 | @@ -1037,6 +1038,7 @@ static EFI_STATUS verify_buffer (char *data, int datasize, 44 | cert->Hdr.dwLength - sizeof(cert->Hdr), 45 | shim_cert, sizeof(shim_cert), sha1hash, 46 | SHA1_DIGEST_SIZE)) { 47 | + update_verification_method(VERIFIED_BY_CERT); 48 | status = EFI_SUCCESS; 49 | return status; 50 | } 51 | @@ -1050,6 +1052,7 @@ static EFI_STATUS verify_buffer (char *data, int datasize, 52 | cert->Hdr.dwLength - sizeof(cert->Hdr), 53 | vendor_cert, vendor_cert_size, 54 | sha256hash, SHA256_DIGEST_SIZE)) { 55 | + update_verification_method(VERIFIED_BY_CERT); 56 | status = EFI_SUCCESS; 57 | return status; 58 | } 59 | @@ -1058,6 +1061,7 @@ static EFI_STATUS verify_buffer (char *data, int datasize, 60 | cert->Hdr.dwLength - sizeof(cert->Hdr), 61 | vendor_cert, vendor_cert_size, 62 | sha1hash, SHA1_DIGEST_SIZE)) { 63 | + update_verification_method(VERIFIED_BY_CERT); 64 | status = EFI_SUCCESS; 65 | return status; 66 | } 67 | -- 68 | 2.11.0 69 | 70 | -------------------------------------------------------------------------------- /recipes-bsp/shim/shim/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright 2012 Red Hat, Inc 2 | 3 | Redistribution and use in source and binary forms, with or without 4 | modification, are permitted provided that the following conditions 5 | are met: 6 | 7 | Redistributions of source code must retain the above copyright 8 | notice, this list of conditions and the following disclaimer. 9 | 10 | Redistributions in binary form must reproduce the above copyright 11 | notice, this list of conditions and the following disclaimer in the 12 | documentation and/or other materials provided with the 13 | distribution. 14 | 15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 16 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 17 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 18 | FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 19 | COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 20 | INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 21 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 22 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23 | HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 24 | STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 25 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 26 | OF THE POSSIBILITY OF SUCH DAMAGE. 27 | 28 | Significant portions of this code are derived from Tianocore 29 | (http://tianocore.sf.net) and are Copyright 2009-2012 Intel 30 | Corporation. 31 | -------------------------------------------------------------------------------- /recipes-bsp/shim/shim/shimx64.efi.signed: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jiazhang0/meta-efi-secure-boot/5829d248a03c5f205a62383f3125515e885f5bb7/recipes-bsp/shim/shim/shimx64.efi.signed -------------------------------------------------------------------------------- /recipes-bsp/shim/shim_git.bb: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2015-2017 Wind River Systems, Inc. 3 | # 4 | 5 | SUMMARY = "shim is a trivial EFI application." 6 | DESCRIPTION = "shim is a trivial EFI application that, when run, attempts to open and \ 7 | execute another application. It will initially attempt to do this via the \ 8 | standard EFI LoadImage() and StartImage() calls. If these fail (because secure \ 9 | boot is enabled and the binary is not signed with an appropriate key, for \ 10 | instance) it will then validate the binary against a built-in certificate. If \ 11 | this succeeds and if the binary or signing key are not blacklisted then shim \ 12 | will relocate and execute the binary." 13 | HOMEPAGE = "https://github.com/rhinstaller/shim.git" 14 | SECTION = "bootloaders" 15 | 16 | LICENSE = "BSD-2-Clause" 17 | LIC_FILES_CHKSUM = "file://COPYRIGHT;md5=b92e63892681ee4e8d27e7a7e87ef2bc" 18 | PR = "r0" 19 | 20 | COMPATIBLE_HOST = '(i.86|x86_64).*-linux' 21 | 22 | inherit deploy user-key-store 23 | 24 | SRC_URI = " \ 25 | git://github.com/rhinstaller/shim.git \ 26 | file://0001-shim-allow-to-verify-sha1-digest-for-Authenticode.patch \ 27 | file://0005-Fix-signing-failure-due-to-not-finding-certificate.patch;apply=0 \ 28 | file://0006-Prevent-from-removing-intermediate-.efi.patch \ 29 | file://0007-Use-sbsign-to-sign-MokManager-and-fallback.patch \ 30 | file://0008-Fix-the-world-build-failure-due-to-the-missing-rule-.patch \ 31 | file://0010-Makefile-do-not-sign-the-efi-file.patch \ 32 | file://0011-Update-verification_method-if-the-loaded-image-is-si.patch;apply=0 \ 33 | " 34 | SRC_URI_append_x86-64 = " \ 35 | ${@bb.utils.contains('DISTRO_FEATURES', 'msft', 'file://shim${EFI_ARCH}.efi.signed file://LICENSE' if uks_signing_model(d) == 'sample' else '', '', d)} \ 36 | " 37 | 38 | SRCREV = "55c65546e46a78edbe41e88cb4ccbd2522e09625" 39 | PV = "12+git${SRCPV}" 40 | 41 | S = "${WORKDIR}/git" 42 | DEPENDS += "\ 43 | gnu-efi nss openssl util-linux-native openssl-native nss-native \ 44 | " 45 | 46 | EFI_ARCH_x86 = "ia32" 47 | EFI_ARCH_x86-64 = "x64" 48 | 49 | EXTRA_OEMAKE = " \ 50 | CROSS_COMPILE="${TARGET_PREFIX}" \ 51 | LIB_GCC="`${CC} -print-libgcc-file-name`" \ 52 | LIB_PATH="${STAGING_LIBDIR}" \ 53 | EFI_PATH="${STAGING_LIBDIR}" \ 54 | EFI_INCLUDE="${STAGING_INCDIR}/efi" \ 55 | RELEASE="_${DISTRO}_${DISTRO_VERSION}" \ 56 | DEFAULT_LOADER=\\\\\\SELoader${EFI_ARCH}.efi \ 57 | OPENSSL=${STAGING_BINDIR_NATIVE}/openssl \ 58 | HEXDUMP=${STAGING_BINDIR_NATIVE}/hexdump \ 59 | PK12UTIL=${STAGING_BINDIR_NATIVE}/pk12util \ 60 | CERTUTIL=${STAGING_BINDIR_NATIVE}/certutil \ 61 | SBSIGN=${STAGING_BINDIR_NATIVE}/sbsign \ 62 | AR=${AR} \ 63 | ${@'VENDOR_CERT_FILE=${WORKDIR}/vendor_cert.cer' if d.getVar('MOK_SB', True) == '1' else ''} \ 64 | ${@'VENDOR_DBX_FILE=${WORKDIR}/vendor_dbx.esl' if uks_signing_model(d) == 'user' else ''} \ 65 | ENABLE_HTTPBOOT=1 \ 66 | " 67 | 68 | PARALLEL_MAKE = "" 69 | 70 | EFI_TARGET = "/boot/efi/EFI/BOOT" 71 | FILES_${PN} += "${EFI_TARGET}" 72 | 73 | MSFT = "${@bb.utils.contains('DISTRO_FEATURES', 'msft', '1', '0', d)}" 74 | 75 | # Prepare the signing certificate and keys 76 | python do_prepare_signing_keys() { 77 | # For UEFI_SB, shim is not built 78 | if d.getVar('MOK_SB', True) != '1': 79 | return 80 | 81 | path = create_mok_vendor_dbx(d) 82 | 83 | # Prepare shim_cert and vendor_cert. 84 | dir = mok_sb_keys_dir(d) 85 | 86 | import shutil 87 | 88 | shutil.copyfile(dir + 'shim_cert.pem', d.getVar('S', True) + '/shim.crt') 89 | pem2der(dir + 'vendor_cert.pem', d.getVar('WORKDIR', True) + '/vendor_cert.cer', d) 90 | 91 | # Replace the shim certificate with EV certificate for speeding up 92 | # the progress of MSFT signing. 93 | if d.expand('${MSFT}') == "1" and uks_signing_model(d) == "sample": 94 | shutil.copyfile(d.expand('${EV_CERT}'), d.expand('${S}/shim.crt')) 95 | } 96 | addtask prepare_signing_keys after do_configure before do_compile 97 | 98 | python do_sign() { 99 | # The pre-signed shim binary will override the one built from the 100 | # scratch. 101 | pre_signed = d.expand('${WORKDIR}/shim${EFI_ARCH}.efi.signed') 102 | dst = d.expand('${B}/shim${EFI_ARCH}.efi.signed') 103 | if d.expand('${MSFT}') == "1" and os.path.exists(pre_signed): 104 | import shutil 105 | shutil.copyfile(pre_signed, dst) 106 | else: 107 | if uks_signing_model(d) in ('sample', 'user'): 108 | uefi_sb_sign(d.expand('${S}/shim${EFI_ARCH}.efi'), dst, d) 109 | elif uks_signing_model(d) == 'edss': 110 | edss_sign_efi_image(d.expand('${S}/shim${EFI_ARCH}.efi'), dst, d) 111 | 112 | sb_sign(d.expand('${S}/mm${EFI_ARCH}.efi'), d.expand('${B}/mm${EFI_ARCH}.efi.signed'), d) 113 | sb_sign(d.expand('${S}/fb${EFI_ARCH}.efi'), d.expand('${B}/fb${EFI_ARCH}.efi.signed'), d) 114 | } 115 | addtask sign after do_compile before do_install 116 | 117 | do_install() { 118 | install -d ${D}${EFI_TARGET} 119 | 120 | local shim_dst="${D}${EFI_TARGET}/boot${EFI_ARCH}.efi" 121 | local mm_dst="${D}${EFI_TARGET}/mm${EFI_ARCH}.efi" 122 | if [ x"${UEFI_SB}" = x"1" ]; then 123 | install -m 0600 ${B}/shim${EFI_ARCH}.efi.signed $shim_dst 124 | install -m 0600 ${B}/mm${EFI_ARCH}.efi.signed $mm_dst 125 | else 126 | install -m 0600 ${B}/shim${EFI_ARCH}.efi $shim_dst 127 | install -m 0600 ${B}/mm${EFI_ARCH}.efi $mm_dst 128 | fi 129 | } 130 | 131 | # Install the unsigned images for manual signing 132 | do_deploy() { 133 | install -d ${DEPLOYDIR}/efi-unsigned 134 | 135 | install -m 0600 ${B}/shim${EFI_ARCH}.efi ${DEPLOYDIR}/efi-unsigned/boot${EFI_ARCH}.efi 136 | install -m 0600 ${B}/mm${EFI_ARCH}.efi ${DEPLOYDIR}/efi-unsigned/mm${EFI_ARCH}.efi 137 | 138 | install -m 0600 "${D}${EFI_TARGET}/boot${EFI_ARCH}.efi" "${DEPLOYDIR}" 139 | install -m 0600 "${D}${EFI_TARGET}/mm${EFI_ARCH}.efi" "${DEPLOYDIR}" 140 | } 141 | addtask deploy after do_install before do_build 142 | -------------------------------------------------------------------------------- /recipes-core/systemd/systemd_%.bbappend: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2017 Wind River Systems, Inc. 3 | # 4 | 5 | DEPENDS += " \ 6 | ${@bb.utils.contains('MACHINE_FEATURES', 'efi', 'gnu-efi', '', d)} \ 7 | " 8 | 9 | EXTRA_OECONF += " \ 10 | ${@bb.utils.contains('MACHINE_FEATURES', 'efi', '--enable-efi --enable-gnuefi --with-efi-libdir=${STAGING_LIBDIR} --with-efi-ldsdir=${STAGING_LIBDIR} --with-efi-includedir=${STAGING_INCDIR}', '', d)} \ 11 | " 12 | -------------------------------------------------------------------------------- /recipes-devtools/libsign/libsign_git.bb: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2017 Wind River Systems, Inc. 3 | # 4 | 5 | SUMMARY = "A generic signing tool framework" 6 | DESCRIPTION = " \ 7 | This project targets to provide a generic signing framework. This framework \ 8 | separates the signing request and signing process and correspondingly forms \ 9 | the so-called signlet and signaturelet. \ 10 | Each signaturelet only concerns about the details about how to construct the \ 11 | layout of a signature format, and signlet only cares how to construct the \ 12 | signing request. \ 13 | " 14 | SECTION = "devel" 15 | LICENSE = "BSD-3-Clause" 16 | LIC_FILES_CHKSUM = "file://${S}/LICENSE;md5=d9bf404642f21afb4ad89f95d7bc91ee" 17 | 18 | SRC_URI = " \ 19 | git://github.com/jiazhang0/libsign.git \ 20 | " 21 | SRCREV = "dfab84b4235a36bb395bc6663e50578bb2f9edca" 22 | PV = "0.3.2+git${SRCPV}" 23 | 24 | DEPENDS += "openssl" 25 | RDEPENDS_${PN}_class-target += "libcrypto" 26 | RDEPENDS_${PN}_class-native += "openssl" 27 | 28 | PARALLEL_MAKE = "" 29 | 30 | S = "${WORKDIR}/git" 31 | 32 | EXTRA_OEMAKE = " \ 33 | CC="${CC}" \ 34 | bindir="${STAGING_BINDIR}" \ 35 | libdir="${STAGING_LIBDIR}" \ 36 | includedir="${STAGING_INCDIR}" \ 37 | EXTRA_CFLAGS="${CFLAGS}" \ 38 | EXTRA_LDFLAGS="${LDFLAGS}" \ 39 | SIGNATURELET_DIR="${libdir}/signaturelet" \ 40 | BINDIR="${bindir}" \ 41 | LIBDIR="${libdir}" \ 42 | " 43 | 44 | do_install() { 45 | oe_runmake install DESTDIR="${D}" 46 | } 47 | 48 | FILES_${PN} += " \ 49 | ${libdir}/signaturelet \ 50 | " 51 | 52 | BBCLASSEXTEND = "native" 53 | -------------------------------------------------------------------------------- /recipes-devtools/sbsigntool/sbsigntool-native_git.bb: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2012-2016 Wind River Systems, Inc. 3 | # 4 | 5 | SUMMARY = "Signing utility for UEFI secure boot" 6 | 7 | LICENSE = "GPLv3" 8 | LIC_FILES_CHKSUM = "file://LICENSE.GPLv3;md5=9eef91148a9b14ec7f9df333daebc746" 9 | 10 | SRC_URI = "git://kernel.ubuntu.com/jk/sbsigntool \ 11 | file://ccan.git.tar.bz2 \ 12 | file://disable-man-page-creation.patch \ 13 | file://Fix-for-multi-sign.patch \ 14 | file://sbsign-add-x-option-to-avoid-overwrite-existing-sign.patch \ 15 | file://fix-mixed-implicit-and-normal-rules.patch;apply=0 \ 16 | file://image-fix-the-segment-fault-caused-by-the-uninitiali.patch \ 17 | " 18 | 19 | SRCREV="951ee95a301674c046f55330cd7460e1314deff2" 20 | PV = "0.6+git${SRCPV}" 21 | 22 | inherit autotools-brokensep pkgconfig native 23 | 24 | DEPENDS_append = " binutils-native openssl-native gnu-efi-native util-linux-native" 25 | 26 | S = "${WORKDIR}/git" 27 | 28 | do_configure() { 29 | cd ${S} 30 | rm -rf lib/ccan.git 31 | git clone ${WORKDIR}/ccan.git lib/ccan.git 32 | cd lib/ccan.git && git apply ${WORKDIR}/fix-mixed-implicit-and-normal-rules.patch && cd - 33 | 34 | OLD_CC="${CC}" 35 | 36 | if [ ! -e lib/ccan ]; then 37 | export CC="${BUILD_CC}" 38 | export TMPDIR=${B} 39 | lib/ccan.git/tools/create-ccan-tree \ 40 | --build-type=automake lib/ccan \ 41 | talloc read_write_all build_assert array_size || exit 2 42 | fi 43 | 44 | export CC="${OLD_CC}" 45 | ./autogen.sh --noconfigure 46 | oe_runconf 47 | } 48 | 49 | EXTRA_OEMAKE += " \ 50 | INCLUDES='-I../lib/ccan.git/' \ 51 | EFI_CPPFLAGS='-DEFI_FUNCTION_WRAPPER \ 52 | -I${STAGING_INCDIR}/efi \ 53 | -I${STAGING_INCDIR}/efi/${BUILD_ARCH}' \ 54 | " 55 | -------------------------------------------------------------------------------- /recipes-devtools/sbsigntool/sbsigntool/Fix-for-multi-sign.patch: -------------------------------------------------------------------------------- 1 | From e58a528ef57e53008222f238cce7c326a14572e2 Mon Sep 17 00:00:00 2001 2 | From: James Bottomley 3 | Date: Mon, 30 Sep 2013 19:25:37 -0700 4 | Subject: [PATCH] Fix for multi-sign 5 | 6 | Upstream-Status: Inappropriate [embedded specific] 7 | 8 | The new Tianocore multi-sign code fails now for images signed with 9 | sbsigntools. The reason is that we don't actually align the signature table, 10 | we just slap it straight after the binary data. Unfortunately, the new 11 | multi-signature code checks that our alignment offsets are correct and fails 12 | the signature for this reason. Fix by adding junk to the end of the image to 13 | align the signature section. 14 | 15 | Signed-off-by: James Bottomley 16 | --- 17 | src/image.c | 8 +++++++- 18 | 1 file changed, 7 insertions(+), 1 deletion(-) 19 | 20 | diff --git a/src/image.c b/src/image.c 21 | index 10eba0e..519e288 100644 22 | --- a/src/image.c 23 | +++ b/src/image.c 24 | @@ -385,7 +385,13 @@ static int image_find_regions(struct image *image) 25 | 26 | /* record the size of non-signature data */ 27 | r = &image->checksum_regions[image->n_checksum_regions - 1]; 28 | - image->data_size = (r->data - (void *)image->buf) + r->size; 29 | + /* 30 | + * The new Tianocore multisign does a stricter check of the signatures 31 | + * in particular, the signature table must start at an aligned offset 32 | + * fix this by adding bytes to the end of the text section (which must 33 | + * be included in the hash) 34 | + */ 35 | + image->data_size = align_up((r->data - (void *)image->buf) + r->size, 8); 36 | 37 | return 0; 38 | } 39 | -- 40 | 1.8.4 41 | 42 | -------------------------------------------------------------------------------- /recipes-devtools/sbsigntool/sbsigntool/ccan.git.tar.bz2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jiazhang0/meta-efi-secure-boot/5829d248a03c5f205a62383f3125515e885f5bb7/recipes-devtools/sbsigntool/sbsigntool/ccan.git.tar.bz2 -------------------------------------------------------------------------------- /recipes-devtools/sbsigntool/sbsigntool/disable-man-page-creation.patch: -------------------------------------------------------------------------------- 1 | Upstream-Status: Inappropriate [embedded specific] 2 | 3 | diff --git a/docs/Makefile.am b/docs/Makefile.am 4 | index 1b5a588..6918dd8 100644 5 | --- a/docs/Makefile.am 6 | +++ b/docs/Makefile.am 7 | @@ -1,8 +1,4 @@ 8 | 9 | -man1_MANS = sbsign.1 sbverify.1 sbattach.1 sbvarsign.1 sbsiglist.1 10 | - 11 | -EXTRA_DIST = sbsign.1.in sbverify.1.in sbattach.1.in \ 12 | - sbvarsign.1.in sbsiglist.1.in 13 | CLEANFILES = $(man1_MANS) 14 | 15 | $(builddir)/%.1: $(srcdir)/%.1.in $(top_builddir)/src/% 16 | -------------------------------------------------------------------------------- /recipes-devtools/sbsigntool/sbsigntool/fix-mixed-implicit-and-normal-rules.patch: -------------------------------------------------------------------------------- 1 | From 05e73dbe1f25600ad0dbb36b2d690560c5a36281 Mon Sep 17 00:00:00 2001 2 | From: Lans Zhang 3 | Date: Tue, 31 Mar 2015 15:34:38 +0800 4 | Subject: [PATCH] Fix mixed implicit and normal rules 5 | 6 | Upstream-Status: Inappropriate [embedded specific] 7 | 8 | This patch comes from upstream: 9 | http://git.yoctoproject.org/cgit/cgit.cgi/meta-luv/plain/recipes-devtools/sbsigntool/sbsigntool/fix-mixed-implicit-and-normal-rules.patch 10 | 11 | Signed-off-by: Lans Zhang 12 | --- 13 | Makefile | 4 ---- 14 | 1 file changed, 4 deletions(-) 15 | 16 | diff --git a/Makefile b/Makefile 17 | index 65d0d8f..a83185d 100644 18 | --- a/Makefile 19 | +++ b/Makefile 20 | @@ -39,10 +39,6 @@ $(SCOREDIR)/SUMMARY: $(MODS:%=$(SCOREDIR)/%.score) 21 | $(CC) -v >> $@ 22 | cat $^ | grep 'Total score:' >> $@ 23 | 24 | -$(SCOREDIR)/%.score: ccan/%/_info tools/ccanlint/ccanlint $(OBJFILES) 25 | - mkdir -p `dirname $@` 26 | - $(CCANLINT) -v -s ccan/$* > $@ || true 27 | - 28 | $(ALL_DEPENDS): %/.depends: %/_info tools/ccan_depends 29 | tools/ccan_depends $* > $@ || ( rm -f $@; exit 1 ) 30 | 31 | -- 32 | 1.8.3.1 33 | 34 | -------------------------------------------------------------------------------- /recipes-devtools/sbsigntool/sbsigntool/image-fix-the-segment-fault-caused-by-the-uninitiali.patch: -------------------------------------------------------------------------------- 1 | From a6862cb3bb3b00a1d6704b2bd1fedbd1374be861 Mon Sep 17 00:00:00 2001 2 | From: Lans Zhang 3 | Date: Thu, 6 Apr 2017 11:11:14 +0800 4 | Subject: [PATCH] image: fix the segment fault caused by the uninitialized 5 | sigbuf 6 | 7 | The uninitialized struct image might contain a non-zeroed sigbuf and then 8 | it is wrongly freed by image_add_signature(). 9 | 10 | Signed-off-by: Lans Zhang 11 | --- 12 | src/image.c | 2 +- 13 | 1 file changed, 1 insertion(+), 1 deletion(-) 14 | 15 | diff --git a/src/image.c b/src/image.c 16 | index cc55791..644e8f1 100644 17 | --- a/src/image.c 18 | +++ b/src/image.c 19 | @@ -395,7 +395,7 @@ struct image *image_load(const char *filename) 20 | struct image *image; 21 | int rc; 22 | 23 | - image = talloc(NULL, struct image); 24 | + image = talloc_zero(NULL, struct image); 25 | if (!image) { 26 | perror("talloc(image)"); 27 | return NULL; 28 | -- 29 | 2.11.0 30 | 31 | -------------------------------------------------------------------------------- /recipes-devtools/sbsigntool/sbsigntool/sbsign-add-x-option-to-avoid-overwrite-existing-sign.patch: -------------------------------------------------------------------------------- 1 | From 0016a571a5ea1ab65817973f179800947e1aa8de Mon Sep 17 00:00:00 2001 2 | From: Lans Zhang 3 | Date: Fri, 15 Jan 2016 09:40:56 +0800 4 | Subject: [PATCH] sbsign: add -x option to avoid overwrite existing signature 5 | 6 | Upstream-Status: Pending 7 | 8 | Signed-off-by: Lans Zhang 9 | --- 10 | src/sbsign.c | 17 +++++++++++++++-- 11 | 1 file changed, 15 insertions(+), 2 deletions(-) 12 | 13 | diff --git a/src/sbsign.c b/src/sbsign.c 14 | index dcf6eed..7dc101f 100644 15 | --- a/src/sbsign.c 16 | +++ b/src/sbsign.c 17 | @@ -66,6 +66,7 @@ struct sign_context { 18 | }; 19 | 20 | static struct option options[] = { 21 | + { "noresign", no_argument, NULL, 'x' }, 22 | { "output", required_argument, NULL, 'o' }, 23 | { "cert", required_argument, NULL, 'c' }, 24 | { "key", required_argument, NULL, 'k' }, 25 | @@ -87,6 +88,7 @@ static void usage(void) 26 | "\t--cert certificate (x509 certificate)\n" 27 | "\t--detached write a detached signature, instead of\n" 28 | "\t a signed binary\n" 29 | + "\t--noresign don't re-sign the binary if signed\n" 30 | "\t--output write signed data to \n" 31 | "\t (default .signed,\n" 32 | "\t or .pk7 for detached\n" 33 | @@ -114,7 +116,7 @@ int main(int argc, char **argv) 34 | const char *keyfilename, *certfilename; 35 | struct sign_context *ctx; 36 | uint8_t *buf, *tmp; 37 | - int rc, c, sigsize; 38 | + int rc, c, sigsize, no_resign = 0; 39 | 40 | ctx = talloc_zero(NULL, struct sign_context); 41 | 42 | @@ -123,11 +125,14 @@ int main(int argc, char **argv) 43 | 44 | for (;;) { 45 | int idx; 46 | - c = getopt_long(argc, argv, "o:c:k:dvVh", options, &idx); 47 | + c = getopt_long(argc, argv, "xo:c:k:dvVh", options, &idx); 48 | if (c == -1) 49 | break; 50 | 51 | switch (c) { 52 | + case 'x': 53 | + no_resign = 1; 54 | + break; 55 | case 'o': 56 | ctx->outfilename = talloc_strdup(ctx, optarg); 57 | break; 58 | @@ -178,6 +183,14 @@ int main(int argc, char **argv) 59 | if (!ctx->image) 60 | return EXIT_FAILURE; 61 | 62 | + if (ctx->image->cert_table) { 63 | + if (no_resign) { 64 | + fprintf(stderr, 65 | + "Don't overwrite existing signature\n"); 66 | + return EXIT_SUCCESS; 67 | + } 68 | + } 69 | + 70 | talloc_steal(ctx, ctx->image); 71 | 72 | ERR_load_crypto_strings(); 73 | -- 74 | 1.9.1 75 | 76 | -------------------------------------------------------------------------------- /recipes-extended/mokutil/mokutil_git.bb: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2016 Wind River Systems, Inc. 3 | # 4 | 5 | SUMMARY = "The utility to manipulate machines owner keys which managed in shim" 6 | 7 | LICENSE = "GPLv3" 8 | LIC_FILES_CHKSUM = "file://COPYING;md5=d32239bcb673463ab874e80d47fae504" 9 | 10 | COMPATIBLE_HOST = '(i.86|x86_64|arm|aarch64).*-linux' 11 | 12 | SRC_URI = "\ 13 | git://github.com/lcp/mokutil.git \ 14 | " 15 | 16 | S = "${WORKDIR}/git" 17 | SRCREV = "e19adc575c1f9d8f08b7fbc594a0887ace63f83f" 18 | PV = "0.3.0+git${SRCPV}" 19 | 20 | inherit autotools pkgconfig 21 | 22 | DEPENDS += "openssl efivar" 23 | RDEPENDS_${PN} += "openssl efivar" 24 | 25 | EXTRA_OEMAKE += "\ 26 | EFIVAR_LIBS='-L${STAGING_LIBDIR} -lefivar' \ 27 | OPENSSL_LIBS='-L${STAGING_LIBDIR} -lssl -lcrypto' \ 28 | " 29 | 30 | FILES_${PN} += "${datadir}/bash-completion/*" 31 | -------------------------------------------------------------------------------- /recipes-kernel/linux/kernel-initramfs-image.bbappend: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2017 Wind River Systems, Inc. 3 | # 4 | 5 | inherit user-key-store deploy 6 | 7 | # Always fetch the latest initramfs image 8 | do_install[nostamp] = "1" 9 | 10 | fakeroot python do_sign() { 11 | initramfs = None 12 | 13 | if d.expand('${INSTALL_INITRAMFS}') == '1': 14 | initramfs = d.expand('${D}/boot/${INITRAMFS_IMAGE}${INITRAMFS_EXT_NAME}.cpio.gz') 15 | elif d.expand('${INSTALL_BUNDLE}') == '1': 16 | initramfs = d.expand('${D}/boot/${KERNEL_IMAGETYPE}-initramfs${INITRAMFS_EXT_NAME}') 17 | 18 | if initramfs == None or not os.path.exists(initramfs): 19 | return 20 | 21 | uks_sel_sign(initramfs, d) 22 | } 23 | addtask sign after do_install before do_deploy do_package 24 | 25 | do_deploy() { 26 | initramfs="" 27 | initramfs_dest="" 28 | 29 | if [ x"${INSTALL_INITRAMFS}" = x"1" ]; then 30 | initramfs="${D}/boot/${INITRAMFS_IMAGE}${INITRAMFS_EXT_NAME}.cpio.gz" 31 | initramfs_dest="${DEPLOYDIR}/${INITRAMFS_IMAGE}-${MACHINE}.cpio.gz" 32 | elif [ x"${INSTALL_BUNDLE}" = x"1" ]; then 33 | initramfs="${D}/boot/${KERNEL_IMAGETYPE}-initramfs${INITRAMFS_EXT_NAME}" 34 | initramfs_dest="${DEPLOYDIR}/${KERNEL_IMAGETYPE}-initramfs-${MACHINE}.bin" 35 | fi 36 | 37 | if [ -n "$initramfs" -a -f "$initramfs.p7b" ]; then 38 | install -d "${DEPLOYDIR}" 39 | 40 | install -m 0644 "$initramfs.p7b" "$initramfs_dest.p7b" 41 | fi 42 | } 43 | addtask deploy after do_install before do_build 44 | 45 | pkg_postinst_${PN}_append () { 46 | if [ x"${INSTALL_BUNDLE}" = x"1" ] ; then 47 | update-alternatives --install /boot/${KERNEL_IMAGETYPE}.p7b ${KERNEL_IMAGETYPE}.p7b /boot/${KERNEL_IMAGETYPE}-initramfs${INITRAMFS_EXT_NAME}.p7b 50101 || true 48 | fi 49 | } 50 | 51 | pkg_prerm_${PN}_append () { 52 | if [ x"${INSTALL_BUNDLE}" = x"1" ] ; then 53 | update-alternatives --remove ${KERNEL_IMAGETYPE}.p7b ${KERNEL_IMAGETYPE}-initramfs${INITRAMFS_EXT_NAME}.p7b || true 54 | fi 55 | } 56 | -------------------------------------------------------------------------------- /recipes-kernel/linux/linux-windriver_%.bbappend: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2017 Wind River Systems, Inc. 3 | # 4 | 5 | require linux-yocto-efi-secure-boot.inc 6 | -------------------------------------------------------------------------------- /recipes-kernel/linux/linux-yocto-efi-secure-boot.inc: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2015-2017 Wind River Systems, Inc. 3 | # 4 | 5 | FILESEXTRAPATHS_prepend := "${THISDIR}/linux-yocto:" 6 | 7 | sccs = " \ 8 | ${@bb.utils.contains('DISTRO_FEATURES', 'efi-secure-boot', \ 9 | 'cfg/efi-ext.scc', '', d)} \ 10 | " 11 | KERNEL_FEATURES_append_x86 += "${sccs}" 12 | KERNEL_FEATURES_append_x86-64 += "${sccs}" 13 | 14 | inherit user-key-store 15 | 16 | fakeroot python do_sign() { 17 | import re 18 | 19 | if (d.expand('${TARGET_ARCH}') != 'x86_64') and (not re.match('i.86', d.expand('${TARGET_ARCH}'))): 20 | return 21 | 22 | if d.expand('${UEFI_SB}') != '1': 23 | return 24 | 25 | import shutil 26 | 27 | for type in d.expand('${KERNEL_IMAGETYPES}').split(): 28 | kernel = d.expand('${B}/${KERNEL_OUTPUT_DIR}/') + type 29 | 30 | # Prepare the unsigned kernel image for manual signing. 31 | shutil.copy(kernel, d.expand('${B}/') + type + '.unsigned') 32 | 33 | # SELoader signature is always based on the unsigned kernel image, 34 | # disallowing chainloader to kernel efi-stub. 35 | uks_sel_sign(kernel, d) 36 | 37 | shutil.copyfile(kernel, d.expand('${D}/boot/') + type + d.expand('-${KERNEL_RELEASE}')) 38 | shutil.copyfile(kernel + '.p7b', d.expand('${D}/boot/') + type + d.expand('-${KERNEL_RELEASE}.p7b')) 39 | } 40 | 41 | # Make sure the kernel image has been signed before kernel_do_deploy() 42 | # which prepares the kernel image for creating usb/iso. 43 | addtask sign after do_install before do_package do_populate_sysroot do_deploy 44 | 45 | fakeroot python do_sign_bundled_kernel() { 46 | import re 47 | 48 | if (d.expand('${TARGET_ARCH}') != 'x86_64') and (not re.match('i.86', d.expand('${TARGET_ARCH}'))): 49 | return 50 | 51 | if d.expand('${UEFI_SB}') != '1': 52 | return 53 | 54 | if (d.expand('${INITRAMFS_IMAGE}') == '') or (d.expand('${INITRAMFS_IMAGE_BUNDLE}') != '1'): 55 | return 56 | 57 | import shutil 58 | 59 | for type in d.expand('${KERNEL_IMAGETYPES}').split(): 60 | kernel = d.expand('${B}/${KERNEL_OUTPUT_DIR}/') + type + '.initramfs' 61 | 62 | # Prepare the unsigned kernel image for manual signing. 63 | shutil.copy(kernel, d.expand('${B}/') + type + '.initramfs.unsigned') 64 | 65 | # SELoader signature is always based on the unsigned kernel image, 66 | # disallowing chainloader to kernel efi-stub. 67 | uks_sel_sign(kernel, d) 68 | 69 | shutil.copyfile(kernel, d.expand('${D}/boot/') + type + d.expand('-initramfs-${MACHINE}.bin')) 70 | shutil.copyfile(kernel + '.p7b', d.expand('${D}/boot/') + type + d.expand('-initramfs-${MACHINE}.bin.p7b')) 71 | } 72 | addtask sign_bundled_kernel after do_bundle_initramfs before do_deploy 73 | 74 | do_deploy_append() { 75 | install -d "${DEPLOYDIR}/efi-unsigned" 76 | 77 | for type in ${KERNEL_IMAGETYPES}; do 78 | if [ -f "${B}/$type.unsigned" ]; then 79 | install -m 0644 "${B}/$type.unsigned" "${DEPLOYDIR}/efi-unsigned/$type" 80 | fi 81 | 82 | if [ -f "${B}/$type.initramfs.unsigned" ]; then 83 | install -m 0644 "${B}/$type.initramfs.unsigned" "${DEPLOYDIR}/efi-unsigned/type.initramfs" 84 | fi 85 | 86 | if [ -f "${D}/boot/$type-initramfs-${MACHINE}.bin.p7b" ]; then 87 | install -m 0644 "${D}/boot/$type-initramfs-${MACHINE}.bin.p7b" "${DEPLOYDIR}" 88 | fi 89 | 90 | if [ -f "${B}/${KERNEL_OUTPUT_DIR}/$type.p7b" ]; then 91 | base_name="${type}-${KERNEL_IMAGE_BASE_NAME}.bin.p7b" 92 | 93 | install -m 0644 "${B}/${KERNEL_OUTPUT_DIR}/$type.p7b" "${DEPLOYDIR}/$base_name" 94 | ln -sf "$base_name" "${DEPLOYDIR}/$type-${KERNEL_IMAGE_SYMLINK_NAME}.bin.p7b" 95 | ln -sf "$base_name" "${DEPLOYDIR}/$type.p7b" 96 | fi 97 | done 98 | } 99 | 100 | # Ship *.p7b files to related packages 101 | python do_package_prepend() { 102 | for type in d.expand('${KERNEL_IMAGETYPES}').split(): 103 | typelower = type.lower() 104 | d.appendVar('FILES_kernel-image-' + typelower, ' /boot/' + type + d.expand('-${KERNEL_VERSION_NAME}.p7b')) 105 | } 106 | -------------------------------------------------------------------------------- /recipes-kernel/linux/linux-yocto-rt_%.bbappend: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2015-2017 Wind River Systems, Inc. 3 | # 4 | 5 | require linux-yocto-efi-secure-boot.inc 6 | -------------------------------------------------------------------------------- /recipes-kernel/linux/linux-yocto_%.bbappend: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2015-2017 Wind River Systems, Inc. 3 | # 4 | 5 | require linux-yocto-efi-secure-boot.inc 6 | -------------------------------------------------------------------------------- /recipes-perl/libfile-slurp/libfile-slurp-perl_9999.19.bb: -------------------------------------------------------------------------------- 1 | DESCRIPTION = "Slurp entire files into variables." 2 | SECTION = "libs" 3 | LICENSE = "Artistic-1.0 | GPL-1.0+" 4 | 5 | LIC_FILES_CHKSUM = "file://README;beginline=37;endline=41;md5=255fbd5f98a90d51d9908d31271ae4d4" 6 | SRC_URI = "http://search.cpan.org/CPAN/authors/id/U/UR/URI/File-Slurp-9999.19.tar.gz" 7 | 8 | S = "${WORKDIR}/File-Slurp-${PV}" 9 | 10 | inherit cpan 11 | BBCLASSEXTEND="native" 12 | PACKAGE_ARCH = "all" 13 | 14 | SRC_URI[md5sum] = "7d584cd15c4f8b9547765eff8c4ef078" 15 | SRC_URI[sha256sum] = "ce29ebe995097ebd6e9bc03284714cdfa0c46dc94f6b14a56980747ea3253643" 16 | -------------------------------------------------------------------------------- /recipes-support/efivar/efivar/Remove-use-of-deprecated-readdir_r.patch: -------------------------------------------------------------------------------- 1 | From 7078852e4a89f5ba27e7a70bc69641e01a6bff7a Mon Sep 17 00:00:00 2001 2 | From: Yunguo Wei 3 | Date: Thu, 19 Jan 2017 15:11:25 +0800 4 | Subject: [PATCH] Remove use of deprecated readdir_r 5 | 6 | Backport 1dc6d576fa4(Remove use of deprecated readdir_r) from 7 | https://github.com/rhinstaller/efivar.git 8 | 9 | Signed-off-by: Yunguo Wei 10 | --- 11 | src/vars.c | 12 ++++-------- 12 | 1 file changed, 4 insertions(+), 8 deletions(-) 13 | 14 | diff --git a/src/vars.c b/src/vars.c 15 | index 2a276de..ec0d6bf 100644 16 | --- a/src/vars.c 17 | +++ b/src/vars.c 18 | @@ -126,19 +126,15 @@ is_64bit(void) 19 | if (dfd < 0) 20 | goto err; 21 | 22 | - struct dirent entry; 23 | - struct dirent *result = NULL; 24 | while (1) { 25 | - int rc = readdir_r(dir, &entry, &result); 26 | - if (rc != 0) 27 | - break; 28 | - if (result == NULL) 29 | + struct dirent *entry = readdir(dir); 30 | + if (entry == NULL) 31 | break; 32 | 33 | - if (!strcmp(entry.d_name, "..") || !strcmp(entry.d_name, ".")) 34 | + if (!strcmp(entry->d_name, "..") || !strcmp(entry->d_name, ".")) 35 | continue; 36 | 37 | - ssize_t size = get_file_data_size(dfd, entry.d_name); 38 | + ssize_t size = get_file_data_size(dfd, entry->d_name); 39 | if (size < 0) { 40 | continue; 41 | } else if (size == 2084) { 42 | -- 43 | 2.7.4 44 | 45 | -------------------------------------------------------------------------------- /recipes-support/efivar/efivar_0.24.bbappend: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2016 Wind River Systems, Inc. 3 | # 4 | 5 | FILESEXTRAPATHS_prepend := "${THISDIR}/efivar:" 6 | 7 | SRC_URI += "\ 8 | file://Remove-use-of-deprecated-readdir_r.patch \ 9 | " 10 | 11 | # In dp.h, 'for' loop initial declarations are used 12 | CFLAGS_append = " -std=gnu99" 13 | 14 | # In order to install headers and libraries to sysroot 15 | do_install_append() { 16 | oe_runmake DESTDIR=${D} install 17 | } 18 | --------------------------------------------------------------------------------