GNUK: Open Source GPG/SSH hardware key storage

I noticed the GNUK project had support for the STM32 Blue Pill. I've been looking for an open source hardware key storage for GPG/SSH keys, so I tried it out.

Blue Pill

GNUK supports the OpenPGP smartcard protocol, and has space for 3 keys. The keys are named: "Signature key", "Encryption key", and "Authentication key". There's a few places that sell the hardware+software as a keyfob solution: FST-01, and Nitrokey Start.


These are the flags I used to configure. Note that the vid+pid I used are available only for private testing.

./configure --vidpid=234b:0000 --enable-factory-reset --target=BLUE_PILL
make -j4

To flash the new binary to the Blue Pill, I used ST's ST-Link utility and ST-LINK/V2-1 hardware. I already had an arm-none-eabi-gcc toolchain installed.


I followed these instructions to setup my new key: gpg configuration, key generation, key import, and set card PIN.

Using it under Linux

After that was done, my gpg-agent had a SSH agent socket, but my environment wasn't pointed at it.

export SSH_AUTH_SOCK=/run/user/$UID/gnupg/S.gpg-agent.ssh

After I changed the SSH_AUTH_SOCK environment variable, I could see the key:

$ ssh-add -L
ssh-rsa AAAAB3Nxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx ssh-rsa cardno:Fxxxxxx

Then all I needed to do was put that line into my .ssh/authorized_keys file.

$ ssh -v testserver.lan
debug1: Next authentication method: publickey
debug1: Offering RSA public key: cardno:Fxxxxxx
debug1: Server accepts key: pkalg ssh-rsa blen 279
debug1: Authentication succeeded (publickey).

Using it under Windows

Moving the USB device to my Windows machine, I followed these directions: GPG4WIN and Pageant. I also wanted to use cygwin ssh, so I also installed ssh-pageant from cygwin's packages.

After running gpg-connect-agent /bye (from GPG4WIN) and ssh-pageant, I had the key available in cygwin:

$ ssh-add -l
2048 SHA256:8xxxxxxxx cardno:Fxxxxxx (RSA)

I had to import the public keys into GPG4WIN, and then run gpg2 --card-status to get it to associate the private keys on the stm32 with the public keys in gpg. Once I did that, the Kleopatra windows app let me sign and encrypt files.


  • Pro: the keys are much safer than on disk. They are stored AES encrypted on the flash of the stm32, with the PIN used to generate the AES key. In order to read the flash of the stm32, you'd need physical access to the chip. Disabling flash readout via SWD would make a physical attack even harder.
  • Pro: PIN brute force locks out the smartcard interface after 3 failures. A separate password can be setup to reset the lockout.
  • Con: each RSA operation takes about 1.5 seconds to complete (not that big of a deal)