Skip to content

Instantly share code, notes, and snippets.

@kurtbahartr
Last active October 2, 2024 19:42
Show Gist options
  • Save kurtbahartr/31fdd1961cb5b5b4a6754c57224fa520 to your computer and use it in GitHub Desktop.
Save kurtbahartr/31fdd1961cb5b5b4a6754c57224fa520 to your computer and use it in GitHub Desktop.
Install Brunch secure boot keys from within ChromeOS after installation without a Linux live environment

ATTENTION!

Brunch changed the way the EFI firmware is handled within the kernel, and `/sys/firmware/efi` is now called `/sys/firmware/brunchefi`. This guide relies on the fact that the mokutil provided in the Debian repos look into the `.../efi/` directory and not the latter. If you want to proceed with this guide, you have to compile mokutil and its dependencies with the new path yourself.

Prologue

ChromeOS is something so efficient yet sometimes so locked down OS and it's what I love the most about it. It provides you flexibility while locking down things that only researchers and power users would be concerned about.

Right as I downgraded my ChromeOS system and Brunch Framework back to stable releases and doing some random research about ChromeOS (I forgot what specifically), I came across this Google support article explaining the differences between regular ChromeOS and ChromeOS Flex, out of which this specific point caught my interest:

ChromeOS devices contain a Google security chip that helps to protect the system and verify that hardware and OS are trusted. Because ChromeOS Flex devices don’t contain a Google security chip, the ChromeOS verified boot procedure is not available on them.
As an alternative, Microsoft reviewed and approved ChromeOS Flex’s bootloader to optionally support UEFI Secure boot. Secure boot can’t provide the security guarantees of ChromeOS verified boot, but it can maintain the same boot security as Windows devices, preventing unknown third-party operating systems from booting on ChromeOS Flex devices. See Microsoft documentation.
Google recommends that you turn on Secure boot on all your ChromeOS Flex devices
~ https://support.google.com/chromeosflex/answer/11542901?hl=en

So you see, Google does provide proper secure boot, which is usually pre-enrolled with Microsoft's certificates, as some kind of an alternative to Google security chip, which is meant for OS protection for the most part. Armed with this knowledge, let's dive into what Brunch has for us given there's really little documentation about secure boot in Brunch's side.

Keep in mind that we'll approach the generic Linux way to enroll the key, using mokutil. Don't worry, just one part of it might jumpscare you but the process is relatively easy.

Determining the location of the EFI partition

If you're like me and want to watch your console as it does things, you might have noticed Brunch also flashes a partition called EFI-SYSTEM on the target disk. If you have little knowledge about Linux live images that ask you to enroll secure boot keys to boot up, you should know that the certificates to boot up the disk is usually located in either \EFI\BOOT\<distro>.cer or right at the root of the partition holding the EFI binaries under the same name. I know it's extremely oversimplified and too theoretical, but it will be really useful along the track.

So let's dive into some command line, shall we?


Gaining access to the root shell

If you booted Brunch up with default options (I.e. cros_debug is present in linux command line in its GRUB config), you should have access to a shell already since the cros_debug parameter is meant to emulate developer mode.

There are two ways to get into a root shell with debug enabled;

  1. You can just switch to the TTY (Ctrl+Alt+F2, the regular Linux way), log into it as chronos and do sudo -i.
  2. You can enable enable_crosh_sudo in Brunch config followed by a reboot, let it do the deed, launch Crosh after logging in (Ctrl+Alt+T, same shortcut as launching terminal in Ubuntu) and do sudo -i, both yield about the same results.

Once we're in a root Bash session, we can now use blkid to see what partition is our EFI partition;

blkid | grep EFI-SYSTEM

The very beginning of the output of this command should give you the device and the partition number where the partition resides in, should be the 12th partition if I'm not mistaken.

Important

I'll be using nvme0n1p12 to refer to the EFI-SYSTEM partition for MY system. Use the output you've grabbed from the blkid command and replace it with your own!

So what are we waiting for? Time to mount it!

mkdir /brunch-efi
mount /dev/nvme0n1p12 /brunch-efi

Now we'll need ChromeOS itself again so switch back to the GUI with Ctrl+Alt+F1 if you're going with TTY approach. Crosh users can just proceed while keeping the shell open.

Getting mokutil and its dependencies from Crostini

Note

If you have the skills to unpack a Debian package and grab the files from it on your own instead, you don't have to jump through this many hoops and can just get the contents of mokutil and libefivar1 packages instead.

ChromeOS doesn't have such an utility like mokutil on its own so we need to grab it ourselves. Chromebrew might provide it themselves or it might be a part of brunch-toolkit too but I prefer to go the DIY route and grab the binaries from within Crostini instead since I know for sure Debian provides mokutil and its dependencies in its package repos.

If you haven't, set up Linux development environment from system settings!

Now drop into the "penguin" container in the Terminal app and give it the following command, make sure you have a working internet connection;

sudo apt install mokutil apt-file
sudo apt-file update

Important

Installing apt-file is really important for us to be able to search through packages later on!

Once you install mokutil, which should have only one dependency being libefivar1, we need to grab the smallest portion of files from Crostini to get mokutil to just work. I'll walk you through the process instead of telling just what files to grab to be future-proof.


Determining the files in the packages we've just installed

I'll just give the commands here since they should be self-explanatory.

apt-file list mokutil
apt-file list libefivar1

The only files that are of our concern here are the ones placed in /usr/bin and the likes (such as /usr/lib as well), we don't need the documentation and license files for our goal.


Now let's create the minimal structure we'll place mokutil into. I'm choosing to name the root of the structure as mokutil-portable but you can use whatever name you want.

mkdir -p ~/mokutil-portable/{bin,lib}

Now you should copy over the files you've gathered with the apt-file commands into the corresponding directories. I might also write a simple function that will simplify this entire operation for you in the future.

Copying over our work to ChromeOS

Now fire up the Files app on your ChromeOS installation and copy the mokutil-portable folder you've just prepared into Downloads or My Files. I'll use the Downloads folder for familiarity.

Remounting user data partition to allow execution and enabling efivarfs

Let's switch back to the root shell (either by Ctrl+Alt+F2 or getting back on Crosh app) and do some preparation!

We first have to remount our user partition and allow execution since ChromeOS mounts it with noexec by default. Source: Personal experience xd

mount -o exec,remount /home/chronos/user

Once that's done, we need to make EFI variables actually visible;

modprobe efivarfs
mount -t efivarfs efivarfs /sys/firmware/efi/efivars

Now to the real deal, finally!

Enrolling the key for Brunch!

From now on, everything is pretty much the same as how you would handle this on a regular Linux install. Remember where you've mounted the EFI partition at the beginning of this documentation!

cd /home/chronos/user/MyFiles/Downloads/mokutil-portable
chmod +x mokutil
./mokutil --import /brunch-efi/brunch.der

Important

mokutil will ask you to enter a password. It's not the password you've chosen as your sudo password! This password is for single use and will only be used by Shim UEFI Key Management only for that very session so make sure to choose something simple to be quick!

If everything goes well, you can reboot and let your computer get into the key management.

Important

The enrollment screen has a 10-second timeout before it can show the menu! If you don't press a key until the timer runs out, you'll have to do the entire process again!

After you've gotten into the key management, everything should be pretty much breeze, just choose "Enroll MOK" and confirm the enrollment, after which you need to enter the password you've fed mokutil with. Once that's done, you can just reboot, turn on secure boot right away - or test things before doing so - and watch Brunch boot up in the slightly more secure environment you've provided to it!

Afterwords

That's it! We've finally done it! I still cannot believe it took me 10 years of tinkering with Linux, using the knowledge I've gotten from doing so in different years, and very little research to achieve this. Anyway, I hope you enjoy your fireproof brunch, Bon Appétit! ;)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment