This is part of my master thesis that I'm about to finish currently.
I am accepting key material from two sources:
- From a TPM, or Hardware-backed Keystore. There we need the whole 32 Bytes (256 bits) for maximum security.
- From a Paper Key, or user input. Assuming we can get ~6 bits of randomness we need at least 42 characters. Going with the more pessimistic ~4.5 bits per character we need at least 56 characters to reach 256 bits strength.
The next step is to calculate candidate values per
Slot information is stored on disk and readable for an attacker.
Potential Slot Key and the slot specific
Salt I generate a
512 bits key stream for the following components:
Encrypted Master Keyfrom the first 256 bits.
Encrypted Noncefrom the next 128 bits, where I discard the first 32 bits because I need the lower 96 bits only.
Check Valuefrom the last 128 bits.
Check Value matches the one stored on disk I know that the user input is valid and I can decrypt the super block with chacha20-poly1305.
Why so complicated?
The idea is that a user can synchronise the encrypted data over multiple devices and access it with convenience of the platforms hardware security.
Even without synchronisation firmware upgrade can erase the contents of a TPM and we need the
Paper Key as a means to open the vault and include a new key with the current TPM.
One risk is that an attacker is able to use the
Check Value generated by Argon2 to reverse back to the
Encrypted Nonce or even
Encrypted Master Key.
I am inspired by the design of LUKS1 and LUKS2.
The 32 bits that are not used in the
Slot.Decryption Nonce XOR could be used for error detection.
This would not stop an attacker but allow the user to detect bit rot.