December 4, 2022

OpenBSD: Full encryption and dual boot with gnu/linux (encrypted as well)

Intro

It is possible to fully encrypt your OpenBSD partition if you are dual-booting, which I am. I have a small gnu/linux partition to use for blobs like skype, zoom etc.

 

 

In this guide I will assume that you have installed gnu/linux (ubuntu) first on the disc and you have toggled the partition destined for OpenBSD as “openbsd data” using fdisk from gnu/linux:

# fdisk /dev/nvme0n1
nvme0n1    nvme0n1p1  nvme0n1p2  nvme0n1p3  nvme0n1p4  
root@amphyction:/home/pau# fdisk /dev/nvme0n1

Welcome to fdisk (util-linux 2.37.2).
Changes will remain in memory only, until you decide to write them.
Be careful before using the write command.

Command (m for help):

Here you choose “t” for toggle and change the labeling of the partition where you want to install OpenBSD to 226 or so (it used to be a6 in the past)

Command (m for help): t
Partition number (1-4, default 4): 4
Hex code or alias (type L to list all): 226

We start with (I)nstall on the command line.

This allows us to e.g. choose the keyboard layout.

disklabel

The important thing is to identify which part of the disc corresponds to the OpenBSD partition. We can achieve this with disklabel -E on the drive

# disklabel -E sd0

If you have toggled the partition with linux’ fdisk to “openbsd data” it will be easy to identify it and the installer will know exactly at what cylinder it stars and where it ends. Very helpful.

disklabel will show you the partitions containing linux and the uefi files (ext2fs and MSDOS, respectively).

Add a new partition taking the rest of the space. Check that the offset corresponds to what disklabel is showing you in the “OpenBSD area” line. It should be the same number of cylinder. Otherwise, you will be overwritting other partitions.

sd0> a a
offset: [82225152]
size: [917989376]
FS type: [4.2BSD]
sd0*> w
sd0> q
No label changes.

Random data and encryption

Now that we have a partition for OpenBSD, we can write random data to the drive first. Note the “rsd0a” part of the command.

# dd if=/dev/urandom of=/dev/rsd0a bs=1m

Declare “a” to be of RAID type. In my case, it looked like this:

sd0> a a
offset: [82225152]
size: [917989376]
FS type: [4.2BSD] RAID
sd0*> w
sd0> q
No label changes.

Now build the encrypted device on our “a” partition.

# bioctl -c C -l sd0a softraid0

If everything goes well, you will get the name of your new device:

softraid0: CRYPTO volume attached as sd2

Create it

# cd /dev && sh MAKEDEV sd2

Overwrite the first megabyte

# dd if=/dev/zero of=/dev/rsd2c bs=1m count=1

Type exit to return to the main installer and choose sd2 as the device for the installation.

Do the usual installation. If you are doing it from a USB drive, in my case it was sd1 and it was not mounted.

After this the laptop will boot. In my case, a thinkpad l13 gen 3, to choose the OpenBSD encrypted partition, I have to press F12 when the red lenovo logo shows up after powering up the laptop. I then choose the entry which shows the name of the inner drive and this leads to the prompt screen of OpenBSD asking me for the bioctl password.

Install linux

It’s not a secret that gnu/linux is becoming more and more like windows. I do not understand anything of it. There is “magic” everywhere, and recession. I do not like it but I need it and slightly prefer it (still) over windows.

In any case, I want the linux partition to be (almost) fully encrypted as well. For that I have found out that the best thing to do as of today (August 2023) is to use any distribution which comes with the calamares installer. You will find a list of the linux distributions which ship calamares here. That allows me to encrypt everything but for one small partition using the manual partitioning. Using other installers has proven to be a real nightmare. Anyway, the unencrypted partition is

/boot/efi/

and then flag it to “boot”.

I have then a second fully encrypted partition for everything, i.e.

/

For some reason, it takes about one full minute for the OS to decrypt it after boot. I do not understand why, because OpenBSD’s (more serious) encryption takes literally less than one minute to decrypt and start. Anyway… linux’ magic, as I was mentioning before.

Booting from grub

We will now find out how to tell grub2 in linux where OpenBSD is and how to boot it.

First, download the OpenBSD UEFI file from your closest mirror. In my case it is under snapshots, amd64, and it is called “BOOTX64.EFI”.

Place it at exactly this location on your gnu/linux installation and rename it to whatever you want, for instance openbsdx64.efi:

# mv BOOTX64.EFI /boot/efi/EFI/BOOT/openbsdx64.efi

Then use grub-customizer or edit /etc/grub.d/40_custom to add OpenBSD. I am doing the former because grub2 is a pain.

Grub2 syntax for OpenBSD

These are the difficult bits (at least for me). I have found out the best way to see where OpenBSD is living in grub2 terminology. For that, I start grub and then jump to the terminal.

grub> ls (hd0,gtp1)/efi/boot

This shows the efi files, as expected, since gpt1 is my first partition on the drive, hd0.

If you have your OpenBSD unencrypted, you can keep on trying on the rest of partitions like

grub> ls (hd0,gtp2)/

When you find the one with OpenbSD on it, you will recognise the usual content:

bsd bsd.booted bsd.rd bsd.sp

etc, etc.

But, since we have encrypted our OpenBSD partition, grub will not be able to tell us what’s on it. In any case, simply keep trying by doing this:

grub> set root='(hd0,gtp4)'
grub> chainloader (hd0,gtp1)/efi/boot/openbsdx64.efi
grub> boot

If you got the partition right, (in this case, gtp4), it will boot. Keep trying until you find the right one. Write it down to make it permanent in the grub configuration later.

With grub-customizer, I have added an “Other” entry with title OpenBSD (curiously) with the following lines:

set root='(hd0,gpt4)'
chainloader (hd0,gtp1)/efi/boot/openbsdx64.efi

Be careful about the quotes in (hd0,gpt4). It turns out that, for some obscure reason, ubuntu is NOT using sh but dash

amphyction% ls -lrt /usr/bin/sh
lrwxrwxrwx 1 root root 4 Mar 23  2022 /usr/bin/sh -> dash

and dash is retarded when it comes to parenthesis. You can look for it in the internet. If you find this kind of error,

Syntax error: word unexpected (expecting ")")

this is the reason. You forgot to escape the parenthesis with quotes.

Updating your bios

This will screw up grub big time. The way to recover it is to follow these steps. I have four partitions on my drive

aemonius# disklabel -E /dev/sd0c
Label editor (enter '?' for help at any prompt)
/dev/sd0c
OpenBSD area: 82225152-1000214528; size: 917989376; free: 0
# size offset fstype [fsize bsize cpg]
a: 917989376 82225152 RAID
c: 1000215216 0 unused
i: 192512 2048 MSDOS
j: 3905536 194560 ext2fs
k: 78125056 4100096 ext2fs

The first partition of about 200M is for efi business, the second one is the linux unencrypted, /boot, the third one is an ubuntu LUKS volume and the fourth one the whole OpenBSD system.

To recover the ubuntu grub installation, I followed these steps (stolen from here). I booted from a live usb drive and then did this:

    • If the directory /sys/firmware/efi/efivars is empty, you need to boot the rescue system including the kernel option “efi=runtime” and mount the EFI variables before proceeding:
      # mount -t efivarfs none /sys/firmware/efi/efivars

       

    • Mount the broken system somewhere into the running filesystem.

      For my system with an EFI partition on /dev/nvme0n1p1, an unencrypted /boot partition on /dev/nvme0n1p2, and a LUKS-encrypted / partition on /dev/nvme0n1p3, do:

      # cryptsetup luksOpen /dev/nvme0n1p3 crypt
      # mount /dev/mapper/crypt /mnt
      # mount /dev/nvme0n1p2 /mnt/boot
      # mount /dev/nvme0n1p1 /mnt/boot/efi
      
      Bind mount various virtual filesystems:
      # for i in /dev /dev/pts /proc /sys /sys/firmware/efi/efivars /run; do sudo mount -B $i /mnt$i; done
    • Chroot into the broken system:
      # chroot /mnt
    • Chroot into the broken system:
      # chroot /mnt
    • Reinstall GRUB to the appropriate disk (without partition number):
      # grub-install /dev/nvme0n1

<li”>Generate the GRUB configuration file:

# update-grub
  • Exit the chroot environment (<CTRL>-D).

  • If everything worked, reboot.