-
Notifications
You must be signed in to change notification settings - Fork 10
/
README
99 lines (72 loc) · 4.08 KB
/
README
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
DESCRIPTION
threshcrypt - A password-based implementation of threshold encryption
LICENSE
Simplified BSD License. See the included 'COPYING' file.
INSTALL
Just run 'make' and copy the binary somewhere. You can also run 'make static'
to build a staticly linked version, which will be compressed with UPX if it is
installed in your $PATH. Tested on x86_64 & i386 Linux with gcc and glibc. t
USAGE
Encrypt:
threshcrypt -t threshold -n shares input_file [output_file]
Decrypt:
threshcrypt input_file [output_file]
See main.c for other options until I update this file.
NOTES
* This is *ALPHA* software. No attempt will be made to maintain file format
backwards compatibility until a beta relase.
* Currently, no automatic adjustment is done to the work factor of the KDF
to compensate for the number of encrypted shares it needs to be run against.
With a large number of shares the default parameters will be rather slow to
verify a share password.
CRYPTO DESIGN
Operation overview:
When encrypting, first the user is prompted to enter passwords for each
share. As each password is confirmed, it is fed to PBKDF2 along with a
random 12 byte salt in order to generate a 'share key'. As soon as the
share key has been generated, the password is zeroed in memory.
Once all the share keys have been generated, a random master key is
generated, using the share keys as an additional entropy source (this
helps if your RNG/PRNG is poor quality). The master key is then
MAC'd and split into a series of shares using Shamir's secret sharing.
Each share is encrypted with the corresponding share key and then zeroed
in memory.
Finally, the plaintext is read in chunks which are then encrypted and MAC'd
to prevent the data from being read/tampered with.
For decryption, the user is prompted to enter 'any password' with an
indication of how many shares have been unlocked and how many are needed
to recover the master key. For each password, *all* shares are checked in
turn and a running total how how many more shares have been been unlocked
is kept (multiple shares can have the same password). Once enough shares
have been decrypted, the master key is recovered. The master key is then
tested against the checksum. If the master key looks good, then the
ciphertext chunks will be verified and decrypted.
Other notes:
The chunked file data is stored using CTR+HMAC encrypt-then-mac.
I may later add options to GCM / EAX / other authenticated encryption
modes, but it's not worth the trouble right now. Simmilarly, currently the
only supported ciphers and hashes are AES and SHA-256 respectively.
I (ab)use PBKDF2 a bit as a key expansion function. This is because if you
specify a larger than hashlen for PBKDF2's output size and use that key
material for anything other than a single large key it can be attacked
in parallel. I'd rather use the HKDF expansion function to generate the
subkeys, but I didn't find a library and didn't want to screw it up^W^W^W
implement it myself.
I *ALSO* (ab)use PBKDF2 with a small number of iterations as a replacement
for HMAC to verify the master key. Plain HMAC would probably be fine for
that, but I'm paranoid and this is how LUKS does master key verification.
This scheme will hopefully add some additional protection in case the hash
algorithm used is broken.
TODO
* add support for other KDFs besides pbkdf2, starting with scrypt
* implement locked_malloc/unlock_free and use it for libgfshare and libtomcrypt
structs
- should page align and round up size to whole pages to ensure freeing has no
side effects
* copy code from crypt_data to ctr_hmac_block which will take a ctr sturct as
an argument.
- wrap with ctr_hmac_dec_block and ctr_hmac_enc_block macros
- convert crypt_data to a wrapper for the above
* implement ctr_hmac_fd wrapped by ctr_hmac_dec_fd and ctr_hmac_enc_fd
* mlock sensitive memory regions in libgfshare and libtomcrypt before using them
* do user interaction on /dev/tty so that data can be accepted on stdin