Yubikey integration with ecryptfs

Registered by Serge Hallyn

Yubikeys are small hardware tokens which can be used using static keys, OTPs, and challenge-response authentication. It would be good for end-users if they could use these to better protect their ecryptfs keys. This blueprint is for discussion of

   1. Which methods (OTP, static key, chal-resp) we would like to support for key protection.

   2. How to split up the functionality between ecryptfs-utils, pam, or other libraries

      (Keeping in mind that some users will want to use pam at login
       to decrypt their homedir, while others will want to use
       mount.ecryptfs_private to mount from the command line)

   3. Recommended best practices for storing keys.

      Do we recommend a passphrase-protected .sig file stored
      offline? Stored in the cloud for low-value data?

A relevant mailing list thread can be found at:

http://<email address hidden>/msg00086.html

Blueprint information

Not started
Steve Langasek
Needs approval
Dustin Kirkland 
Series goal:
Milestone target:

Related branches



The YubiKey has HMAC-SHA1 challenge-response support with HMAC key
customizable by the owner.

To protect the ecryptfs mount passphrase using the HMAC-SHA1 C/R, the
mount passphrase can be encrypted (wrapped) with the response (20 bytes)
to a challenge (up to 64 bytes) that is stored in plain text on the

However, since the same challenge always result in the same response
this is a bit vulnerable to replay attacks since someone that can read
the response to the challenge once would be able to unwrap passphrase.

To prevent this, the challenge could be made to change every time the
correct response is presented. This can be achieved by encrypting
(wrapping) not only the ecryptfs passphrase, but also the HMAC key on
the computer. Every time the correct response is given, the HMAC key
is available. A new challenge can then be randomized and a new response
calculated. The new response is then used to re-wrap the HMAC key and
ecryptfs mount passphrase. I've nicknamed this 'rolling challenges'.

Pseudo-code :

Initialization :

  K = have_user_enter_HMAC_key()
  C1 = get_random_challenge()
  R1 = HMAC-SHA-1(K, C1)
  WRAP1 = encrypt_data(K + passphrase, R1)

Unlock attempt :

  C1 = load_from_challenge_file()
  WRAP1 = load_from_wrapped_file()
  R1 = get_response_to_challenge(C1)
  if (K, passphrase = decrypt_data(WRAP1, CR)) {
    C2 = get_random_challenge()
    R2 = HMAC-SHA-1(K, C2)
    WRAP2 = encrypt_data(K + passphrase, R2)
  } else {
    print ("Bad response to challenge " + C1)

Architecture: what pieces go where? One possibility is that the rolling challenge support goes into libyubico, and gets used both in mount.ecryptfs_private. pam_ecryptfs exec()s this, so should not need the rolling response smarts itself, however it does need to detect (using the existence of a file under .ecryptfs/) that a rolling response will be used, so that even though the login passphrase did not provide the mount key, it will still proceed to exec mount.ecryptfs_private.

File format: How should the HMAC key and mount passphrase be encrypted? Simon Josefsson (security architect at Yubico) quite strongly recommends using GPGME with static passphrase instead of rolling our own file encryption. The contents of the file could be in almost any format to me, as long as it is easy to parse and extendable in the future.

Discussion with the security team has led to the conclusion that for this to be useful, it should block on trusted boot becoming better supported.

More useful will be the better support of remote authentication with yubikey. This will be tracked at https://blueprints.launchpad.net/ubuntu/+spec/security-o-2factor-auth.

So no actions for this item for this cycle.


Work Items