Grub 2 fails to boot a kernel on a luks encrypted volume with Secure Boot enabled

Bug #1565950 reported by Chris Marks on 2016-04-04
142
This bug affects 28 people
Affects Status Importance Assigned to Milestone
grub2 (Ubuntu)
Medium
Unassigned

Bug Description

Booting in UEFI Secure Boot requires that all code loaded up to and including the OS kernel be signed. This includes all grub modules. This is accomplished by including selected modules in a single signed binary. However, the modules required for grub to use an encrypted volume have been omitted from the binary package and therefore Ubuntu cannot boot from an encrypted volume with Secure Boot enabled. This can be corrected as follows.

The debian/build-efi-images file needs to have lines 136-140 changed from:

GRUB_MODULES="$CD_MODULES
 lvm
 mdraid09
 mdraid1x
 "

to:

GRUB_MODULES="$CD_MODULES
 cryptodisk
 gcry_arcfour
 gcry_blowfish
 gcry_camellia
 gcry_cast5
 gcry_crc
 gcry_des
 gcry_dsa
 gcry_idea
 gcry_md4
 gcry_md5
 gcry_rfc2268
 gcry_rijndael
 gcry_rmd160
 gcry_rsa
 gcry_seed
 gcry_serpent
 gcry_sha1
 gcry_sha256
 gcry_sha512
 gcry_tiger
 gcry_twofish
 gcry_whirlpool
 luks
 lvm
 mdraid09
 mdraid1x
 "

Launchpad Janitor (janitor) wrote :

Status changed to 'Confirmed' because the bug affects multiple users.

Changed in grub2 (Ubuntu):
status: New → Confirmed
Changed in grub2 (Ubuntu):
importance: Undecided → Medium
Marcin (marcincelebucki) wrote :

This bug is also attached for any other grub2 module, example for: loopback
"error: Secure Boot forbids loading module from (hd0, msdos1)/EFI/ubuntu/x86_64-efi/loopback.mod."

tags: added: xenial

This is not a duplicate of bug #1062623. That other bug has to do with grub install and setting some switches to ease installation. This bug has to do with the modules that are included in the signed grub binary without which an encrypted boot partition cannot be loaded if the UEFI BIOS is set to require Secure Boot.

Nazar Mokrynskyi (nazar-pc) wrote :

For me the issue is even deeper.
I'm not striving for Secure Boot, just for UEFI with encrypted `/boot`.

However, even when `/boot/grub/grub.cfg` contains lines with `insmod luks` and `insmod cryptodisk` (I've tried even both `GRUB_ENABLE_CRYPTODISK=y` and `GRUB_PRELOAD_MODULES="luks cryptodisk"` at the same time), resulting `/boot/efi/EFI/ubuntu/grubx64.efi` (on ESP partition, of course) doesn't have those modules embedded and thus falls back to console without possibility to actually boot the system.

I feel like modules bundling is broken, since, for instance, BTRFS driver is always bundled independently from whether I use BTRFS or ext4.

@Nazar, Are you saying that the modules are not on your ESP? If so, they need to be there. Mine are on the ESP at EFI/ubuntu/x86_64-efi/.

Nazar Mokrynskyi (nazar-pc) wrote :

No, they are not on ESP (I mean files like luks.mod, etc.), my assumption is that those files should be bundled into `grubx64.efi`, otherwise what is the point of having options like `GRUB_PRELOAD_MODULES`.

Is my assumption wrong and it works in a different way? I'd really like to avoid keeping anything besides `EFI\ubuntu\grubx64.efi` and `EFI\ubuntu\grub.cfg` on ESP partition.

I'm not an expert on what the GRUB_PRELOAD_MODULES is used for, but I know that it only specifies that grub should load the specified modules as early as possible in the boot process. AFAIK, the modules you need to actually load and handoff to your chosen kernel must be in the ESP.

Nazar Mokrynskyi (nazar-pc) wrote :

I'm not an expert either. I'm just wondering why some modules are there and others not. I think it makes sense to bundle everything that is explicitly used in `/boot/grub/grub.cfg` automatically.

Nazar Mokrynskyi (nazar-pc) wrote :

I've tried to `insmod luks` manually (I've copied luks.mod, cryptodisk.mod and procfs.mod to ESP for this purpose).
2 issues here:
1) It is trying to find modules in `/@/boot/grub/*`, while that will clearly be inaccessible until decrypted (thud modules should be bundled with grubx64.efi
2) When manually loading necessary modules, `search.fs_uuid` from `ESP/EFI/ubuntu/grub.cfg` still results in `error: no such device: <UUID>`

No password prompt at any step.

I believe there should be a way to boot the system with encrypted `/boot`.

Nazar Mokrynskyi (nazar-pc) wrote :

Updated test setup to current 17.04 and after manual loading necessary modules alongside with `cryptomount -a` I was finally able to see `Ubuntu`, but didn't went any further because of https://forums.virtualbox.org/viewtopic.php?f=3&t=76791

Nick B. (futurepilot) wrote :

Just encountered this problem when trying to setup a fully encrypted system. I rebuilt the grub2 package with the changes listed in the first comment and tested in VirtualBox in UEFI mode and it does work.

You can't simply copy the modules to the ESP partition because it a) won't work with secure boot and b) grub seems to be hardcoded to try to load them from the /boot/grub/ directory which isn't accessible at that point in the boot process and there doesn't appear to be a way to specify them manually.

Can these extra modules please get included in the grubx64.efi binary?

Nazar Mokrynskyi (nazar-pc) wrote :

Yes, Secure Boot will not work, however, grubx64.efi happily uses grub.cfg that is placed in the same directory and you can instruct GRUB to load modules from other location, here is my config:
search.fs_uuid E495-1F0C boot
set prefix=($boot)'/EFI/ubuntu'
insmod luks
insmod gcry_sha256
cryptomount -u 739967f19770470aa0318d8b8bcdb350
search.fs_uuid 5170aca4-061a-4c6c-ab00-bd7fc8ae6030 root cryptouuid/739967f19770470aa0318d8b8bcdb350
set prefix=($root)'/root/boot/grub'
configfile $prefix/grub.cfg

kay (kay-diam) wrote :

If signed grub allows to load unsigned modules from encrypted partition - this is a high security issue. Spoofed module can store the decryption password.

kay (kay-diam) wrote :

s/encrypted/unencrypted efi/

Phillip Susi (psusi) wrote :

The whole point is that you can't do that when secure boot is enabled.

Andreas Oberritter (obi++) wrote :

Besides including the required modules into the binary, which would be very appreciated, please consider the following options:

1.) Install all required modules to the ESP. Although this doesn't help secure boot, this would allow booting insecurely in order to be able to uninstall signed grub.

2.) Refuse to install signed grub on systems unable to boot it, because of inaccessible filesystems.

3.) Install both signed and unsigned grub in parallel.

Andrew Gunnerson (cxl) wrote :

Yep, I had to chroot into the installation, remove the Ubuntu-signed GRUB, run grub-install, and sign the EFI binary with my own key for secure boot.

Nazar Mokrynskyi (nazar-pc) wrote :

This bug is almost 2 years old and no one seems to care about it unfortunately

TJ (tj) wrote :

I've just been caught out by this when the EFI -signed- packages somehow got themselves installed - despite having been removed in the past when they appeared due to a change in the depends - and replaced the locally built grubx64.efi that contains the cryptodisk, luks, etc., modules, leaving the system unbootable.

On another (BIOS-based) system I started an LXD 18.04 container, installed grub-amd64-efi, and then built a custom core image to transfer to a USB stick and then used the the EFI boot manager to add that to the boot menu. Once that started I used the grub shell to unlock the encrypted /boot/ file-system, reset 'root' and 'prefix' and started the usual menu.

Here's the commands I used to build the grubx64.efi inside the container.

apt install grub-amd64-efi

## I added the following to /etc/default/grub (just in case - I think this is only noticed by grub-install though)

GRUB_ENABLE_CRYPTODISK=y

mkdir -p /boot/efi/EFI/UBUNTU
grub-mkimage -v -p /boot -o /boot/efi/EFI/UBUNTU/grubx64.efi -O x86_64-efi part_gpt fat ext2 efi_gop cryptodisk luks gcry_rijndael gcry_sha1 usb usbms usb_keyboard efifwsetup efinet iso9660 help gcry_sha256 loopback lsefi lsefimmap lsefisystab lvm mdraid09 mdraid1x part_msdos ntfs ntfscomp squash4 tftp http udf ufs1 ufs2 exfat ehc
i uhci cat

Then from the host PC I wrote a GPT with a single 256MB partition to an memory card (SD-card in this case) and formatted it as FAT16 and copied the GRUB core image to it:

mkfs.vfat -F 16 /dev/mmcblk0p1
mkdir -p /mnt/boot
mount /dev/mmcblk0p1 /mnt/boot
mkdir -p /mnt/boot/EFI/BOOT
cp /var/lib/lxd/containers/u1804/rootfs/boot/efi/EFI/UBUNTU/grubx64.efi /mnt/boot/EFI/BOOT/BOOTX64.EFI
umount /mnt/boot

Then I rebooted the EFI PC with the SD-Card inserted in a USB card-adapter into its setup program and added a boot menu entry pointing to the BOOTX64.EFI, then booted to it.

Once in the GRUB rescue shell I identified the partition containing encrypted GRUB root file-system (Known as /boot/ on Linux) using:

> ls
> ls (hd1,gpt2)
Unknown filesytem

And then did:

> cryptomount hd1,gpt2

Typed the passphrase correctly and saw:

slot 0 opened

Then I did 'ls' to list the devices and saw a new (crypto0) device. I checked that GRUB could read the file-system inside it with:

> ls (crpyto0)/

Then reset the environment variables:

> set root=crypto0
> set prefix=($root)/grub
> ls $prefix/

Having seen the files in the GRUB directory I then loaded the menu-generating module and executed it:

> insmod normal
> normal

And booted normally.

Lastly I identified and removed the grub*signed packages and those that depend on them, and regenerated the correct grubx64.efi core image.

apt list --installed grub*
apt list --installed shim*

sudo apt remove shim shim-signed grub-efi-amd64-signed
sudo grub-install /dev/sda
sudo ls -latr /boot/efi/EFI/ubuntu/

I confirmed the EFI boot menu entry was now pointing to the newly generated grubx64.efi

sudo efibootmgr -v

Paddy Landau (paddy-landau) wrote :

I believe that bug #1401532 is related (but not a duplicate).

To post a comment you must log in.
This report contains Public information  Edit
Everyone can see this information.

Other bug subscribers