summaryrefslogtreecommitdiff
path: root/toxencryptsave/toxencryptsave.c
diff options
context:
space:
mode:
authorirungentoo_trip <irungentoo@gmail.com>2014-10-23 18:09:02 -0700
committerirungentoo_trip <irungentoo@gmail.com>2014-10-23 18:09:02 -0700
commit9878b441b1d2b175b20d28cc41406280e3cada31 (patch)
treeab571798a6eae9ac8e569e043bb1828ee8b71a97 /toxencryptsave/toxencryptsave.c
parentcfac10fb82b27c80e2ba72f07a3ef0c10f16faa6 (diff)
parentd90ee9d4e447f7520fee899b7b6211125095242b (diff)
Merge branch 'dubslow-master'
# # Please enter a commit message to explain why this merge is necessary, # especially if it merges an updated upstream into a topic branch. # # Lines starting with '#' will be ignored, and an empty message aborts # the commit.
Diffstat (limited to 'toxencryptsave/toxencryptsave.c')
-rw-r--r--toxencryptsave/toxencryptsave.c94
1 files changed, 57 insertions, 37 deletions
diff --git a/toxencryptsave/toxencryptsave.c b/toxencryptsave/toxencryptsave.c
index 6567eb96..b6453a89 100644
--- a/toxencryptsave/toxencryptsave.c
+++ b/toxencryptsave/toxencryptsave.c
@@ -36,9 +36,9 @@
36#endif 36#endif
37 37
38#define TOX_PASS_ENCRYPTION_EXTRA_LENGTH (crypto_box_MACBYTES + crypto_box_NONCEBYTES \ 38#define TOX_PASS_ENCRYPTION_EXTRA_LENGTH (crypto_box_MACBYTES + crypto_box_NONCEBYTES \
39 + crypto_pwhash_scryptsalsa208sha256_SALTBYTES) 39 + crypto_pwhash_scryptsalsa208sha256_SALTBYTES + TOX_ENC_SAVE_MAGIC_LENGTH)
40 40
41#define TOX_PASS_KEY_LENGTH (crypto_box_KEYBYTES + crypto_pwhash_scryptsalsa208sha256_SALTBYTES) 41#define TOX_PASS_KEY_LENGTH (crypto_pwhash_scryptsalsa208sha256_SALTBYTES + crypto_box_KEYBYTES)
42 42
43int tox_pass_encryption_extra_length() 43int tox_pass_encryption_extra_length()
44{ 44{
@@ -50,6 +50,11 @@ int tox_pass_key_length()
50 return TOX_PASS_KEY_LENGTH; 50 return TOX_PASS_KEY_LENGTH;
51} 51}
52 52
53int tox_pass_salt_length()
54{
55 return crypto_pwhash_scryptsalsa208sha256_SALTBYTES;
56}
57
53/* This "module" provides functions analogous to tox_load and tox_save in toxcore 58/* This "module" provides functions analogous to tox_load and tox_save in toxcore
54 * Clients should consider alerting their users that, unlike plain data, if even one bit 59 * Clients should consider alerting their users that, unlike plain data, if even one bit
55 * becomes corrupted, the data will be entirely unrecoverable. 60 * becomes corrupted, the data will be entirely unrecoverable.
@@ -59,7 +64,24 @@ int tox_pass_key_length()
59/* return size of the messenger data (for encrypted saving). */ 64/* return size of the messenger data (for encrypted saving). */
60uint32_t tox_encrypted_size(const Tox *tox) 65uint32_t tox_encrypted_size(const Tox *tox)
61{ 66{
62 return tox_size(tox) + TOX_PASS_ENCRYPTION_EXTRA_LENGTH + TOX_ENC_SAVE_MAGIC_LENGTH; 67 return tox_size(tox) + TOX_PASS_ENCRYPTION_EXTRA_LENGTH;
68}
69
70/* This retrieves the salt used to encrypt the given data, which can then be passed to
71 * derive_key_with_salt to produce the same key as was previously used. Any encrpyted
72 * data with this module can be used as input.
73 *
74 * returns -1 if the magic number is wrong
75 * returns 0 otherwise (no guarantee about validity of data)
76 */
77int tox_get_salt(uint8_t *data, uint8_t *salt)
78{
79 if (memcmp(data, TOX_ENC_SAVE_MAGIC_NUMBER, TOX_ENC_SAVE_MAGIC_LENGTH) != 0)
80 return -1;
81
82 data += TOX_ENC_SAVE_MAGIC_LENGTH;
83 memcpy(salt, data, crypto_pwhash_scryptsalsa208sha256_SALTBYTES);
84 return 0;
63} 85}
64 86
65/* Generates a secret symmetric key from the given passphrase. out_key must be at least 87/* Generates a secret symmetric key from the given passphrase. out_key must be at least
@@ -76,19 +98,28 @@ uint32_t tox_encrypted_size(const Tox *tox)
76 */ 98 */
77int tox_derive_key_from_pass(uint8_t *passphrase, uint32_t pplength, uint8_t *out_key) 99int tox_derive_key_from_pass(uint8_t *passphrase, uint32_t pplength, uint8_t *out_key)
78{ 100{
101 uint8_t salt[crypto_pwhash_scryptsalsa208sha256_SALTBYTES];
102 randombytes(salt, sizeof salt);
103 return tox_derive_key_with_salt(passphrase, pplength, salt, out_key);
104}
105
106/* Same as above, except with use the given salt for deterministic key derivation.
107 * The salt must be tox_salt_length() bytes in length.
108 */
109int tox_derive_key_with_salt(uint8_t *passphrase, uint32_t pplength, uint8_t *salt, uint8_t *out_key)
110{
79 if (pplength == 0) 111 if (pplength == 0)
80 return -1; 112 return -1;
81 113
82 uint8_t passkey[crypto_hash_sha256_BYTES]; 114 uint8_t passkey[crypto_hash_sha256_BYTES];
83 crypto_hash_sha256(passkey, passphrase, pplength); 115 crypto_hash_sha256(passkey, passphrase, pplength);
84 /* First derive a key from the password */ 116
117 uint8_t key[crypto_box_KEYBYTES];
118
119 /* Derive a key from the password */
85 /* http://doc.libsodium.org/key_derivation/README.html */ 120 /* http://doc.libsodium.org/key_derivation/README.html */
86 /* note that, according to the documentation, a generic pwhash interface will be created 121 /* note that, according to the documentation, a generic pwhash interface will be created
87 * once the pwhash competition (https://password-hashing.net/) is over */ 122 * once the pwhash competition (https://password-hashing.net/) is over */
88 uint8_t salt[crypto_pwhash_scryptsalsa208sha256_SALTBYTES];
89 uint8_t key[crypto_box_KEYBYTES];
90 randombytes(salt, sizeof salt);
91
92 if (crypto_pwhash_scryptsalsa208sha256( 123 if (crypto_pwhash_scryptsalsa208sha256(
93 key, sizeof(key), passkey, sizeof(passkey), salt, 124 key, sizeof(key), passkey, sizeof(passkey), salt,
94 crypto_pwhash_scryptsalsa208sha256_OPSLIMIT_INTERACTIVE * 2, /* slightly stronger */ 125 crypto_pwhash_scryptsalsa208sha256_OPSLIMIT_INTERACTIVE * 2, /* slightly stronger */
@@ -123,13 +154,17 @@ int tox_pass_key_encrypt(const uint8_t *data, uint32_t data_len, const uint8_t *
123 * need them to decrypt the data 154 * need them to decrypt the data
124 */ 155 */
125 156
126 /* first add the prefix */ 157 /* first add the magic number */
127 uint8_t nonce[crypto_box_NONCEBYTES]; 158 memcpy(out, TOX_ENC_SAVE_MAGIC_NUMBER, TOX_ENC_SAVE_MAGIC_LENGTH);
128 random_nonce(nonce); 159 out += TOX_ENC_SAVE_MAGIC_LENGTH;
129 160
161 /* then add the rest prefix */
130 memcpy(out, key, crypto_pwhash_scryptsalsa208sha256_SALTBYTES); 162 memcpy(out, key, crypto_pwhash_scryptsalsa208sha256_SALTBYTES);
131 key += crypto_pwhash_scryptsalsa208sha256_SALTBYTES; 163 key += crypto_pwhash_scryptsalsa208sha256_SALTBYTES;
132 out += crypto_pwhash_scryptsalsa208sha256_SALTBYTES; 164 out += crypto_pwhash_scryptsalsa208sha256_SALTBYTES;
165
166 uint8_t nonce[crypto_box_NONCEBYTES];
167 random_nonce(nonce);
133 memcpy(out, nonce, crypto_box_NONCEBYTES); 168 memcpy(out, nonce, crypto_box_NONCEBYTES);
134 out += crypto_box_NONCEBYTES; 169 out += crypto_box_NONCEBYTES;
135 170
@@ -172,11 +207,6 @@ int tox_encrypted_save(const Tox *tox, uint8_t *data, uint8_t *passphrase, uint3
172 uint8_t temp_data[temp_size]; 207 uint8_t temp_data[temp_size];
173 tox_save(tox, temp_data); 208 tox_save(tox, temp_data);
174 209
175 /* the output data consists of, in order: magic number, enc_data */
176 /* first add the magic number */
177 memcpy(data, TOX_ENC_SAVE_MAGIC_NUMBER, TOX_ENC_SAVE_MAGIC_LENGTH);
178 data += TOX_ENC_SAVE_MAGIC_LENGTH;
179
180 /* now encrypt */ 210 /* now encrypt */
181 return tox_pass_encrypt(temp_data, temp_size, passphrase, pplength, data); 211 return tox_pass_encrypt(temp_data, temp_size, passphrase, pplength, data);
182} 212}
@@ -194,11 +224,6 @@ int tox_encrypted_key_save(const Tox *tox, uint8_t *data, uint8_t *key)
194 uint8_t temp_data[temp_size]; 224 uint8_t temp_data[temp_size];
195 tox_save(tox, temp_data); 225 tox_save(tox, temp_data);
196 226
197 /* the output data consists of, in order: magic number, enc_data */
198 /* first add the magic number */
199 memcpy(data, TOX_ENC_SAVE_MAGIC_NUMBER, TOX_ENC_SAVE_MAGIC_LENGTH);
200 data += TOX_ENC_SAVE_MAGIC_LENGTH;
201
202 /* encrypt */ 227 /* encrypt */
203 return tox_pass_key_encrypt(temp_data, temp_size, key, data); 228 return tox_pass_key_encrypt(temp_data, temp_size, key, data);
204} 229}
@@ -211,9 +236,12 @@ int tox_encrypted_key_save(const Tox *tox, uint8_t *data, uint8_t *key)
211 */ 236 */
212int tox_pass_key_decrypt(const uint8_t *data, uint32_t length, const uint8_t *key, uint8_t *out) 237int tox_pass_key_decrypt(const uint8_t *data, uint32_t length, const uint8_t *key, uint8_t *out)
213{ 238{
214 if (length <= TOX_PASS_ENCRYPTION_EXTRA_LENGTH) 239 if (length <= TOX_PASS_ENCRYPTION_EXTRA_LENGTH
240 || 0 != memcmp(data, TOX_ENC_SAVE_MAGIC_NUMBER, TOX_ENC_SAVE_MAGIC_LENGTH))
215 return -1; 241 return -1;
216 242
243 data += TOX_ENC_SAVE_MAGIC_LENGTH;
244
217 uint32_t decrypt_length = length - TOX_PASS_ENCRYPTION_EXTRA_LENGTH; 245 uint32_t decrypt_length = length - TOX_PASS_ENCRYPTION_EXTRA_LENGTH;
218 //uint8_t salt[crypto_pwhash_scryptsalsa208sha256_SALTBYTES]; 246 //uint8_t salt[crypto_pwhash_scryptsalsa208sha256_SALTBYTES];
219 uint8_t nonce[crypto_box_NONCEBYTES]; 247 uint8_t nonce[crypto_box_NONCEBYTES];
@@ -241,12 +269,11 @@ int tox_pass_key_decrypt(const uint8_t *data, uint32_t length, const uint8_t *ke
241 */ 269 */
242int tox_pass_decrypt(const uint8_t *data, uint32_t length, uint8_t *passphrase, uint32_t pplength, uint8_t *out) 270int tox_pass_decrypt(const uint8_t *data, uint32_t length, uint8_t *passphrase, uint32_t pplength, uint8_t *out)
243{ 271{
244
245 uint8_t passkey[crypto_hash_sha256_BYTES]; 272 uint8_t passkey[crypto_hash_sha256_BYTES];
246 crypto_hash_sha256(passkey, passphrase, pplength); 273 crypto_hash_sha256(passkey, passphrase, pplength);
247 274
248 uint8_t salt[crypto_pwhash_scryptsalsa208sha256_SALTBYTES]; 275 uint8_t salt[crypto_pwhash_scryptsalsa208sha256_SALTBYTES];
249 memcpy(salt, data, crypto_pwhash_scryptsalsa208sha256_SALTBYTES); 276 memcpy(salt, data + TOX_ENC_SAVE_MAGIC_LENGTH, crypto_pwhash_scryptsalsa208sha256_SALTBYTES);
250 277
251 /* derive the key */ 278 /* derive the key */
252 uint8_t key[crypto_box_KEYBYTES + crypto_pwhash_scryptsalsa208sha256_SALTBYTES]; 279 uint8_t key[crypto_box_KEYBYTES + crypto_pwhash_scryptsalsa208sha256_SALTBYTES];
@@ -272,12 +299,6 @@ int tox_pass_decrypt(const uint8_t *data, uint32_t length, uint8_t *passphrase,
272 */ 299 */
273int tox_encrypted_load(Tox *tox, const uint8_t *data, uint32_t length, uint8_t *passphrase, uint32_t pplength) 300int tox_encrypted_load(Tox *tox, const uint8_t *data, uint32_t length, uint8_t *passphrase, uint32_t pplength)
274{ 301{
275 if (memcmp(data, TOX_ENC_SAVE_MAGIC_NUMBER, TOX_ENC_SAVE_MAGIC_LENGTH) != 0)
276 return -1;
277
278 data += TOX_ENC_SAVE_MAGIC_LENGTH;
279 length -= TOX_ENC_SAVE_MAGIC_LENGTH;
280
281 uint32_t decrypt_length = length - TOX_PASS_ENCRYPTION_EXTRA_LENGTH; 302 uint32_t decrypt_length = length - TOX_PASS_ENCRYPTION_EXTRA_LENGTH;
282 uint8_t temp_data[decrypt_length]; 303 uint8_t temp_data[decrypt_length];
283 304
@@ -295,12 +316,6 @@ int tox_encrypted_load(Tox *tox, const uint8_t *data, uint32_t length, uint8_t *
295 */ 316 */
296int tox_encrypted_key_load(Tox *tox, const uint8_t *data, uint32_t length, uint8_t *key) 317int tox_encrypted_key_load(Tox *tox, const uint8_t *data, uint32_t length, uint8_t *key)
297{ 318{
298 if (memcmp(data, TOX_ENC_SAVE_MAGIC_NUMBER, TOX_ENC_SAVE_MAGIC_LENGTH) != 0)
299 return -1;
300
301 data += TOX_ENC_SAVE_MAGIC_LENGTH;
302 length -= TOX_ENC_SAVE_MAGIC_LENGTH;
303
304 uint32_t decrypt_length = length - TOX_PASS_ENCRYPTION_EXTRA_LENGTH; 319 uint32_t decrypt_length = length - TOX_PASS_ENCRYPTION_EXTRA_LENGTH;
305 uint8_t temp_data[decrypt_length]; 320 uint8_t temp_data[decrypt_length];
306 321
@@ -316,10 +331,15 @@ int tox_encrypted_key_load(Tox *tox, const uint8_t *data, uint32_t length, uint8
316 * returns 1 if it is encrypted 331 * returns 1 if it is encrypted
317 * returns 0 otherwise 332 * returns 0 otherwise
318 */ 333 */
319int tox_is_save_encrypted(const uint8_t *data) 334int tox_is_data_encrypted(const uint8_t *data)
320{ 335{
321 if (memcmp(data, TOX_ENC_SAVE_MAGIC_NUMBER, TOX_ENC_SAVE_MAGIC_LENGTH) == 0) 336 if (memcmp(data, TOX_ENC_SAVE_MAGIC_NUMBER, TOX_ENC_SAVE_MAGIC_LENGTH) == 0)
322 return 1; 337 return 1;
323 else 338 else
324 return 0; 339 return 0;
325} 340}
341
342int tox_is_save_encrypted(const uint8_t *data)
343{
344 return tox_is_data_encrypted(data);
345}