js' blog

New PGP key - again, but this time on a Gnuk
Created: 13.02.2015 21:57 UTC

So, I changed my PGP key - again, I know. But there's a good reason for it: I now have my new key on a Gnuk. Well, to be more correct, on an FST-01 running Gnuk. The FST-01 is a small ARM board in the size of a USB stick that is based on an open hardware design. And Gnuk is a GPLv3 licensed implementation of the OpenPGP card specification for the FST-01.

After receiving my FST-01, I quickly realized how hard it is to actually generate a key in a secure environment from which I can then transfer it to the Gnuk. Since one of my requirements is to use Ed25519 for the signing key (as I want to sign all my Git commits and thus want small signatures), I had to update the FST-01 to Gnuk 1.1.4 first. And I had to update GnuPG to include a few fixes for GnuPG + Smartcards (while the Gnuk is not a smartcard, it behaves like one and speaks the OpenPGP card protocol). But how to do all that in a secure environment?

So I came up with a plan: I downloaded the latest ArchLinux install image, as it comes with at least GnuPG 2.1, which means I can at least generate an Ed25519 PGP key. I burned that on one machine, then verified the CD in another that was already running ArchLinux and thus had the ArchLinux key ring and then booted it on a third machine - just to make sure. It's important to note that I removed all hard drives and network connections from the machine I booted it on (and of course used one without (U)EFI or other things for sneaky backdoors - and just to be sure even disabled loading of the microcode updates in the boot loader).

Once I booted it, I generated a 4096 bit RSA certification key (the idea being that a.) everybody can at least import and sign my key and b.) every keyserver can handle it and thus can get the missing Ed25519 key on the next refresh as my key specifies a keyserver that can handle Ed25519), an Ed25519 subkey for signing, a 4096 bit RSA key for encryption (since Curve25519 support for encryption isn't there yet) and an Ed25519 key for authentication (useful for SSH!) and stored all keys on a USB thumb drive. After that, I removed the thumb drive and attached another thumb drive to which I only copied the public keys (so I can copy those to the machine with which I want to use the Gnuk). Then I shut down the machine and waited until enough time passed to make sure all contents of the RAM are gone.

Once enough time passed, I booted it again and this time gave internet connectivity to it. I then downloaded the necessary cross-compilers and Gnuk and applied some patches (and of course verified the hashes for all of them!). The ”applied some patches“ part is the result of several iterations of doing this, since I discovered 2 bugs which were quickly fixed. Once the firmware was built, I would flash it to the Gnuk, then plug in the Gnuk and set the signing and authentication key type to Ed25519.

Now I once again rebooted the machine with internet connectivity, downloaded the GnuPG sources, verified the tarball, applied the necessary patches (after verifying their hashes!) to it and rebuilt it. After that, I unplugged internet connectivity and plugged in the USB thumb drive with the private key and finally imported the signing key, encryption key and authentication key to the Gnuk with the patched GnuPG (note that the certification key is missing - this is because the OpenPGP card protocol has nothing for it and to further improve security as this is the only long-lived key; the subkeys can easily be replaced). Don't forget to change the Gnuk's PIN, though!

Since this is all quite a lot of manual work, especially as you need to mount tmpfs all over the place etc., I created scripts for the steps for which you need internet connectivity anyway: For building the Gnuk firmware and for building the patched GnuPG. These scripts will download everything that's required and verify all hashes, but obviously, you should check the scripts first and make sure the checksums in there are correct!

While the whole process right now feels like a lot of work, it really isn't that much work anymore with those two scripts. Things should only get better over time, as a new ArchLinux ISO will at some point contain a GnuPG with all the patches (GnuPG 2.1.2 has already been released and contains all the necessary patches) and the FST-01 will at some point most likely ship with a newer version of Gnuk.

In any case, when carefully doing everything in this order and exactly like written, there is no point where the private keys could leak into the internet (or some non-volatile storage other than the thumb drive holding the private key, because none is attached!).

Oh, and of course, here's my new fingerprint:

6CBB 47F8 A2BB F84D 9C54  1868 6795 57FE 2FF7 C07A

It will be used to sign all commits from now on.

By the way: The FST-01 can also be used as a true random number generator. The software for that is called NeuG.

Edit: I should note that you should not order the FST-01 with the shrink tube, as you cannot access the SWD port there! And I should also note that RSA 4096 takes 6 - 8 seconds on the FST-01. I consider this an advantage, though, as you then notice if something is signing / decrypting when it shouldn't, as the FST-01 has a blue LED that is lighting up when it signs / decrypts.

Edit 2: I noticed that basically all the entropy is coming from haveged on the ArchLinux install CD. I really don't trust haveged (a quick web search reveals a lot of reasons why you really shouldn't), so I decided to flash NeuG to my FST-01 and use that to add more entropy to the pool (after killing haveged and draining all the entropy it generated). Since rngd is not part of the install CD, this means I had to download it before I could generate the key. While this is a disadvantage security wise (because for that I was connected to the internet for a brief moment), I consider the risk low enough and the advantage of having a TRNG far outweights it.

In any case, the fingerprint of the new key generated with some randomness coming from NeuG is:

2D73 E456 EE94 12BC 9077  78DF 78D4 EEEF 482C B982