Yubikey 5 on Void linux
I recently (finally) got myself a yubikey which i plan to use with pass - and hence gpg.
In this article, we take a look into the basic setup required to make the yubikey work on void linux.
Install required packages
First, we need to install a couple of packets such as a pcsc daemon and the yubikey manager:
$ xbps-install -Su u2f-hidraw-policy gnupg2-scdaemon yubikey-manager pcsc-ccid pcsclite
Also make sure that your user is a member of the plugdev
group to use the key via gnupg2 (more on that later).
Basic setup
ykman and pcscd
ykman
requires pcscd
to be running. Since i won’t be fiddling with ykman
too often and don’t fancy
running yet another daemon permanently as root, i’m stating pcscd
just ‘on-demand’ by manually launching it:
# /etc/sv/pcscd/run
After that, you should be able to launch ykman
as your normal user:
$ ykman list
WARNING: No OTP HID backend available. OTP protocols will not function.
ERROR: Unable to list devices for connection
YubiKey 5C NFC (5.4.3) [CCID] Serial: 20111000
ykman configuration
First, we disable applets we don’t need for USB and NFC:
$ ykman config usb -d OTP
$ ykman config usb -d U2F
$ ykman config nfc -d OTP
$ ykman config nfc -d U2F
...
$ ykman config usb -l
OpenPGP
Then, we configure the key to auto eject itself on touch and after 30 seconds:
$ ykman config usb --touch-eject --autoeject-timeout 30
…and we finally reset the openpgp applet:
$ ykman openpgp reset
WARNING! This will delete all stored OpenPGP keys and data and restore factory settings. Proceed? [y/N]: y
Resetting OpenPGP data, don't remove the YubiKey...
Success! All data has been cleared and default PINs are set.
PIN: 123456
Reset code: NOT SET
Admin PIN: 12345678
(Don’t forget to touch your key due to auto-eject to ‘insert’ it before executing this (and following) commands).
Now, we can change the admin and access pin:
$ ykman openpgp access change-admin-pin
...
$ ykman openpgp access change-pin
...
GPG setup
We can now finally start using our new yubikey using GPG.
First, let’s see if gpg
can access it using the --card-status
command.
Note: By default, gpg does not use pcscd, so you must kill it before gpg can access your yubi key (and if pcscd fails, you might want to kill the gpg-agent…).
Anway, thats what you should be seeing: (Tap the key if gpg complains about failing to find a device if you setup auto-eject)
$ gpg --card-status
Reader ...........: 1050:0404:X:0
Application ID ...: D2760001240100000006206929530000
Application type .: OpenPGP
Version ..........: 3.4
Manufacturer .....: Yubico
Serial number ....: 20692953
Name of cardholder: [not set]
Language prefs ...: [not set]
Salutation .......:
URL of public key : [not set]
Login data .......: [not set]
Signature PIN ....: not forced
Key attributes ...: rsa2048 rsa2048 rsa2048
Max. PIN lengths .: 127 127 127
PIN retry counter : 3 0 3
Signature counter : 0
KDF setting ......: off
UIF setting ......: Sign=off Decrypt=off Auth=off
Signature key ....: [none]
Encryption key....: [none]
Authentication key: [none]
General key info..: [none]
Generate a new key
$ gpg --expert --full-generate-key
gpg (GnuPG) 2.3.8; Copyright (C) 2021 Free Software Foundation, Inc.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Please select what kind of key you want:
(1) RSA and RSA
(2) DSA and Elgamal
(3) DSA (sign only)
(4) RSA (sign only)
(7) DSA (set your own capabilities)
(8) RSA (set your own capabilities)
(9) ECC (sign and encrypt) *default*
(10) ECC (sign only)
(11) ECC (set your own capabilities)
(13) Existing key
(14) Existing key from card
Your selection? 9
Please select which elliptic curve you want:
(1) Curve 25519 *default*
(2) Curve 448
(3) NIST P-256
(4) NIST P-384
(5) NIST P-521
(6) Brainpool P-256
(7) Brainpool P-384
(8) Brainpool P-512
(9) secp256k1
Your selection? 1
Please specify how long the key should be valid.
0 = key does not expire
<n> = key expires in n days
<n>w = key expires in n weeks
<n>m = key expires in n months
<n>y = key expires in n years
Key is valid for? (0)
Key does not expire at all
Is this correct? (y/N) y
Now, that’s all fine and dandy, but openkeychain will not be able to decrypt messages with such a key as of January 2023 if a recent version of gnupg was used to create the key, so we edit the key to disable AEAD:
Set key prefs (optional if you don’t care about openkeychain)
$ gpg --edit-key $your_key_id
gpg> showpref
[ultimate] (1). Yubikey HSM <yubikey-hsm@blinkenlights.ch>
Cipher: AES256, AES192, AES, 3DES
AEAD: OCB
Digest: SHA512, SHA384, SHA256, SHA224, SHA1
Compression: ZLIB, BZIP2, ZIP, Uncompressed
Features: MDC, AEAD, Keyserver no-modify
# Note 'AEAD: OCB' - we will now *set* all prefs excluding that.
gpg> setpref AES256, AES192, AES, 3DES, SHA512, SHA384, SHA256, SHA224, SHA1, ZLIB, BZIP2, ZIP, Uncompressed
Set preference list to:
Cipher: AES256, AES192, AES, 3DES
AEAD:
Digest: SHA512, SHA384, SHA256, SHA224, SHA1
Compression: ZLIB, BZIP2, ZIP, Uncompressed
Features: MDC, Keyserver no-modify
Really update the preferences? (y/N) y
gpg> save
Exporting the key
In order to have a backup (in case the Yubikey breaks or is lost), we will take a backup of the key and store it in a very secret place.
$ gpg -a --export-secret-key this-key@example.com > privkey.asc
Move key to YubiKey
First, we move the signature and authentication key:
$ gpg --edit-key $your-key
gpg> keytocard
Really move the primary key? (y/N) y
Please select where to store the key:
(1) Signature key
(3) Authentication key
Your selection? 1
gpg> keytocard
Really move the primary key? (y/N) y
Please select where to store the key:
(1) Signature key
(3) Authentication key
Your selection? 3
gpg> save
After that, --card-status
should confirm that the signature and authentication key are moved - but not the secret key, so let’s do that now:
$ gpg --edit-key $your-key
gpg> key 1
gpg> keytocard
Please select where to store the key:
(2) Encryption key
Your selection? 2
gpg> save
# we are all done, so also publish the key to the keyserver:
$ gpg --keyserver keys.openpgp.org --send-keys $your-key
# Now wait for the e-mail to confirm the upload.
…and that’s it!
Recovery
Re-adding the stub
If you somehow lost your .gpg
directory (or want to use the same key on a different computer), you’ll have to re add a stub key to your installation.
First, import the public key using gpg --import
, like you’d do with any other key.
Then, run this strange command:
$ gpg-connect-agent "scd serialno" "learn --force" /bye
S SERIALNO D1230001250200000006000000000000
OK
S PROGRESS learncard k 0 0
S PROGRESS learncard k 0 0
S PROGRESS learncard k 0 0
OK
After that, gpg --list-secret-keys
should show the secret (stub) key.