From 035518ff69a97fa5d3fa432e13c9593a9f459a4e Mon Sep 17 00:00:00 2001 From: Luca Boccassi Date: Tue, 27 Feb 2018 19:28:33 +0000 Subject: UEFI: add support for Secure Boot on amd64 and arm64 Support for UEFI Secure Boot is modelled after how it currently works in Ubuntu and on how it is going to work on Debian. A minimal bootloader, shim, is used as the first-stage and it then loads grub. Both have to be signed. shim-signed is already available in Debian so the filenames are already established, and the grub2 repository and packaging is common between the 2 distros so we can already be reasonably sure of what it is going to be. So if both are available, copy /usr/lib/shim/shim[x64|aa64].efi.signed as boot[x64|aa64].efi so that UEFI loads it first, and copy /usr/lib/grub/[x86_64|arm64]-efi-signed/grub[x64|aa64].efi.signed as grub[x64|aa64].efi. This grub2 EFI monolithic image is currently hard-coded in grub2's repository to look for a config file in efi/debian, so make a copy of the previously added minimal grub.cfg that loads the real one in that directory in both the fat32 and ISO 9660 partitions. The new option --uefi-secure-boot can be set to auto (default, enable or disable. In auto, the lack of the signed EFI binaries is intentionally left as a soft failure - live-build will simply fallback to using the locally generated non-signed grub2 monolithic EFI binary as the only bootloader. Given the difficulties surrounding the Secure Boot signing infrastructure this approach gives the most flexibility and makes sure things will "just work" once the packages are available, without the need to change anything in the configuration. This will also greatly help downstream distributions and users who want to do self-signing. The enable or disable options work as expected. Closes: #821084 --- scripts/build/binary_grub-efi | 90 ++++++++++++++++++++++++++++++++++++++++++- scripts/build/config | 11 ++++++ 2 files changed, 99 insertions(+), 2 deletions(-) (limited to 'scripts') diff --git a/scripts/build/binary_grub-efi b/scripts/build/binary_grub-efi index aea42a693..ab6630b3b 100755 --- a/scripts/build/binary_grub-efi +++ b/scripts/build/binary_grub-efi @@ -58,6 +58,57 @@ Check_package chroot /usr/bin/grub-mkimage grub-common Check_package chroot /usr/bin/mcopy mtools Check_package chroot /sbin/mkfs.msdos dosfstools +# Check UEFI Secure Boot setting and depends +# By default (auto) do a best-effort build: if the signed binaries are available use +# them, but don't fail if they are not, just print a warning. +case "${LB_ARCHITECTURES}" in + amd64|i386) + _SB_EFI_PLATFORM="x86_64" + _SB_EFI_NAME="x64" + _SB_EFI_DEB="amd64" + ;; + arm64) + _SB_EFI_PLATFORM="arm64" + _SB_EFI_NAME="aa64" + _SB_EFI_DEB="arm64" + ;; +esac + +_PRE_SB_PACKAGES="${_LB_PACKAGES}" +_LB_PACKAGES="shim-signed grub-efi-${_SB_EFI_DEB}-signed" +case "${LB_UEFI_SECURE_BOOT}" in + auto) + # Use Check_installed, as Check_package will error out immediately + set +e + Install_package + set -e + Check_installed chroot /usr/lib/grub/${_SB_EFI_PLATFORM}-efi-signed/grub${_SB_EFI_NAME}.efi.signed \ + grub-efi-${_SB_EFI_DEB}-signed + _GRUB_INSTALL_STATUS="${INSTALL_STATUS}" + Check_installed chroot /usr/lib/shim/shim${_SB_EFI_NAME}.efi.signed \ + shim-signed + + if [ "${INSTALL_STATUS}" -ne 0 -o "${_GRUB_INSTALL_STATUS}" -ne 0 ] + then + Echo_warning "UEFI Secure Boot disabled due to missing signed Grub/Shim." + else + Echo_message "UEFI Secure Boot support enabled." + fi + ;; + enable) + Check_package chroot /usr/lib/grub/${_SB_EFI_PLATFORM}-efi-signed/grub${_SB_EFI_NAME}.efi.signed \ + grub-efi-${_SB_EFI_DEB}-signed + Check_package chroot /usr/lib/shim/shim${_SB_EFI_NAME}.efi.signed \ + shim-signed + Install_package + Echo_message "UEFI Secure Boot support enabled." + ;; + disable) + Echo_message "UEFI Secure Boot support disabled." + ;; +esac +_LB_PACKAGES="${_PRE_SB_PACKAGES}" + # Setting destination directory case "${LIVE_IMAGE_TYPE}" in hdd*|netboot) @@ -109,6 +160,27 @@ gen_efi_boot_img(){ mkdir -p ${_CHROOT_DIR}/grub-efi-temp/efi/boot mcopy -n -i ${_CHROOT_DIR}/\$outdir/efi.img '::efi/boot/boot*.efi' ${_CHROOT_DIR}/grub-efi-temp/efi/boot cp -r "${_CHROOT_DIR}"/\$outdir/* "${_CHROOT_DIR}/grub-efi-temp/" + + # Secure Boot support: + # - use shim as the boot.efi that gets loaded first by the firmware + # - drop a grub.cfg (same reason as below) in the cfg directory as configured + # by the signed grub efi binary creation. At the moment that is efi/debian + # as set by grub2/debian/build-efi-images and cannot be changed without + # rebuilding grub2 + # - the source paths are taken from shim-signed: + # https://packages.debian.org/sid/amd64/shim-signed/filelist + # and grub-efi-amd64-signed, currently in Ubuntu: + # https://packages.ubuntu.com/xenial/amd64/grub-efi-amd64-signed/filelist + # https://packages.ubuntu.com/bionic/arm64/grub-efi-arm64-signed/filelist + if [ -r ${_CHROOT_DIR}/usr/lib/grub/\$platform-signed/grub\$efi_name.efi.signed -a \ + -r ${_CHROOT_DIR}/usr/lib/shim/shim\$efi_name.efi.signed -a \ + "${LB_UEFI_SECURE_BOOT}" != "disable" ]; then + mkdir -p ${_CHROOT_DIR}/grub-efi-temp/efi/debian + cp ${_CHROOT_DIR}/usr/lib/grub/\$platform-signed/grub\$efi_name.efi.signed \ + ${_CHROOT_DIR}/grub-efi-temp/efi/boot/grub\$efi_name.efi + cp ${_CHROOT_DIR}/usr/lib/shim/shim\$efi_name.efi.signed \ + ${_CHROOT_DIR}/grub-efi-temp/efi/boot/boot\$efi_name.efi + fi } PRE_EFI_IMAGE_PATH="${PATH}" @@ -158,7 +230,7 @@ EOF # the case of a multi-arch amd64/i386 image size=0 -for file in ${_CHROOT_DIR}/grub-efi-temp/efi/boot/boot*.efi \ +for file in ${_CHROOT_DIR}/grub-efi-temp/efi/boot/*.efi \ ${_CHROOT_DIR}/grub-efi-temp-cfg/grub.cfg; do size=\$((\$size + \$(stat -c %s "\$file"))) done @@ -166,15 +238,29 @@ done # directories: efi efi/boot boot boot/grub size=\$((\$size + 4096 * 4)) +# efi/debian and additional grub.cfg +if [ -d ${_CHROOT_DIR}/grub-efi-temp/efi/debian ]; then + size=\$((\$size + 4096)) + size=\$((\$size + \$(stat -c %s "${_CHROOT_DIR}/grub-efi-temp-cfg/grub.cfg"))) + cp ${_CHROOT_DIR}/grub-efi-temp-cfg/grub.cfg \ + ${_CHROOT_DIR}/grub-efi-temp/efi/debian +fi + blocks=\$(((\$size / 1024 + 55) / 32 * 32 )) rm -f ${_CHROOT_DIR}/grub-efi-temp/boot/grub/efi.img mkfs.msdos -C "${_CHROOT_DIR}/grub-efi-temp/boot/grub/efi.img" \$blocks >/dev/null mmd -i "${_CHROOT_DIR}/grub-efi-temp/boot/grub/efi.img" ::efi mmd -i "${_CHROOT_DIR}/grub-efi-temp/boot/grub/efi.img" ::efi/boot -mcopy -o -i "${_CHROOT_DIR}/grub-efi-temp/boot/grub/efi.img" ${_CHROOT_DIR}/grub-efi-temp/efi/boot/boot*.efi \ +mcopy -o -i "${_CHROOT_DIR}/grub-efi-temp/boot/grub/efi.img" ${_CHROOT_DIR}/grub-efi-temp/efi/boot/*.efi \ "::efi/boot" +if [ -d ${_CHROOT_DIR}/grub-efi-temp/efi/debian ]; then + mmd -i "${_CHROOT_DIR}/grub-efi-temp/boot/grub/efi.img" ::efi/debian + mcopy -o -i "${_CHROOT_DIR}/grub-efi-temp/boot/grub/efi.img" \ + ${_CHROOT_DIR}/grub-efi-temp-cfg/grub.cfg "::efi/debian" +fi + mmd -i "${_CHROOT_DIR}/grub-efi-temp/boot/grub/efi.img" ::boot mmd -i "${_CHROOT_DIR}/grub-efi-temp/boot/grub/efi.img" ::boot/grub mcopy -o -i "${_CHROOT_DIR}/grub-efi-temp/boot/grub/efi.img" ${_CHROOT_DIR}/grub-efi-temp-cfg/grub.cfg \ diff --git a/scripts/build/config b/scripts/build/config index c692a926f..cad73b4cd 100755 --- a/scripts/build/config +++ b/scripts/build/config @@ -116,6 +116,7 @@ USAGE="${PROGRAM} [--apt apt|aptitude]\n\ \t [--swap-file-path PATH]\n\ \t [--swap-file-size MB]\n\ \t [--tasksel apt|aptitude|tasksel]\n\ +\t [--uefi-secure-boot auto|enable|disable]\n\ \t [--updates true|false]\n\ \t [--backports true|false]\n\ \t [--verbose]\n\ @@ -148,6 +149,7 @@ Local_arguments () net-cow-server:,net-tarball:,firmware-binary:,firmware-chroot:,swap-file-path:,swap-file-size:, loadlin:,win32-loader:,source:,source-images:,breakpoints,conffile:,debug,force, help,ignore-system-defaults,quiet,usage,verbose,version,bootstrap-qemu-static:,bootstrap-qemu-arch:, + uefi-secure-boot:, bootstrap-qemu-exclude:" # Remove spaces added by indentation LONG_OPTIONS="$(echo ${LONG_OPTIONS} | tr -d ' ')" @@ -674,6 +676,11 @@ Local_arguments () shift 2 ;; + --uefi-secure-boot) + LB_UEFI_SECURE_BOOT="${2}" + shift 2 + ;; + --loadlin) LB_LOADLIN="${2}" shift 2 @@ -1299,6 +1306,10 @@ LB_SWAP_FILE_PATH="${LB_SWAP_FILE_PATH}" # \$LB_SWAP_FILE_SIZE: set swap file size # (Default: ${LB_SWAP_FILE_SIZE}) LB_SWAP_FILE_SIZE="${LB_SWAP_FILE_SIZE}" + +# \$LB_UEFI_SECURE_BOOT: enable/disable UEFI secure boot +# (Default: ${LB_UEFI_SECURE_BOOT}) +LB_UEFI_SECURE_BOOT="${LB_UEFI_SECURE_BOOT}" EOF # Creating lb_source_* configuration -- cgit v1.2.3