FSFE Fellower Card + LUKS on Startup

Peter Lebbing peter at digitalbrains.com
Thu Nov 12 12:06:08 CET 2009

> I think it is not a problem to decrypt the key file in the startup process, 
> isn't it!? Is it possible to access the card reader (omnikey 4040) and the 
> smartcard via gpg from the initrd ram disk? Has anyone ever tried it in a 
> similar way or are there any alternatives? Finally, is there a HowTo?

I hacked this together on Debian squeeze. It might need a little work to get
it working under another distribution. But I did not use LUKS; LUKS is based
on passwords and I use the asymmetric crypto of the OpenPGP card, so I
figured it made more sense to literally store the encryption key in a file
encrypted to the card. I use the cryptsetup package for this (which also
handles the LUKS drives, by the way).

The basic idea is to include the gpg binary and its libraries, especially
libusb-0.1.so.4. The libraries are handled automatically by initramfs-tools,
and most, if not all except for libusb, of the libraries are already in the
default initramfs.

The biggest problem is that gnupg opens /dev/tty and this is not available
in the initramfs. This might actually be a bug in initramfs-tools, I'm not
sure. To hack a fix, I changed gnupg to open /dev/console instead. This is a
hack that will only work in a very limited number of cases, so the binary I
create this way is special-purpose for the initramfs. See the diff[1] below.

I then use the debian build programs to build a .deb, and from that .deb
extract /usr/bin/gpg. I move that binary to
/usr/local/lib/cryptsetup/gpg-console (note that gpg-console is the name of
the binary, not a directory).

There are obviously different ways of compiling. I was just hacking
something together and the default Debian binary was fine except for the
/dev/tty thing, so I chose to build it the same way as the normal Debian
binary, without even looking at other ways like a simple "make".

The cryptsetup package uses entries in /etc/crypttab for the encrypted
partitions. I use something like the following entry:

root_crypt /dev/mapper/vg1-root /etc/gpgcryptroot/root.gpg

This should be one line. vg1-root is the LVM logical volume root in volume
group vg1.

Next are the scripts for including and using gnupg in the initramfs. They
are highly initramfs-tools specific. Secondly, they are a little big to
include in this mail, so I uploaded them to [2]. This also includes the diff
mentioned before.

The actual decryption is done by the script /etc/gpgcryptroot/decrypt_gpg.
It does a crude check to see if it is running in the initramfs. If it is
not, it takes a different approach more suitable for activating partitions
from a fully running system instead of the initramfs. I'll come back to that

The script expects a directory with at least the following files:
  A limited public-key ring, containing only the needed key that is on the
  The limited secret-key ring, again only the needed smartcard key.
  They key to unlock the root. The name is irrelevant (but needs to match
  the /etc/crypttab entry). It is just the literal key material cryptsetup
  expects; 16 bytes for AES-128 as above.

Optionally a gpg.conf could be placed there if it is necessary for gpg to
function correctly.

I placed these files at /etc/gpgcryptroot, together with the script. Please
mind the access permissions on the files and the directory; gpg expects them
to be "secure" and complains otherwise.

The decrypt_gpg script invokes the special-purpose gpg binary, and it asks
for the PIN of the smartcard. The contents of the decrypted key file are
passed to cryptsetup.

The final script glues together the other components with the initramfs. I
derived it from /usr/share/initramfs-tools/hooks/cryptopensc from the
cryptsetup package. It should be placed at
/etc/initramfs-tools/hooks/cryptgpg. The /etc/crypttab entry indicates where
the files pubring.gpg, secring.gpg, root.gpg and optionally gpg.conf are,
and the script copies them to the initramfs. It also copies the
/usr/local/lib/cryptsetup/gpg-console binaries and its libraries to the

A few final words on which partitions (mount points) can be encrypted with
this hacked-together scheme. The root is the obvious target and the only one
that is somewhat tested. /boot can not be encrypted. This is a fundamental
limitation; unless the BIOS or boot loader can do the decryption, you will
always need something unencrypted to start from. /usr, as a separate
partition, can also not be encrypted without further tweaks, because the
script works either in the initramfs, or in a system with /usr/bin and
possibly more already mounted.

For the system I use it on, everything is in one partition. It's not my
normal workstation but a protected environment to do my super secret
stuff in ;).

The part of the script that does acces to encrypted partitions in a fully
booted system expects gpg to be able to decrypt the file succesfully with
its default settings. In fact, as a horrible kludge, I use "su" to load the
environment normally encountered when root logs in, as environment for gpg
to run in. By default, cryptsetup gives a really limited environment to the
keyscripts, and this was the first I thought of that works.

With "gpg with its default settings", I mean home directory, keyrings, etcetera.

I hope this all is somewhat clear. It is definitely not a step-by-step
HOWTO, requires some Linux skills and is completely not peer reviewed ;).

Good luck,


--- gnupg-1.4.9/util/ttyio.c    2007-10-23 09:55:31.000000000 +0200
+++ gnupg-1.4.9-new/util/ttyio.c        2009-10-05 17:54:25.000000000 +0200
@@ -106,7 +106,7 @@
   /* Assume the standard tty on memory error or when there is no
      ctermid. */
-  return name? name : "/dev/tty";
+  return "/dev/console";


More information about the Gnupg-users mailing list