# Encrypt HDD with keyfile and password and allow backing up the keyfile with secret sharing

### I want to:

1. Encrypt my whole HDD with a keyfile and a password (meaning that both are required to decrypt it),
2. Be able to back up pieces of the keyfile in several distant locations using Secret Sharing,
3. Be able to change the password often and easily.

### Notes:

• The keyfile is made of 4096 random bits and is done using dd if=/dev/urandom /keys/keyfile bs=1024 count=4,
• The password is approximately 20 characters long,

To make things clear, I'll state the intended meaning of a few words:

• keyfile – the randomly generated file
• password – the text asked to the user and never stored in a file
• key – the data used to decrypt the masterkey
• masterkey – the data used to encrypt / decrypt the drive

### Thoughts:

• To allow “3.”, I use cryptsetup since it uses a masterkey that's encrypted with your key so I can change my key without having to rencrypt everything. I could use dm-crypt directly but it'd be much harder and would only save the space occupied by the luks headers. And I already have enough space so I don't think it's worth the trouble.

• To allow “1.”, I could encrypt the keyfile with the password and use the keyfile as key but then,

• If I backed the encrypted version of the keyfile, I'd have to update all backups every time I changed the password,
• If I backed the non-encrypted version of the keyfile, I'd allow to bypass the password by recovering the backup.
• So instead, I chose to combine the keyfile and the password.

### Combination of keyfile and password into key:

I use a bitwise XOR to compute the key from the keyfile and the password. I start at the left and when one of then is empty, I just output the rest of the other one. See my C source file at GitHub.

The other option I thought of was concatenating them. But I didn't like the idea of my key having a recognizable pattern: Random data followed by text.

I therefore used the XOR because it preserves the randomness: for a given password, the distribution of a uniform distribution XORed with that password is still the uniform distribution.

### Current state:

I have something that should work and if there are bugs, I probably will be able to fix them.

### Questions:

1. Is /dev/urandom fine for my use-case or should I use /dev/random?
2. Some people told me that I should use a key derivation function because otherwise, the effect of the password isn't spread. But do I need the effect of the password to be spread? The way I see it, cryptsetup will already use a key derivation function on my key to increase computation time and try to spread the effect of each bit.

Feel free to criticize (constructively) any decision or assumptions I've made (for that project).

-
What is the point of such a long keyfile? $\;$ – Ricky Demer May 10 '14 at 17:37
@RickyDemer : No idea. That's what the tutorials I read did. – xavierm02 May 10 '14 at 17:37
A maybe unexpected, but nevertheless important question: What algorithm (and which cipher-mode) are you planning to use for your HDD encryption in step ”1.”? – e-sushi May 10 '14 at 18:04
@e-sushi : The compiled default in Debian: aes-xts-plain64. – xavierm02 May 10 '14 at 22:07
I see you destroying all your data :) I would use a more sophisticated secret sharing algorithm, that allows sharing the secret to $n$ people whereas the data from $m < n$ people is enough to recover the stored secret. Else the loss of a single secrete kills all your data (one possible algorithm is encoding the secret in a polynomial and share some points on the polynomial (don't know the name of the algorithm right now)) – Thekwasti Jun 5 '14 at 14:29

1. Is /dev/urandom fine for my use-case or should I use /dev/random?

Theoretically, there is no security difference as both are regarded to be cryptographically secure RNGs. Practically, you’ll want to use /dev/urandom as that is “non-blocking” since it re-uses it’s entropy-pool whenever it runs out of random data, while /dev/random may make your program “stall” if it runs out of entropy. Simpler said: /dev/random can be a bottleneck, /dev/urandom fixes the issue.

1. Some people told me that I should use a key derivation function because otherwise, the effect of the password isn't spread. But do I need the effect of the password to be spread? The way I see it, cryptsetup will already use a key derivation function on my key to increase computation time and try to spread the effect of each bit.

I am not familiar with cryptsetup, and I don’t want to judge its internal workings by just taking a short glimpse at the related website… but if you’re sure it implements its own key derivation function (which I think it does as the site talks about using cryptsetup to generate dedicated key-files), it indeed wouldn’t make much sense to run that through another KDF after that. Yet, if you’re not sure if cryptsetup indeed provides a KDF (again: I am not 100% sure about that), or if you have any doubts about the quality of its KDF, I would certainly advise to opt-in for a dedicated KDF tool.

Oh, and one more thing – in case you don’t know about it…

… I could use dm-crypt directly …

“Word on the street” has it that there are some weaknesses to watch out for when using dm-crypt. Meaning: whenever you’re thinking about dm-crypt, remember to choose your settings wisely.

-