Short version of this question is: How do I convert a user key on the kernel keyring storing ecryptfs authentication token / FEFEK to an encrypted key on keyring? (I.e. how to add an encrypted key with user-specified plaintext data, instead of a randomly-generated key - such as a pre-existing mounting passphrase for an existing ecryptfs file system.) Read on for why...
I'm trying to figure out how to practically use ecryptfs with a TPM, and the information I'm finding is generally out-of-date/obsolete. All I've found is blog articles or IBM whitepapers from a few years ago that appear to use features that don't exist anymore / unmaintained features (the removed TSPI module, and the OpenSSL TPM library that seems unmaintained and is no longer in my package manager). I've gathered that the proper way to do this now involves trusted and encrypted kernel keys, as per:
The strategy outlined in the above documentation indicates the idea would be to make a new trusted key, sealed with the TPM, and then use it to make a new encrypted key in the ecryptfs format, specifying the trusted key as the master. That's easy enough to follow, and does what I'm looking for, except...
The problem is if the TPM dies, I need to recover my data (e.g. computer dies, and need to restore from encrypted backups). What I'm wanting to do is use a passphrase to decrypt data if the TPM is not available, to be used only in special circumstances. Alternatively, users might have a pre-existing ecryptfs file system with a mounting passphrase / FEFEK already chosen - i.e. you don't want to re-encrypt all your files just to use the TPM. This seems like an obvious need, yet I'm have trouble figuring out the "how".
From the above documentation:
The data structure defined by eCryptfs to contain information required for the FEK decryption is called authentication token and, currently, can be stored in a kernel key of the 'user' type, inserted in the user's session specific keyring by the userspace utility 'mount.ecryptfs' shipped with the package 'ecryptfs-utils'. Encrypted keys of the newly introduced [ecryptfs encrypted] format store an authentication token in its payload with a FEFEK randomly generated by the kernel and protected by the parent master key. [What if I want to use an existing FEFEK?]
OK, so it sounds to me like the kernel is storing the encrypted key in the same
format as a regular user key that would be added to the keyring by the ecryptfs
userspace tools (e.g. by
ecryptfs-add-passphrase or the mount helper). That is,
the payload of the user key and the encrypted key are basically one and the
same, except the kernel won't allow userspace to read the encrypted key in
unencrypted format. Right?
So I think what I want to do is this - am I on the right track here?
ecryptfs-add-passphraseto add a mounting passphrase to the keyring. (It could be a mounting passphrase for an existing ecryptfs filesystem). Now I have a user key on the keyring storing an ecryptfs authentication token. The mounting passphrase can be complex and stored in an offline secure location, perhaps protected by
ecryptfs-wrap-passphrase, and only used in a data recovery scenario (e.g. if the TPM goes up in smoke).
- Create a new trusted key in the keyring, as per above kernel documentation.
- Convert the existing user key storing authentication token from
ecrypt-add-passphrasein step #1 into an encrypted key on the keyring, using the trusted key as the master key. (This is where I'm stuck.)
- Remove the user key from the keyring since we don't need it any more.
keyctl pipeto save the encrypted key to a file on disk for later mounting.
Ordinary day-to-day mounting would work like:
- Load and unseal trusted key into keyring.
- Load encrypted key blob from step #5 above into encrypted key in keyring, using trusted key as master key.
- Mount using the encrypted key from previous step.
If the TPM is destroyed or lost:
ecryptfs-add-passphraseto add the mounting passphrase from backup into an authentication token stored in a user key.
- Mount using this user key.
So my key question is this: How do I convert a user key storing authentication token to an encrypted key, as in step #3 in the setup procedure above? For example, kernel docs say this to decrypt an existing encrypted key previously exported with keyctl pipe :
keyctl add encrypted name "load hex_blob" ring
But I want to do something like this to make a new encrypted key from some pre-existing plaintext:
keyctl add encrypted name "load ecryptfs trusted:masterkey `keyctl print <id of user key holding plaintext authentication token / FEFEK / mounting passphrase>`" @u
(This as opposed to the random new key generated with
add encrypted name "new ecryptfs")
If the above isn't possible then what am I missing in my strategy? Feels like I'm missing some obvious information here.