Yubico Forum

[HOWTO] YubiX with YubiHSM for Yubikey AES storage (KSM)
Page 1 of 1

Author:  Tom [ Wed Jan 15, 2014 12:48 pm ]
Post subject:  [HOWTO] YubiX with YubiHSM for Yubikey AES storage (KSM)


I am writing this HOWTO as a quick guide to hopefully help others, as I initially struggled to get YubiX running with YubiHSM due to a lack of understanding. YubiHSM can is quite interesting and flexible and can be used for many things, however I am predominately interested in using it to securely store Yubikey AES keys and this guide is about that, not about using it to store/secure/encrypt/decrypt wonderful arbitrary things.

I installed the YubiX Virtual Appliance 0.6. Initially it is setup to use the YubiCloud Key Storage Module (KSM) so that the default programming on the purchased Yubikeys will work with the cloud service. I wanted a local KSM, so followed the guides to create a KSM GPG key, to generate YubiKey AES keys that are encrypted and signed, and to import the YubiKey keys into the local KSM. I had some initial issues because I had mis-copied-and-pasted the API key[1], but once this was resolved everything worked well.

Setting up the YubiHSM was confusing for me at first. I read through the detailed YubiHSM-Manual-v1.0.4.pdf guide but was lost with how to actually create the YubiKey keys, and have YubiAuth work etc. Initially I was trying to create the keys using a terminal emulator connected to the serial interface of the YubiHSM. Turns out it is actually pretty easy once you know how...

First, I installed some additional packages:
  • minicom - friendly menu driven serial communication program
  • yhsm-yubikey-ksm - Yubikey Key Storage Module using YubiHSM
YubiX is Ubuntu/Debian based, so we use APT (i.e. apt-get install <pkg>).

yhsm-yubikey-ksm has a nice ASCII diagram to help demonstrate how this works, I am stealing it for this HOWTO:

     O            +----------+
    /|\           |Validation|     +-----+   +---------+
     |  -- OTP--> |  server  | --> | KSM +---| YubiHSM |
    / \           +----------+     +-----+   +---------+
    user             +--+--+
                     | DB  |

The idea is that the user will supply an OTP to the validation server, which will consult the DB and the KSM. The KSM will use the YubiHSM to verify the OTP. If the servers are compromised the secret keys cannot be extracted. Removing the YubiHSM will stop all the authentications. This setup is more secure than storing the secrets on the server, where they could be stolen during a compromise.

Initially the YubiHSM will not be configured. By default it will start in configuration mode when there is no configuration. Once it is configured, configuration mode can be entered by holding down the configuration button with a pin whilst inserting it into the USB port.

The guide on the YubiAuth wiki for YubiHSMs has the YubiHSM configured to generate AEADs but if I understand correctly with the flags set in the guide on the wiki it will not be able to verify OTPs. A strong security setup would have one YubiHSM used for key generation (personalisation), the wrapped keys (AEAD) would be distributed, and "verifier" YubiHSMs would be configured with the same AEAD keys but different flags so that they can be used for verifying OTPs for example but not for creating them. Refer to section 5.1 of the YubiHSM Manual (v1.0.4). However in this proof of concept I only want to use one YubiHSM. So during the configuration we need to set additional flags. I got lazy and set them all, but only the bare minimum should be set (TODO FIXME).

At first I didn't understand how to properly unlock the YubiHSM after setting a Master Key and Admin YubiKey. I was entering configuration mode again to unlock it via minicom. Later I discovered there is the yhsm-keystore-unlock command for this purpose.

For simplicity, which is the great for security, as well as portability YubiHSM interfaces with the computer as a simple USB serial device. To enable multiple programs to interact with this serial device Yubico provides yhsm-daemon which listens on a TCP port and multiplexes connections to the serial device. Other commands, like yhsm-keystore-unlock, can be instructed to use the TCP port rather than using the serial device with the yhsm://<host>:<port> URL - generally this will be yhsm://, I doubt it is a good idea to have it listen on anything other than the loopback. You basically want to use yhsm-daemon, and then have everything else use that yhsm URL rather than connecting directly (the default).

When you set an Admin Yubikey during configuration, you need to store the Yubikey AES key so that the YubiHSM can verify the OTP. This is done with the dbload command. You can list it with the dblist command, and you can verify it is working with the otpver command. It is recommended to set one. This means when the YubiHSM is first inserted it will be locked. It needs to be unlocked before it can be used. It can be unlocked from Configuration mode, but in general you would use the yhsm-keystore-unlock command I mentioned above. It can be locked again by using the wrong OTP value. You can also set a Master Key which is used to encrypt the non-volatile storage. It will need to be decrypted/unlocked first, before it can be used - this is done with the same command. It is recommended to set a Master Key as well.

As I said above initially I was trying to create the Yubikey AES keys directly on the YubiHSM via minicom. I was struggling to understand many things such as why the AEAD keys are created as 30 bytes - the reason is 16 (AES key) + 6 (private ID) + 8 (MAC). The AEAD keys have an index/handle that is used to refer to them by.

You need to generate at least one AEAD key. This will be used by yhsm-yubikey-hsm and other related commands for the on-server-storage of wrapped Yubikey keys, which will refer to the AEAD key by its handle. You need to take note of what the AEAD AES key was, so that you can decrypt the AEAD blobs sitting on the server and get the Yubikey AES keys so that you can personalise the Yubikeys. The format option is nice as it shows you which part is the 128-bit AES key and which part is the private ID. There is no way to see what the AEAD key was unless the debug flag was set during configuration (not recommended), so make sure you take not of it, and store it securely, otherwise you will need to create a new AEAD key to create new Yubikey keys.

With YubiAuth set to use YubiHSM, it will store the user account's passwords in the YubiHSM. I tested this - with a user account with only a password set and no Yubikey assigned, with the YubiHSM connected the user can authenticate, when the YubiHSM is disconnected the user can no longer authenticate.

Since YubiAuth has the configuration option to use a YubiHSM I thought that the local Yubi KSM was meant to be left and it would just magically start to use the YubiHSM. However I think that this option is just for the storage of the passwords and that the Yubi KSM will use a SQL database, so what we need to do is start the YubiHSM KSM, yhsm-yubikey-ksm, and configure YubiAuth to use the URL for the yhsm-yubikey-ksm. The local KSM is no longer used/needed. Existing local OTP keys could be exported and imported into the YubiHSM, but I think it is more-secure to generate them with the YubiHSM.

Generating the Yubikey keys with YubiHSM there is no lockcode generated, the lockcode is always 000000000000, whereas in the personalisation GUI it will generate them - I don't know what this lockcode is used for, does anyone know? I hazard a guess it is to stop users from re-configuring their keys, so that only an admin with knowledge of the lockcode can. However where to store such secrets? They need to be retrieved so I guess the YubiHSM is not the best fit - use something else like GPG or a password manager...

In summary:
  1. install the yhsm-yubikey-ksm package
  2. Configure the YubiHSM
    1. Set the necessary (and minimum) flags
    2. Set a Master Key
    3. Set at least one Admin Yubikey
    4. Load the Admin Yubikey key(s)
    5. Generate at least one AEAD
  3. Configure yhsm-yubikey-ksm to use yhsm-daemon (yhsm URL)
  4. Configure yhsm-yubikey-ksm to start at necessary run-levels
  5. Configure YubiAuth to use the yhsm-yubikey-ksm ($otp) rather than the YubiCloud KSM or the local Yubi KSM
  6. Create the Yubikey AES keys with the yhsm-generate-keys command
  7. Extract the Yubikey AES keys with the yhsm-decrypt-aead command
  8. Personalise the Yubikeys to use the Yubikey AES keys generated and extracted above
  9. Add users to YubiAuth
  10. Assign Yubikeys to the users
  11. On boot-up, manually unlock the YubiHSM with the yhsm-keystore-unlock command

[1] I had left the base64 "=" padding off the end, and this resulted in Python errors that bubbled up as HTTP 500 Internal Server Errors in the RADIUS failed reply. I have another thread on it if you want more details.

Page 1 of 1 All times are UTC + 1 hour
Powered by phpBB® Forum Software © phpBB Group