Editor’s Note: This is a guest blog post by Anthony J. Martinez republished with his permission. You can view the original blog post here.
With the arrival of my second Librem Key, I thought now would be a good time to go over how I use Qubes OS features along with some more products from Purism for various signing, encryption, and authentication tasks.
Here are the various components at play:
The base of all but one of my qubes is Fedora.
The new Librem Key needs to have its PIN set, and since my Qubes OS configuration uses a USB qube it will be necessary to give my running disposable VM access to the key itself:
dom0, where my target vm is
disp4632 and my
$ qvm-usb attach disp4632 sys-usb:2-1
In the disposable VM run:
[user@disp4632 ~]$ gpg --card-status Reader ...........: Purism, SPC Librem Key (000000000000000000009BB1) 00 00 Application ID ...: D276000124010303000500009BB10000 Application type .: OpenPGP Version ..........: 3.3 Manufacturer .....: ZeitControl Serial number ....: 00009BB1 Name of cardholder: [not set] Language prefs ...: de Salutation .......: URL of public key : [not set] Login data .......: [not set] Signature PIN ....: forced Key attributes ...: rsa2048 rsa2048 rsa2048 Max. PIN lengths .: 64 64 64 PIN retry counter : 3 0 3 Signature counter : 0 KDF setting ......: off Signature key ....: [none] Encryption key....: [none] Authentication key: [none] General key info..: [none]
gpg --card-editin the disposable VM
1and follow the prompts, where the first PIN is the default:
3and follow the prompts, where the first Admin PIN is the default:
qvm-usb detach disp4632 sys-usb:2-1
# Assuming you plugged the original key into the same port qvm-usb attach disp4632 sys-usb:2-1
dom0 find the appropriate block device, and attach it to the disposable VM:
qvm-block list ... qvm-block attach disp4632 sys-usb:sdb1
In the disposable VM find the attached disk (likely
[user@disp4632 ~]$ lsblk NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT --- SNIP --- xvdi 202:128 1 28.9G 0 disk
Then mount the disk:
[user@disp4632 ~]$ udisksctl mount -b /dev/xvdi Mounted /dev/xvdi at /mnt/removable
Note that I did not
sudo mount /dev/xvdi /mnt/removable as the operation does not require root, and we do not use powers we do not need do we?!
[user@disp4632 ~]$ cp /mnt/removable/gpg-backup/backup* .
[user@disp4632 ~]$ udisksctl unmount -b /dev/xvdi Unmounted /dev/xvdi.
qvm-block detach disp4632 sys-usb:sdb1
This assumes you have installed
opensc and have
First, find the Key ID for encryption key on your existing Librem Key:
[user@disp4632 ~]$ pkcs15-tool -D Using reader with a card: Purism, SPC Librem Key (000000000000000000009BB4) 00 00 PKCS#15 Card [OpenPGP card]: Version : 0 Serial number : 000500009bb4 Manufacturer ID: ZeitControl Language : de Flags : PRN generation, EID compliant // SNIP Private RSA Key [Encryption key] Object Flags : [0x03], private, modifiable Usage : [0x22], decrypt, unwrap Access Flags : [0x1D], sensitive, alwaysSensitive, neverExtract, local Algo_refs : 0 ModLength : 4096 Key ref : 1 (0x01) Native : yes Auth ID : 02 ID : 02 <-- THIS ID MD:guid : ee23dccc-fc38-2dc2-3bc8-bb5f859168d4 // SNIP
Now use it to decrypt the
pbkdf2 key used to encrypt the GPG backup tarball itself. This hybrid encryption scheme allows securely storing data of arbitrary sizes and using
pbkdf2 with randomly generated secrets and then encrypting those secrets with the Librem Key’s encryption key.
pbkdf2 password file with the Librem Key:
[user@disp4632 ~]$ openssl rsautl -engine pkcs11 -keyform e -decrypt -inkey 02 -in backup.key.enc -out backup.key engine "pkcs11" set. Enter PKCS#11 token PIN for OpenPGP card (User PIN):
Decrypting the GPG backup with the
pbkdf2 password file:
[user@disp4632 ~]$ openssl enc -chacha20 -pbkdf2 -pass file:backup.key -d -in backup.tar.gz.enc -out backup.tar.gz
tar xf backup.tar.gz
[user@disp4632 ~]$ gpg -k /home/user/.gnupg/pubring.kbx ----------------------------- pub rsa4096 2021-05-08 [C] FCBF31FDB34C8555027AD1AF0AD2E8529F5D85E1 uid [ultimate] Anthony J. Martinez <@ajmartinez:txrx.staart.one> sub rsa4096 2021-05-08 [S] sub rsa4096 2021-05-08 [E] sub rsa4096 2021-05-08 [A]
qvm-usb detach disp4632 sys-usb:2-1
qvm-usb attach disp4632 sys-usb:2-1
Edit the key in expert mode:
[user@disp4632 ~]$ gpg --expert --edit-key FCBF31FDB34C8555027AD1AF0AD2E8529F5D85E1
gpg> prompt select each subkey and use the
Example, using the signing key (key 1):
gpg> key 1 sec rsa4096/0AD2E8529F5D85E1 created: 2021-05-08 expires: never usage: C trust: ultimate validity: ultimate ssb* rsa4096/A2206FDD769DBCFC <-- NOTICE THE * HERE - this key is selected created: 2021-05-08 expires: never usage: S ssb rsa4096/6BE6910237B3B233 created: 2021-05-08 expires: never usage: E ssb rsa4096/FD94BDD7BED5E262 created: 2021-05-08 expires: never usage: A [ultimate] (1). Anthony J. Martinez <firstname.lastname@example.org> [ultimate] (2) Anthony J. Martinez <@ajmartinez:txrx.staart.one> gpg> keytocard gpg> key 1 <-- this is to deselect key 1
Repeat the above for key 2 and 3.
[user@disp4632 ~]$ gpg --card-edit Reader ...........: Purism, SPC Librem Key (000000000000000000009BB1) 00 00 Application ID ...: D276000124010303000500009BB10000 Application type .: OpenPGP Version ..........: 3.3 Manufacturer .....: ZeitControl Serial number ....: 00009BB1 Name of cardholder: [not set] Language prefs ...: de Salutation .......: URL of public key : [not set] Login data .......: [not set] Signature PIN ....: forced Key attributes ...: rsa4096 rsa4096 rsa4096 Max. PIN lengths .: 64 64 64 PIN retry counter : 3 0 3 Signature counter : 0 KDF setting ......: off Signature key ....: C9ED 41D4 EB62 80BB E61F 0E59 A220 6FDD 769D BCFC created ....: 2021-05-08 11:43:52 Encryption key....: 335D C8BC E4A6 8FFF B9B5 CBEF 6BE6 9102 37B3 B233 created ....: 2021-05-08 11:44:54 Authentication key: D157 68B9 CCCF 4FB5 6FC2 971E FD94 BDD7 BED5 E262 created ....: 2021-05-08 11:45:39
From here the new Librem Key is configured, and the disposable VM is of no further use. Since disposable VMs are destroyed when the application they were created to run is stopped, the only cleanup necessary is to close the terminal to the disposable VM.
On my system, I also have
personal-gpg qubes. These are both network-isolated and function much the same way the physical key does. The
personal-gpg qube holds the very same subkeys as both Librem Keys, and through the use of Split GPG allows for a smartcard-like use of the qube from my other qubes. In a later post, I will detail how I use QubesRPC in
personal-gpg to also serve as my
ssh-agent for using the authentication subkey in things like my
admin qube to prevent me from needing dozens of copies of my SSH private keys everywhere. The
vault qube is home to the master secret key, and as such never has any data fed in to it.
The process used to decrypt data can be reversed to encrypt data as well. I will leave that as an exercise for the reader, but the short version is that instead of the decrypt option(s) for the
openssl tools use their encrypt counterparts. If you wish to generate a random secret to use with
pbkdf2 the following should do the trick:
openssl rand -base64 -out secret.key 32