OpenBSD Encrypted Virtual Filesystem Mini-HOWTO


This Mini-HOWTO covers how to create and use local, encrypted virtual filesystems with OpenBSD (that is, encrypted virtual filesystems on physically attached, local disks as opposed to on remote machines over the network). Although nearly undocumented, OpenBSD makes the creation and use of encrypted virtual filesystems rather easy. Hopefully, this Mini-HOWTO will help document this feature a little better.

Caveat and Disclaimer

As always, if you destroy or otherwise lose your data, it is obviously your fault. Don't blame anyone else, especially me, for whatever undesirable circumstances may result from your actions. You have free will. Deal with it. :-)

The Implementation

Rather than implementing some ungainly means of grafting encryption on top of OpenBSD's existing filesystem semantics, encrypted virtual filesystem support is inserted into OpenBSD's existing vnode(9) system via vnd(4), OpenBSD's Vnode Disk Driver. The only encryption algorithm implemented so far is blowfish(3) and, while it would be nice to have a choice among a few good ciphers, this limitation is not really much of a shortcomming since blowfish is a relativey fast and secure algorithm.

Actual shortcomings are:

Creating and Using

There is only one prerequisite for using virtual encrypted filesystems under OpenBSD. Your kernel must have been compiled with at least one vnd pseudo-device defined. For example, the following line in your KERNEL configuration file would allow you to simultaneously use up to 4 vnd devices.

  pseudo-device vnd 4

The good news is that this exact line is included in the configuration file for GENERIC, the default OpenBSD kernel, so you may well be able to move forward here without having to stop and rebuild your kernel.

The tool used to configure these encrypted virtual filesystems is vnconfig(8). Other than reading the man page/s (of course), the only real trick is that you have to use the svnd ("safe" vnd) devices introduced in OpenBSD 2.1 rather than the regular vnd devices. The main difference between the two is that access via svnd devices goes through the buffercache while access via vnd devices bypasses it. And since cache-coherency is needed for disk[-like] access, the svnd variety must be used here.

When using a file as a disk, the file needs to be of static size. One way to create a file of a specific size is to use the dd(1) command to put as many empty bytes into it as required in order to reach the desired size. Using 1024 byte blocks for simplicity, here is an example.

  # dd if=/dev/zero of=/lame/secrets/cryptfile bs=1024 count=51200

This command will create an empty (or, more precisely, a sparse) 50 Meg file called cryptfile in the /lame/secrets directory. Since a mount point will be needed in order to use it like a disk, we should go ahead and make this as well, something like so ...

  # mkdir /lame/secrets/cryptmnt

Now, the vnconfig command is used to associate the file, cryptfile with an svnd device like so ...

  # /usr/sbin/vnconfig -ck -v /dev/svnd0c /lame/secrets/cryptfile

This command will prompt for a password to be given to this encrypted virtual filesystem. Enter something good.

Now, the disklabel(8) command can be used to partition this file up as desired (just as if it were a real disk) or, if it's full size will be used as a single filesystem (the usual case for such a file), you may as well not bother with disklabel since it's full size will be available as partition c by default anyway.

Now, the newfs(8) command must be used to make filesystems on any partitions that will be used since they will need filesystems on them (again, just like a real disk) in order to be used as virtual filesystems.

Once the foregoing is done, the partition/s of the cryptfile virtual disk can be mounted for use like any normal filesystem. The password will have to be provided, of course, upon each mount attempt in order to successfully make the mount. And upon unmounting, all that will be left for prying eyes is the encrypted file, cryptfile. :-)

Below, you will find a little shell script called mkcryptfs that will automate this initial file creation process. :-)

Now, for the sake of simplicity, let's assume we left all the space in file, cryptfile, in the one big partition, c, which can now be mounted like so ...

  # /sbin/mount /dev/svnd0c /lame/secrets/cryptmnt

That's all there is to it. Now you can just cd to /lame/secrets/cryptmnt and write whatever top secret manifestos you have in mind there. When done, simply unmount the file and unconfigure the previously configured cryptfile<-->svnd association for it as follows...

  # /sbin/umount /lame/secrets/cryptmnt
  # /usr/sbin/vnconfig -u -v /dev/svnd0c

Simplifying Repetition

Here is a little shell script called mkcryptfs to simplify the process of creating the encrypted virtual filesystem files to be used.

And here is a little shell script called cryptfs to simplify mounting and unmounting these encrypted virtual filesystems once they have been created. Although cryptfs can be used to mount/unmount arbitrary encrypted virtual filesystems on arbitrary mount points via arbitrary svnd devices, it allows a set of defaults which make mounting your most often used encrypted virtual filesystem as simple as ...

  # cryptfs -m
  Encryption key: secretstring

and unmounting it as simple as ...

  # cryptfs -u

Pretty simple, huh. Have fun. :-)

Unclean Shutdown Damage

Under OpenBSD's current encrypted virtual filesystem implementation, when a system with a mounted, encrypted virtual filesystem is shutdown uncleanly, the encrypted virtual filesystem's structures get damaged and, since OpenBSD's fsck(8) command will not currently acknowledge vnd filesystems, these damaged structures can not reasonably be repaired.

This is bad. In reality, however, it seems that this damage is very marginal (if real at all). Such a "damaged" filesystem can be mounted and used anyway by mounting it with the -f, force, option to the mount(8) command. Continuing to use such a "damaged" encrypted virtual filesystem in this way, I have seen no corruption so far. All the same, I am understandably uneasy about it so, rather than gambling like this, I would recommend keeping 2 copies of encrypted virtual filesystem files. It should be rather easy to modify the cryptfs script provided here to automatically handle this. If you do that, let me know. Otherwise, I'll get around to it myself sometime.

Adding HMACs

The fact that no HMAC is kept on these virtual encrypted filesystems is not that big a deal IMNSHO. If you are extremely paranoid about this though, it should be relatively easy to rewrite the cryptfs script provided here as in perl and add this feature via either the Digest::HMAC_SHA1 or Digest::HMAC_MD5 perl module, depending on your tastes, both of which are included in OpenBSD's p5-Digest-MD5 port/package. If you do that, let me know. Otherwise, I'll get around to it myself sometime. :-)

Good Luck,

-- Kyle Amon

BackWatcher, Inc.
Information Security Solutions