Block encryption in OpenBSD
written on Sun 05 July 2015
OpenBSD's block encryption is slightly different than on Linux or FreeBSD.
LUKS, FreeBSD uses
gbde. On OpenBSD 5.7
the user can utilise
softraid0 driver to acquire the same thing. Please note
that you could also use
vnconfig's internal encryption (Blowfish), but on
vnconfig's manpage the maintainer says this method is deprecated. So, I won't
even consider it here.
The plan is the same as in other systems:
First we need to create a container file, ideally basing its initial content on
Second, we need to create a loop device, so the file will become a device.
softraid0's driver --
bioctlaccepts only devices as arguments.
Third, after creating the virtual device, we need to insert an encryption layer on it (
Last, we can later create the filesystem and mount it to some directory.
So, let's go!
Creating a container file
This is pretty straightforward. We can use
dd to copy the contents of
/dev/urandom to a file:
$ dd if=/dev/urandom of=encrypted_storage.bin bs=1M count=10
This command-line will create a file with 10 megabytes of random bytes in it.
Creating a loop device
OpenBSD contains a command named
vnconfig for creation of loop devices. The
name comes from "virtual node configuration", where "virtual node" is a
terminology used for loop devices.
The kernel installed by default supports adding 4 vn's. Since OpenBSD removed the ability to dynamically load kernel modules, I guess we're stuck with that.
Here's how you can create a loop device:
$ sudo vnconfig vnd0 encrypted_storage.bin $ sudo vnconfig -l vnd0: covering encrypted_storage.bin on sd0a, inode 2808930 vnd1: not in use vnd2: not in use vnd3: not in use
vnd0 is the name of the first virtual node that is available.
vnconfig -l showed us the status of virtual node allocation. It's easy to see
vnd0 is allocated, rest of vn's are unallocated. But, there is a slight
Unlike on Linux, you don't refer to these nodes by
/dev/vnd0 or anything like
that. In fact,
/dev/vnd0 doesn't even exist. But we'll see that in a minute.
Creating an encryption layer
First we need to prepare our device for
softraid0 by creating BSD partitions.
BSD partitions live inside normal MBR partitions, so we need to create an MBR partition first!
Creation of normal MBR partition is done by the
fdisk command. The name of the
device will be our
vnd0 device, but we can refer to it only by the
/dev/rvnd0c device. Now let's see:
/dev/rvnd0cis a character device for
vnd0. "c" at the end of the device name means that we want to refer to the whole disk, not a partition of any kind.
/dev/vnd0cis a block device for
vnd0. "c" at the end means the same thing as in
fdisk only accepts character devices, so we need to refer to our virtual node
device by using
$ sudo fdisk -i /dev/rvnd0c Do you wish to write new MBR and partition table? [n] y Warning CHS values out of bounds only saving LBA values Writing MBR at offset 0.
-i argument will create a new MBR partition table with one partition
covering the whole disk. This is perfect for creation of another layer of BSD
We can verify the allocation by using
$ sudo fdisk /dev/rvnd0c Disk: /dev/rvnd0c geometry: 204/1/100 [20480 Sectors] Offset: 0 Signature: 0xAA55 Starting Ending LBA Info: #: id C H S - C H S [ start: size ] ------------------------------------------------------------------------------- 0: 00 0 0 0 - 0 0 0 [ 0: 0 ] unused 1: 00 0 0 0 - 0 0 0 [ 0: 0 ] unused 2: 00 0 0 0 - 0 0 0 [ 0: 0 ] unused *3: A6 1 0 29 - 203 0 100 [ 128: 20272 ] OpenBSD
Now we can start creating BSD partitions. We will need 1 partition, unless your needs are different.
Creation of 1 partition can be done with
disklabel. During installation of
OpenBSD you've already used
disklabel, so you'll probably know how to use it.
disklabel seems to accept both block and character devices, so it probably
doesn't matter if you pass
$ sudo disklabel -E /dev/rvnd0c Label editor (enter '?' for help at any prompt)
First we can make sure our BSD partition layout is empty by using the
> p OpenBSD area: 0-20480; size: 20480; free: 20480 # size offset fstype [fsize bsize cpg] c: 20480 0 unused
Remember, the 'c' partition is a reference to the whole disk. This output doesn't mean that there is a 'c' partition.
If it's empty, let's use
a command to add a parition:
> a partition: [a] offset:  size:  FS type: [4.2BSD] RAID
Notice I've used a different
FS type here. I've used
RAID filesystem type,
because this partition will be used by
probably fail to install itself in
4.2BSD partition (I haven't checked that
Let's verify that everything went well by printing the partition table once again:
> p OpenBSD area: 0-20480; size: 20480; free: 0 # size offset fstype [fsize bsize cpg] a: 20480 0 RAID c: 20480 0 unused
Everything seems OK, we can save & quit the partition table by using the
> q Write new label?: [y] y
Now our container is prepared for
Creation of softraid0
We can finally create the encryption layer. Since we have every preprequisite already covered, this is very easy.
We will use
bioctl command to interface with
$ sudo bioctl -c C -l /dev/vnd0a softraid0
-c C will tell
bioctl that we would like to use
CRYPTO RAID discipline.
This basically means that we won't actually use RAID functionality, we just want
an encryption layer.
-l /dev/vnd0a specifies the target device we would like to use. We're giving
the block device here, because
bioctl wants a block device, and we specify the
'a' partition here as well, because we've created it in the
disklabel step few
softraid0 is the name of the driver to use, and it needs to stay just like
The driver tool will ask us for the passphrase. It won't be echoed, just specify it and we're done here.
$ sudo bioctl -c C -l /dev/vnd0a softraid0 Passphrase: softraid0: CRYPTO volume attached as sd1
Make sure to write it properly, because
bioctl will not ask twice.
The algorithm used is AES XTS 256, which is a standard one. You don't really
have to modify it, because it's considered to be secure. You can modify the
number of encryption key generation rounds with the
-r option. Please check
for more information on this.
We can see that we have a new device now,
sd1. It's already encrypted and
we can finally create a filesystem on it.
We could partition it with
disklabel, but it seems that this isn't
necessary. We can just refer to this device with the 'c' suffix, which refers to
the whole disk.
rsd1c device means that we want to access the character device
sd1c means that we would like to refer to the whole space of
without considering any partitions.
newfs doesn't accept block devices, so we
sd1c here, we have to use
$ sudo newfs /dev/rsd1c newfs: reduced number of fragments per cylinder group from 1240 to 1232 to enlarge last cylinder group /dev/rsd1c: 9.7MB in 19952 sectors of 512 bytes 5 cylinder groups of 2.41MB, 154 blocks, 384 inodes each super-block backups (for fsck -b #) at: 32, 4960, 9888, 14816, 19744,
We can mount the filesystem now:
$ sudo mount /dev/sd1c /tmp/disk
Done! We have a new encrypted directory with 10 megabytes of free space in it.
$ df -h Filesystem Size Used Avail Capacity Mounted on /dev/sd0a 27.6G 2.7G 23.5G 10% / /dev/sd1c 9.3M 2.0K 8.9M 0% /tmp/disk
Achievement unlocked: creation of your first encrypted storage on OpenBSD ;).