Using CryptoStick as an HSM

gdestuynder

1

Mozilla maintains a wide range of services which are secured using different solutions.  For internal repositories, our Operations Security team has chosen to use the low-cost, open source and open hardware CryptoStick from the German Privacy Foundation.

Advantages of using an HSM
An HSM is a Hardware Security Module. It’s a hardware card, stick, device able to perform crypto operations. In general, it stores private keys which are used to sign, encrypt or authenticate.
The key itself never leaves the hardware, thus attackers cannot steal the key (i.e., if the hardware is disconnected, the key cannot be used anymore.)

Note: In the event the system is compromised, the connected key can still be used. Thus, the access to the system should be otherwise secured and the key should be removed when not in use.

Our use case
Internal package repositories, such as RPM or Deb. all use GnuPG for package signing.
Mozilla’s architecture is however broad and different teams use different platforms, at different places, in different networks.
We want to ensure that the packages they install are signed by us, and while we’re at it, have a good level of assurance that the key used for signing cannot be compromised or stolen.
We also need redundancy.

Many community-owned projects, such as Linux distributions have to deal with the exact same issue. Often, the signing machine has no HSM. This is one of the possible solutions.

About the CryptoStick
The choice was driven by:

  • The  openness of the project
  • The size and connectivity (USB)
  • No real smart card, yet easy to physically disconnect
  • The integration with GnuPG (OpenPGP Smart card, ISO 7816-4)
  • Low price and ease of getting additional sticks
  • Speed, support and certifications were not a requirement

The major point being, that the CryptoStick operates without any smart card, but emulates one instead.

Note: while we focus here on using OpenPGP for signing, the stick also supports other standards, such as x509 certificates and SSH authentication.

cstick2

Our setup
We use BL460c blade servers which have an internal USB port. Dimensions are perfect for the CryptoStick.

We have decided on having two repository machines for redundancy, signing with the same keys.
We also needed to be able to replace the hardware easily (both machines and the CryptoStick) in case of failure, which involves backing up the private key off-site. Finally, we needed the signing to happen automatically.

Some modifications were needed in order to make this work:

Custom PIN-entry program
As the OpenPGP smart card standard requires entering a user PIN upon signing, we needed this user PIN to be entered automatically. Consequently, we assume the user PIN adds no security in our setup.

A simple script is used as pinentry program: https://github.com/gdestuynder/pinentry-auto

Note: the non-enforcing user PIN option only allows for caching the user PIN upon successfully entering the user PIN a first time, which would defeat the purpose of automatic signing in case of system reboot, process restart, etc.

One private signing key, multiple sticks
The OpenPGP smart card standard also require the private keys generated on the HSM to contain the card’s serial number. While it allows for a software backup at creation time, the backup also contains the card’s serial number. The hardware will refuse to load those keys on a CryptoStick with a different serial number.

There is a different way to work around this issue. The stick also supports importing private keys. By using an offline machine, it is possible to generate the signing key in software using traditional GnuPG commands, and import it on the stick.
This allowed us to import the signing key on different sticks, and to keep an off-site backup.

This is also the most significant difference with traditional HSMs, which requires a set of smart cards to protect and import the key backup. In our use case, we decided that the trade-off was acceptable.

Note: when possible, it’s recommended to keep a master signing key offline, and create software signing GnuPG sub-keys. In the unlikely event of HSM compromise, it is then possible to revoke the sub-keys while retaining the trust of the master key, which then is simply used to issue new signing sub-keys. Not all package repositories support this feature.

Advanced usage, some commands
Here are some sample commands that are commonly used with the CryptoStick.

Note: it’s generally more convenient to have the gpg-agent running, for speed,and for PIN caching. General usage, such as encryption, signing and authentication work with the exact same commands as with a regular GnuPG or SSH key.

Get card info:
$ gpg –card-status


scdaemon[10692]: updating slot 0 status: 0x0000->0x0007 (0->1)
Application ID ...: D2760001240102000005000014731337
Version ..........: 2.0
Manufacturer .....: ZeitControl
Serial number ....: 00001478
Name of cardholder: Mozilla
Language prefs ...: en
Sex ..............: unspecified
URL of public key : [not set]
Login data .......: [not set]
Signature PIN ....: [not set]
Key attributes ...: 2048R 2048R 2048R
Max. PIN lengths .: 32 32 32
PIN retry counter : 3 0 3
Signature counter : 16
Signature key ....: 067A A494 9B64 347D FA2E EEEE 9B3C 64F9 8006 EEEE
created ....: 2013-01-17 22:40:53
Encryption key....: 3C00 DA66 554D 67FE 8607 1AAB AAAA C9F2 AAAA 1D67
created ....: 2013-01-17 22:40:53
Authentication key: 1AF9 988A 0EAB 6F10 D69C 2DFC EF3B CCCC 784E A733
created ....: 2013-01-17 22:40:53
General key info..: [none]

Set User and Admin PIN. Defaults are 123456 and 12345678 respectively:

$ gpg --card-edit
Command> admin
Admin commands are allowed
Command> passwd

Generate keys (you need to have setup the PINs above first):

$ gpg --card-edit
Command> admin
Admin commands are allowed
Command> generate

Import existing key (only recommended if the original keys were generated on a trusted machine, such as an offline machine that has never been connected to the network):
Note: this will erase the key from disk during the import. If necessary, make an extra backup of the key first.


$ gpg --edit-key
gpg> toggle
gpg> keytocard
(say yes)
gpg> save
gpg> quit

Reset to factory defaults:
Make sure GnuPG agent is started, if not:

$ eval $(gpg-agent --daemon)

Send the reset commands:

$ gpg-connect-agent < file

Where “file” contains:

hex
scd serialno
scd apdu 00 20 00 81 08 40 40 40 40 40 40 40 40
scd apdu 00 20 00 81 08 40 40 40 40 40 40 40 40
scd apdu 00 20 00 81 08 40 40 40 40 40 40 40 40
scd apdu 00 20 00 81 08 40 40 40 40 40 40 40 40
scd apdu 00 20 00 83 08 40 40 40 40 40 40 40 40
scd apdu 00 20 00 83 08 40 40 40 40 40 40 40 40
scd apdu 00 20 00 83 08 40 40 40 40 40 40 40 40
scd apdu 00 20 00 83 08 40 40 40 40 40 40 40 40
scd apdu 00 e6 00 00
scd apdu 00 44 00 00
/echo Reset complete

One response

  1. Michael Henry wrote on :

    Thanks for the information. I was curious how you were using it and this answers a lot of questions I had. :-)