Encrypted bootable media with SecureBoot/GRUB/LUKS

From Gentoo Wiki
Jump to:navigation Jump to:search

Motivation

Often bootable media holds unencrypted next stage boot content like kernel, initramfs and other boot config.

Encrypting bootable media can enhance privacy, and prevent unauthorized access.

Abstract

Overall boot process varies depending on the hardware platform being used.

This page focuses primarily on x86_64 architecture with simplified boot process chain:

Hardware -> UEFI -> Unified kernel image (UKI) -> OS

Per design boot stages hardware->UEFI and UEFI->UKI are never encrypted.

These boot stages can only protected by cryptographic signature like Secure Boot.

Implementation

GRUB boot loader support encrypted next stage boot content.

As UEFI still needs unencypted next stage bootloader, GRUB boot loader have to be splited into two parts: unencrypted GRUB core and encrypted next boot stage content.

Unencrypted GRUB core can protected by cryptographic signature like Secure Boot also.

Installation

Prepare bootable media

Note
Bootable media example is an USB device.
Tip
Do not be miserly on partition sizes. Leave room for additional future payloads like rescue boot.
Partition Size Purpose Encrypted? Comment
1 1 MiB BIOS GRUB unencrypted not in use on UEFI platform (only needed on PC-BIOS platform)
2 1 GiB UEFI ESP unencrypted GRUB core, UKI and firmware update blobs.
3 2 GiB GRUB data encrypted GRUB content and next stage boot loaders

Create bootable media partition

Tip
Use shell variable to protect against unintentionally reuse of destructive commands from shell history.
root #export bootmedia=/dev/disk/by-id/usb-General_USB_Flash_Disk_01234567890-0:0

Double check for empty media source:

root #parted "${bootmedia}" print
Warning
Next command is DESTRUCTIVE and can DESTROY data. CHECK your selected media twice.
root #parted --script "${bootmedia}" \
    "mklabel gpt" \
    "mkpart 'BIOS Grub'  34s            1mib" \
    "mkpart 'EFI System' 1mib           $((1+1024))mib" \
    "mkpart 'Grub data'  $((1+1024))mib $((1+1024+2024))mib" \
    "set 1 bios_grub on" \
    "set 2 esp on" \
    "type 3 ca7d7ccb-63ed-4c53-861c-1742536059cc"

Partitions should look like:

root #parted "${bootmedia}" unit mib print
...
Partition Table: gpt
Disk Flags: 

Number  Start    End      Size     File system  Name        Flags
 1      0.02MiB  1.00MiB  0.98MiB               BIOS Grub   bios_grub
 2      1.00MiB  1025MiB  1024MiB               EFI System  boot, esp
 3      1025MiB  3049MiB  2024MiB               Grub data
Tip
PARTUUID can be changed with "gdisk" from sys-apps/gptfdisk package.

Create bootable media filesystems

Create EFI System Partition (ESP) filesystem
See also
For more information: EFI System Partition.
root #mkfs.fat -v -F 32 -S 4096 -n "efi-bootfs" -i ef10b001 "${bootmedia}-part2"
Create encrypted GRUB data filesystem

Prepare partition by filling with random data:

See also
For more information: Secure wipe.
root #shred --verbose -n1 "${bootmedia}-part3"

Create encrypted partition with LUKS2 container:

See also
For more information: Dm-crypt.
Important
Cryptsetup format options based on best practice but maybe unsuitable on slow systems.
root #cryptsetup luksFormat --type luks2 --cipher aes-xts-plain64 --key-size 512 --hash sha512 --pbkdf argon2id --pbkdf-force-iterations 10 --pbkdf-memory 524288 --pbkdf-parallel 4 --use-random "${bootmedia}-part3"

Open encrypted partition to create a filesystem on it:

root #cryptsetup open "${bootmedia}-part3" "${bootmedia##*/}-part3.luks"

Create GRUB data filesystem:

See also
For more information: ext4.
root #mkfs.ext4 -e remount-ro -m 0 -L "grub-bootfs" /dev/mapper/"${bootmedia##*/}-part3.luks"

Install GRUB boot loader

See also
For more information: GRUB.

Mount filesystems for GRUB boot loader installation:

root #mkdir /mnt/bootmedia_efi
root #mount -o noatime,dmask=022,fmask=133 "${bootmedia}-part2" /mnt/bootmedia_efi
root #mkdir /mnt/bootmedia_grubdata
root #mount -o noatime /dev/mapper/"${bootmedia##*/}-part3.luks" /mnt/bootmedia_grubdata

Enable GRUB encrypted data support:

root #echo GRUB_ENABLE_CRYPTODISK=y >> /etc/default/grub

Install GRUB boot loader:

Important
As of 2024.09 GRUB support only PBKDF2 and not "stronger" Argon2 key derivation function.
Copy argon_*.patch files from grub-improved-luks2-git[1] to /etc/portage/patches/sys-boot/grub-2.12/ directory.
Tip
Use --removable to intall EFI/BOOT/BOOTX64.EFI blob (EFI default search if no efibootmgr entry exist).
When Secure Boot is active loading additional GRUB modules at GRUB runtime is not allowed.
root #GRUB_PREBOOT_MODULES="argon2 gcry_sha256 gcry_sha512"
root #GRUB_ALLOWEDSECUREBOOT_MODULES="linux tpm"
root #grub-install --target=x86_64-efi --boot-directory=/mnt/bootmedia_grubdata --efi-directory=/mnt/bootmedia_efi --modules "${GRUB_PREBOOT_MODULES} ${GRUB_ALLOWEDSECUREBOOT_MODULES}" --recheck --removable --disable-shim-lock

(optional) sign GRUB boot loader

Important
This page assume custom Secure Boot with own sign key and cert in place.
See also
For more information: Secure Boot.
root #sbsign --key "${SECUREBOOT_SIGN_KEY}" --cert "${SECUREBOOT_SIGN_CRT}" --output /mnt/bootmedia_efi/EFI/BOOT/BOOTX64.EFI /mnt/bootmedia_efi/EFI/BOOT/BOOTX64.EFI
root #sbverify --list /mnt/bootmedia_efi/EFI/BOOT/BOOTX64.EFI
root #sbverify --cert "${SECUREBOOT_SIGN_CRT}" /mnt/bootmedia_efi/EFI/BOOT/BOOTX64.EFI

Backup signed GRUB core in case generic BOOTX64.EFI will be overridden:

root #mkdir /mnt/bootmedia_efi/EFI/grub/
root #cp -a /mnt/bootmedia_efi/EFI/BOOT/BOOTX64.EFI /mnt/bootmedia_efi/EFI/grub/grubx64.efi

Configuration

Configure GRUB next stage boot loader

Install default GRUB config:

root #grub-mkconfig -o /mnt/bootmedia_grubdata/grub/grub.cfg

Example custom config to boot kernel with initramfs from encrypted GRUB data partition.

FILE /mnt/bootmedia_grubdata/grub/custom.cfg
submenu "host1 (menu)" {
    menuentry "host1 [curr]" {
        linux /linux/host1/kernel-curr
        initrd /linux/host1/initramfs.cpio.xz /linux/additional.cpio
    }
    menuentry "host1 [prev]" {
        linux /linux/host1/kernel-prev
        initrd /linux/host1/initramfs.cpio.xz /linux/additional.cpio
    }
}

Example custom config to boot SystemRescue ISO[2] from encrypted GRUB data partition.

Tip
GRUB module "loopback" was not enabled on Secure Boot for safety. Disable Secure Boot or add "loopback" to pre-load GRUB module list.

Replace <GRUBDATA-LUKS-UUID> with effective UUID from GRUB data LUKS container.

SystemRescue will load ISO payload from encrypted GRUB data partition, so GRUB data password needs to enter again.
FILE /mnt/bootmedia_grubdata/grub/custom.cfg
submenu "SystemRescue (menu)" {
    set sysrcd_version='11.01'
    menuentry "Boot SystemRescue ${sysrcd_version}" {
        set gfxpayload=keep
        set isofile="/iso/systemrescue-${sysrcd_version}-amd64.iso"
        loopback loop ${isofile}
        # use cryptdevice= to open encrypted GRUB boot filesystem (grub-bootfs) again
        linux (loop)/sysresccd/boot/x86_64/vmlinuz cryptdevice=UUID=<GRUBDATA-LUKS-UUID>:grub-bootfs_crypt img_label=grub-bootfs img_loop=${isofile} archisobasedir=sysresccd iomem=relaxed ar_source=/dev/mapper/grub-bootfs_crypt
        initrd (loop)/sysresccd/boot/intel_ucode.img (loop)/sysresccd/boot/amd_ucode.img (loop)/sysresccd/boot/x86_64/sysresccd.img
    }
}

Clear up

Close all bootmedia filesystems and LUKS container:

root #umount /mnt/bootmedia_efi
root #umount /mnt/bootmedia_grubdata
root #cryptsetup close "${bootmedia##*/}-part3.luks"
root #unset bootmedia

See also

  • UEFI — a firmware standard for boot ROM designed to provide a stable API for interacting with system hardware. On x86 it replaced the legacy BIOS.
  • Secure Boot — an enhancement of the security of the pre-boot process of a UEFI system.
  • GRUB — a multiboot secondary bootloader capable of loading kernels from a variety of filesystems on most system architectures.
  • Dm-crypt — a disk encryption system using the kernels crypto API framework and device mapper subsystem.
  • ext4 — an open source disk filesystem and most recent version of the extended series of filesystems.
  • Full Disk Encryption From Scratch — a guide which covers the process of configuring a drive to be encrypted using LUKS and btrfs.

References