Background
I have a new(ish) laptop. I have two NVME drives in it. The first disk, nvme0, has Linux Mint 22.3 installed. Then I added a second disk, nvme1, and installed Windows 11 from scratch.
I used to try and manage one disk with many partitions, but Windows always tried to eat my linux install. By which I mean the windows bootloader would mess up my grub. So now we’re rocking two disks (on a budget, because storage and graphics cards are crazy right now…)
The problem
Grub recognizes the windows bootloader, and I end up getting the option during boot to select that as my side quest. Which is great. It’s easier than hitting F12 during boot repeatedly, waiting for the BIOS to load, and then selecting the other physical disk.
But the bitlocker warning pops up, and that’s a pain in the ass. It also yells at me about my PIN needing to be reset. Which requires me to use my full password, or my e-mail address that M$ has on file for me. Which requires an internet connection and phoning home to the mothership. And also my phone number as a 2nd factor, then putting in the code they send me. It’s a whole process. And the point of all this was to be able to switch back and forth between linux and windows quickly…
One option would be to just disable secure boot. But I know enough about cybersecurity from my job to know that 40% of other devices out in the world are malicious actors
As I understand it, during boot, the trusted platform module (TPM) 2.0 chips can keep track of file systems, hardware states, and the system clock. If windows boot manager detects a change in any of this, the TPM works with it to not release a key needed to decrypt your bitlocker key. That’s the best I understand it for now. I need to do some more reading, because encryption is fascinating. But essentially the key is stored in the TPM, and isn’t in a state at rest to be picked up and just used. The key itself is encrypted with a seed derived from the hardware state of your machine. That (I think) allows the EFI partition to be decrypted. Then that has your actual key needed to decrypt the rest of your partitions.
So by booting through the grub bootloader, we’re changing things from the state windows is expecting, that it was aware of during install.
The fix
First, we have to boot into windows, and disable some protections. This will allow you to get to the login screen by bypassing some of these hardware state checks initially.
This will require you to get into windows fully. Which is a chore. So if you were smart, you have your bitlocker key stored somewhere safe. If not, like me, you can go to account.microsoft.com/devices/recoverykey and put in all the info it wants. Then M$ will show you the bitlocker key associated with that device. Have that ready to go. And if you’re a little bit smart, save this into your password manager on your phone. So you can get to it with just your fingerprint next time you need it.
- Boot up
- Select Windows Boot Manager in the grub menu (you should have a grub menu, even if it’s got a 5 second timeout)
- Put in your bitlocker key
- Proceed to booting the OS
- Get to the login screen
- Acknowledge that your PIN has been compromised or whatever it’s yelling about
- Login with Microsoft’s multi-factor authentication
- Open the start menu and search for the powershell
- Launch the powershell as an administrator
Now you can turn off the protections. Adjust the drive letter if you’re using something other than C: as your boot drive.
manage-bde -protectors -enable c:
Wait for it to say that it’s completed the action, and shows the default prompt again.
- Reboot your computer
- Go into linux this time
- Open the terminal
- Figure out which is your efi partition
You can do this a number of ways. The first of which is with lsblk
ben@mylaptop:~$ lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS
...
nvme0n1 259:0 0 465.8G 0 disk
├─nvme0n1p1 259:1 0 512M 0 part
├─nvme0n1p2 259:2 0 256.1G 0 part /
├─nvme0n1p3 259:3 0 201.2G 0 part /home
└─nvme0n1p4 259:4 0 8G 0 part [SWAP]
nvme1n1 259:5 0 476.9G 0 disk
├─nvme1n1p1 259:6 0 200M 0 part /boot/efi
├─nvme1n1p2 259:7 0 128M 0 part
├─nvme1n1p3 259:8 0 474G 0 part
├─nvme1n1p4 259:9 0 1.1G 0 part
└─nvme1n1p5 259:10 0 1.5G 0 part
If you’re new at this, you can see that nvme0n1p2 is my partition that’s mounted as my root disk. And partition 3 of the same nvme drive is my /home directory. This confirms that nvme0 is the physical disk with linux on it. Meaning nvme1 has windows on it (if I didn’t mess it up in some crazy way. Spoiler… I didn’t)
We can also use the df utility.
ben@mylaptop:~$ df -h
Filesystem Size Used Avail Use% Mounted on
tmpfs 3.2G 2.3M 3.2G 1% /run
efivarfs 438K 241K 193K 56% /sys/firmware/efi/efivars
/dev/nvme0n1p2 252G 57G 183G 24% /
tmpfs 16G 2.5M 16G 1% /dev/shm
tmpfs 5.0M 8.0K 5.0M 1% /run/lock
/dev/nvme0n1p3 197G 118G 70G 63% /home
/dev/nvme1n1p1 196M 114M 83M 58% /boot/efi
tmpfs 3.2G 220K 3.2G 1% /run/user/1000
(some mounted NFS shares)
This also shows /boot/efi, which is a windows partition and not used in linux that way, is on /dev/nvme1n1p1.
Cool. So now what we actually need is the universally unique identifier (UUID) for that partition. Let’s go get that. If you don’t know, disks are listed in the devices folder. So in /dev/ you’ll see nvme[0-x], sd[a-x], ttyUSB[0-x], I2C interfaces, etc. There’s a subfolder in here called /disk/by-uuid. So if I unplug one disk, and plug another one into my SATA port, references to /dev/sda don’t get broken. So let’s (get this show moving already, and) list all devices in this folder.
ben@mylaptop:$ ls -l /dev/disk/by-uuid
total 0
lrwxrwxrwx 1 root root 15 Sep 2 10:50 2C4E39014E38C4FC -> ../../nvme1n1p4
lrwxrwxrwx 1 root root 15 Sep 2 10:50 3AB4-4E24 -> ../../nvme1n1p1
lrwxrwxrwx 1 root root 15 Sep 2 10:50 44EAEE8AEAEE7816 -> ../../nvme1n1p5
lrwxrwxrwx 1 root root 15 Sep 2 10:50 56da85b0-c87b-43a8-980b-5adefe940da5 -> ../../nvme0n1p2
lrwxrwxrwx 1 root root 15 Sep 2 10:50 7CC4-9E6E -> ../../nvme0n1p1
lrwxrwxrwx 1 root root 15 Sep 2 10:50 8dcde50f-839e-4b0c-8b3b-14abfb98272a -> ../../nvme0n1p4
lrwxrwxrwx 1 root root 15 Sep 2 10:50 d4ecb485-8f6c-4a1a-8273-d4d2942a4812 -> ../../nvme0n1p3
These aren’t in any order, other than the UUID, which is not something you can change easily. So you can see the second item in the list is my nvme1n1p1 partition. Its UUID is only 8 characters, or 4 bytes long. 3AB4-4E24. This is the actual string you’ll need.
So now we’re finally ready to update grub. We’re going to do something called chain loading, and let grub point directly to the .efi file on that partition.
ben@mylaptop:$ sudo nano /etc/grub.d/40_custom
Notice that there are 3 lines of notes. Read them. You’re modifying the file by appending to it, not by erasing everything that’s already in there. The first 2 lines are useful and shouldn’t be mucked about with unless you really know what you’re doing.
#!/bin/sh
exec tail -n +3 $0
# This file provides an easy way to add custom menu entries. Simply type the
# menu entries you want to add after this comment. Be careful not to change
# the 'exec tail' line above.
menuentry 'Windows Boot Manager (new)' {
search --fs-uuid --no-floppy --set=root 3AB4-4E24
chainloader /EFI/Microsoft/Boot/bootmgfw.efi
}
You can see on line 3 where the UUID is. Replace that with yours. You can also see on the last line that there’s a filesystem on the EFI partition. And we’re pointing grub directly at the bootmgfw.efi file.
Save this. With ctrl+o and ctrl-x for nano. Or however you want to save in your text editor of choice.
Now we’re just going to update grub for our next boot, using the sudo update-grub command.
We’re finally ready to boot back into windows, in an order that will be consistent for whatever hardware checks the secure boot process needs.
- Reboot your machine
- When grub hangs, navigate to the bottom to the Windows Boot Manager (new) entry that you just created.
- You should boot into windows without the bitlocker key (because we disabled it the last time we were in windows)
- You will still need to do some MFA steps to login, since it still thinks your PIN has been messed with.
- I chose to ‘reset your PIN’, and just set it back to what it was before. I’m not sure if this will work or not if you cancel out of the PIN reset step.
- Let Windows load the desktop and do what it’s going to do.
- Run the powershell again.
- Re-enable the protections we had before with
manage-bde -protectors -enable c:
Again, modifying if your boot drive letter is something other than C:
End
Well, that’s it! You should be able to reboot at this point, select the windows bootloader from the grub menu, and have it all work, only having to enter your PIN. No more bitlcker, no more e-mail and code, text message and code, login with github, or any of that. Boot, choose your OS, enter your PIN. The end. I hope this helps someone. I’d been living like a heathen for longer than I’d like to admit. But it finally wore me down enough to go fix it the right way. Until next time…