diff options
author | irungentoo <irungentoo@gmail.com> | 2015-04-01 19:57:31 -0400 |
---|---|---|
committer | irungentoo <irungentoo@gmail.com> | 2015-04-01 19:57:31 -0400 |
commit | abff31d2ad3d10df59de72c67a2100e2ad9effb4 (patch) | |
tree | b622d5bd597bf70c2ccc76d42fae00793a3f86bc /toxencryptsave/toxencryptsave.c | |
parent | a2df5f2f5716e1288ff1cde054fba5651a35f570 (diff) | |
parent | 36ed4956fdeacd73243d9348dcb7ef279f22c726 (diff) |
Merge branch 'master' of https://github.com/dubslow/toxcore
Diffstat (limited to 'toxencryptsave/toxencryptsave.c')
-rw-r--r-- | toxencryptsave/toxencryptsave.c | 70 |
1 files changed, 36 insertions, 34 deletions
diff --git a/toxencryptsave/toxencryptsave.c b/toxencryptsave/toxencryptsave.c index 9b202f49..e2f28a58 100644 --- a/toxencryptsave/toxencryptsave.c +++ b/toxencryptsave/toxencryptsave.c | |||
@@ -28,7 +28,6 @@ | |||
28 | #include "toxencryptsave.h" | 28 | #include "toxencryptsave.h" |
29 | #include "defines.h" | 29 | #include "defines.h" |
30 | #include "../toxcore/crypto_core.h" | 30 | #include "../toxcore/crypto_core.h" |
31 | #include "../toxcore/tox.h" | ||
32 | #define SET_ERROR_PARAMETER(param, x) {if(param) {*param = x;}} | 31 | #define SET_ERROR_PARAMETER(param, x) {if(param) {*param = x;}} |
33 | 32 | ||
34 | #ifdef VANILLA_NACL | 33 | #ifdef VANILLA_NACL |
@@ -41,8 +40,8 @@ | |||
41 | #error TOX_PASS_SALT_LENGTH is assumed to be equal to crypto_pwhash_scryptsalsa208sha256_SALTBYTES | 40 | #error TOX_PASS_SALT_LENGTH is assumed to be equal to crypto_pwhash_scryptsalsa208sha256_SALTBYTES |
42 | #endif | 41 | #endif |
43 | 42 | ||
44 | #if TOX_PASS_KEY_LENGTH != (crypto_pwhash_scryptsalsa208sha256_SALTBYTES + crypto_box_KEYBYTES) | 43 | #if TOX_PASS_KEY_LENGTH != crypto_box_KEYBYTES |
45 | #error TOX_PASS_KEY_LENGTH is assumed to be equal to (crypto_pwhash_scryptsalsa208sha256_SALTBYTES + crypto_box_KEYBYTES) | 44 | #error TOX_PASS_KEY_LENGTH is assumed to be equal to crypto_box_KEYBYTES |
46 | #endif | 45 | #endif |
47 | 46 | ||
48 | #if TOX_PASS_ENCRYPTION_EXTRA_LENGTH != (crypto_box_MACBYTES + crypto_box_NONCEBYTES + crypto_pwhash_scryptsalsa208sha256_SALTBYTES + TOX_ENC_SAVE_MAGIC_LENGTH) | 47 | #if TOX_PASS_ENCRYPTION_EXTRA_LENGTH != (crypto_box_MACBYTES + crypto_box_NONCEBYTES + crypto_pwhash_scryptsalsa208sha256_SALTBYTES + TOX_ENC_SAVE_MAGIC_LENGTH) |
@@ -83,7 +82,8 @@ bool tox_get_salt(const uint8_t *data, uint8_t *salt) | |||
83 | * | 82 | * |
84 | * returns true on success | 83 | * returns true on success |
85 | */ | 84 | */ |
86 | bool tox_derive_key_from_pass(uint8_t *passphrase, size_t pplength, uint8_t *out_key, TOX_ERR_KEY_DERIVATION *error) | 85 | bool tox_derive_key_from_pass(uint8_t *passphrase, size_t pplength, TOX_PASS_KEY *out_key, |
86 | TOX_ERR_KEY_DERIVATION *error) | ||
87 | { | 87 | { |
88 | uint8_t salt[crypto_pwhash_scryptsalsa208sha256_SALTBYTES]; | 88 | uint8_t salt[crypto_pwhash_scryptsalsa208sha256_SALTBYTES]; |
89 | randombytes(salt, sizeof salt); | 89 | randombytes(salt, sizeof salt); |
@@ -91,9 +91,9 @@ bool tox_derive_key_from_pass(uint8_t *passphrase, size_t pplength, uint8_t *out | |||
91 | } | 91 | } |
92 | 92 | ||
93 | /* Same as above, except with use the given salt for deterministic key derivation. | 93 | /* Same as above, except with use the given salt for deterministic key derivation. |
94 | * The salt must be tox_salt_length() bytes in length. | 94 | * The salt must be TOX_PASS_SALT_LENGTH bytes in length. |
95 | */ | 95 | */ |
96 | bool tox_derive_key_with_salt(uint8_t *passphrase, size_t pplength, uint8_t *salt, uint8_t *out_key, | 96 | bool tox_derive_key_with_salt(uint8_t *passphrase, size_t pplength, uint8_t *salt, TOX_PASS_KEY *out_key, |
97 | TOX_ERR_KEY_DERIVATION *error) | 97 | TOX_ERR_KEY_DERIVATION *error) |
98 | { | 98 | { |
99 | if (pplength == 0 || !passphrase || !salt || !out_key) { | 99 | if (pplength == 0 || !passphrase || !salt || !out_key) { |
@@ -120,8 +120,8 @@ bool tox_derive_key_with_salt(uint8_t *passphrase, size_t pplength, uint8_t *sal | |||
120 | } | 120 | } |
121 | 121 | ||
122 | sodium_memzero(passkey, crypto_hash_sha256_BYTES); /* wipe plaintext pw */ | 122 | sodium_memzero(passkey, crypto_hash_sha256_BYTES); /* wipe plaintext pw */ |
123 | memcpy(out_key, salt, crypto_pwhash_scryptsalsa208sha256_SALTBYTES); | 123 | memcpy(out_key->salt, salt, crypto_pwhash_scryptsalsa208sha256_SALTBYTES); |
124 | memcpy(out_key + crypto_pwhash_scryptsalsa208sha256_SALTBYTES, key, crypto_box_KEYBYTES); | 124 | memcpy(out_key->key, key, crypto_box_KEYBYTES); |
125 | SET_ERROR_PARAMETER(error, TOX_ERR_KEY_DERIVATION_OK); | 125 | SET_ERROR_PARAMETER(error, TOX_ERR_KEY_DERIVATION_OK); |
126 | return 1; | 126 | return 1; |
127 | } | 127 | } |
@@ -134,7 +134,7 @@ bool tox_derive_key_with_salt(uint8_t *passphrase, size_t pplength, uint8_t *sal | |||
134 | * | 134 | * |
135 | * returns true on success | 135 | * returns true on success |
136 | */ | 136 | */ |
137 | bool tox_pass_key_encrypt(const uint8_t *data, size_t data_len, const uint8_t *key, uint8_t *out, | 137 | bool tox_pass_key_encrypt(const uint8_t *data, size_t data_len, const TOX_PASS_KEY *key, uint8_t *out, |
138 | TOX_ERR_ENCRYPTION *error) | 138 | TOX_ERR_ENCRYPTION *error) |
139 | { | 139 | { |
140 | if (data_len == 0 || !data || !key || !out) { | 140 | if (data_len == 0 || !data || !key || !out) { |
@@ -155,8 +155,7 @@ bool tox_pass_key_encrypt(const uint8_t *data, size_t data_len, const uint8_t *k | |||
155 | out += TOX_ENC_SAVE_MAGIC_LENGTH; | 155 | out += TOX_ENC_SAVE_MAGIC_LENGTH; |
156 | 156 | ||
157 | /* then add the rest prefix */ | 157 | /* then add the rest prefix */ |
158 | memcpy(out, key, crypto_pwhash_scryptsalsa208sha256_SALTBYTES); | 158 | memcpy(out, key->salt, crypto_pwhash_scryptsalsa208sha256_SALTBYTES); |
159 | key += crypto_pwhash_scryptsalsa208sha256_SALTBYTES; | ||
160 | out += crypto_pwhash_scryptsalsa208sha256_SALTBYTES; | 159 | out += crypto_pwhash_scryptsalsa208sha256_SALTBYTES; |
161 | 160 | ||
162 | uint8_t nonce[crypto_box_NONCEBYTES]; | 161 | uint8_t nonce[crypto_box_NONCEBYTES]; |
@@ -165,7 +164,7 @@ bool tox_pass_key_encrypt(const uint8_t *data, size_t data_len, const uint8_t *k | |||
165 | out += crypto_box_NONCEBYTES; | 164 | out += crypto_box_NONCEBYTES; |
166 | 165 | ||
167 | /* now encrypt */ | 166 | /* now encrypt */ |
168 | if (encrypt_data_symmetric(key, nonce, data, data_len, out) | 167 | if (encrypt_data_symmetric(key->key, nonce, data, data_len, out) |
169 | != data_len + crypto_box_MACBYTES) { | 168 | != data_len + crypto_box_MACBYTES) { |
170 | SET_ERROR_PARAMETER(error, TOX_ERR_ENCRYPTION_FAILED); | 169 | SET_ERROR_PARAMETER(error, TOX_ERR_ENCRYPTION_FAILED); |
171 | return 0; | 170 | return 0; |
@@ -184,10 +183,10 @@ bool tox_pass_key_encrypt(const uint8_t *data, size_t data_len, const uint8_t *k | |||
184 | bool tox_pass_encrypt(const uint8_t *data, size_t data_len, uint8_t *passphrase, size_t pplength, uint8_t *out, | 183 | bool tox_pass_encrypt(const uint8_t *data, size_t data_len, uint8_t *passphrase, size_t pplength, uint8_t *out, |
185 | TOX_ERR_ENCRYPTION *error) | 184 | TOX_ERR_ENCRYPTION *error) |
186 | { | 185 | { |
187 | uint8_t key[TOX_PASS_KEY_LENGTH]; | 186 | TOX_PASS_KEY key; |
188 | TOX_ERR_KEY_DERIVATION _error; | 187 | TOX_ERR_KEY_DERIVATION _error; |
189 | 188 | ||
190 | if (!tox_derive_key_from_pass(passphrase, pplength, key, &_error)) { | 189 | if (!tox_derive_key_from_pass(passphrase, pplength, &key, &_error)) { |
191 | if (_error == TOX_ERR_KEY_DERIVATION_NULL) { | 190 | if (_error == TOX_ERR_KEY_DERIVATION_NULL) { |
192 | SET_ERROR_PARAMETER(error, TOX_ERR_ENCRYPTION_NULL); | 191 | SET_ERROR_PARAMETER(error, TOX_ERR_ENCRYPTION_NULL); |
193 | } else if (_error == TOX_ERR_KEY_DERIVATION_FAILED) { | 192 | } else if (_error == TOX_ERR_KEY_DERIVATION_FAILED) { |
@@ -197,7 +196,7 @@ bool tox_pass_encrypt(const uint8_t *data, size_t data_len, uint8_t *passphrase, | |||
197 | return 0; | 196 | return 0; |
198 | } | 197 | } |
199 | 198 | ||
200 | return tox_pass_key_encrypt(data, data_len, key, out, error); | 199 | return tox_pass_key_encrypt(data, data_len, &key, out, error); |
201 | } | 200 | } |
202 | 201 | ||
203 | /* This is the inverse of tox_pass_key_encrypt, also using only keys produced by | 202 | /* This is the inverse of tox_pass_key_encrypt, also using only keys produced by |
@@ -207,7 +206,7 @@ bool tox_pass_encrypt(const uint8_t *data, size_t data_len, uint8_t *passphrase, | |||
207 | * | 206 | * |
208 | * returns true on success | 207 | * returns true on success |
209 | */ | 208 | */ |
210 | bool tox_pass_key_decrypt(const uint8_t *data, size_t length, const uint8_t *key, uint8_t *out, | 209 | bool tox_pass_key_decrypt(const uint8_t *data, size_t length, const TOX_PASS_KEY *key, uint8_t *out, |
211 | TOX_ERR_DECRYPTION *error) | 210 | TOX_ERR_DECRYPTION *error) |
212 | { | 211 | { |
213 | if (length <= TOX_PASS_ENCRYPTION_EXTRA_LENGTH) { | 212 | if (length <= TOX_PASS_ENCRYPTION_EXTRA_LENGTH) { |
@@ -215,25 +214,27 @@ bool tox_pass_key_decrypt(const uint8_t *data, size_t length, const uint8_t *key | |||
215 | return 0; | 214 | return 0; |
216 | } | 215 | } |
217 | 216 | ||
217 | if (!data || !key || !out) { | ||
218 | SET_ERROR_PARAMETER(error, TOX_ERR_DECRYPTION_NULL); | ||
219 | return 0; | ||
220 | } | ||
221 | |||
218 | if (memcmp(data, TOX_ENC_SAVE_MAGIC_NUMBER, TOX_ENC_SAVE_MAGIC_LENGTH) != 0) { | 222 | if (memcmp(data, TOX_ENC_SAVE_MAGIC_NUMBER, TOX_ENC_SAVE_MAGIC_LENGTH) != 0) { |
219 | SET_ERROR_PARAMETER(error, TOX_ERR_DECRYPTION_BAD_FORMAT); | 223 | SET_ERROR_PARAMETER(error, TOX_ERR_DECRYPTION_BAD_FORMAT); |
220 | return 0; | 224 | return 0; |
221 | } | 225 | } |
222 | 226 | ||
223 | data += TOX_ENC_SAVE_MAGIC_LENGTH; | 227 | data += TOX_ENC_SAVE_MAGIC_LENGTH; |
228 | data += crypto_pwhash_scryptsalsa208sha256_SALTBYTES; // salt only affects key derivation | ||
224 | 229 | ||
225 | size_t decrypt_length = length - TOX_PASS_ENCRYPTION_EXTRA_LENGTH; | 230 | size_t decrypt_length = length - TOX_PASS_ENCRYPTION_EXTRA_LENGTH; |
226 | //uint8_t salt[crypto_pwhash_scryptsalsa208sha256_SALTBYTES]; | ||
227 | uint8_t nonce[crypto_box_NONCEBYTES]; | ||
228 | 231 | ||
229 | //memcpy(salt, data, crypto_pwhash_scryptsalsa208sha256_SALTBYTES); | 232 | uint8_t nonce[crypto_box_NONCEBYTES]; |
230 | key += crypto_pwhash_scryptsalsa208sha256_SALTBYTES; // ignore the salt, which is only needed for kdf | ||
231 | data += crypto_pwhash_scryptsalsa208sha256_SALTBYTES; | ||
232 | memcpy(nonce, data, crypto_box_NONCEBYTES); | 233 | memcpy(nonce, data, crypto_box_NONCEBYTES); |
233 | data += crypto_box_NONCEBYTES; | 234 | data += crypto_box_NONCEBYTES; |
234 | 235 | ||
235 | /* decrypt the data */ | 236 | /* decrypt the data */ |
236 | if (decrypt_data_symmetric(key, nonce, data, decrypt_length + crypto_box_MACBYTES, out) | 237 | if (decrypt_data_symmetric(key->key, nonce, data, decrypt_length + crypto_box_MACBYTES, out) |
237 | != decrypt_length) { | 238 | != decrypt_length) { |
238 | SET_ERROR_PARAMETER(error, TOX_ERR_DECRYPTION_FAILED); | 239 | SET_ERROR_PARAMETER(error, TOX_ERR_DECRYPTION_FAILED); |
239 | return 0; | 240 | return 0; |
@@ -254,33 +255,34 @@ bool tox_pass_key_decrypt(const uint8_t *data, size_t length, const uint8_t *key | |||
254 | bool tox_pass_decrypt(const uint8_t *data, size_t length, uint8_t *passphrase, size_t pplength, uint8_t *out, | 255 | bool tox_pass_decrypt(const uint8_t *data, size_t length, uint8_t *passphrase, size_t pplength, uint8_t *out, |
255 | TOX_ERR_DECRYPTION *error) | 256 | TOX_ERR_DECRYPTION *error) |
256 | { | 257 | { |
258 | if (length <= TOX_PASS_ENCRYPTION_EXTRA_LENGTH || pplength == 0) { | ||
259 | SET_ERROR_PARAMETER(error, TOX_ERR_DECRYPTION_INVALID_LENGTH); | ||
260 | return 0; | ||
261 | } | ||
262 | |||
263 | if (!data || !passphrase || !out) { | ||
264 | SET_ERROR_PARAMETER(error, TOX_ERR_DECRYPTION_NULL); | ||
265 | return 0; | ||
266 | } | ||
267 | |||
257 | if (memcmp(data, TOX_ENC_SAVE_MAGIC_NUMBER, TOX_ENC_SAVE_MAGIC_LENGTH) != 0) { | 268 | if (memcmp(data, TOX_ENC_SAVE_MAGIC_NUMBER, TOX_ENC_SAVE_MAGIC_LENGTH) != 0) { |
258 | SET_ERROR_PARAMETER(error, TOX_ERR_DECRYPTION_BAD_FORMAT); | 269 | SET_ERROR_PARAMETER(error, TOX_ERR_DECRYPTION_BAD_FORMAT); |
259 | return 0; | 270 | return 0; |
260 | } | 271 | } |
261 | 272 | ||
262 | uint8_t passkey[crypto_hash_sha256_BYTES]; | ||
263 | crypto_hash_sha256(passkey, passphrase, pplength); | ||
264 | |||
265 | uint8_t salt[crypto_pwhash_scryptsalsa208sha256_SALTBYTES]; | 273 | uint8_t salt[crypto_pwhash_scryptsalsa208sha256_SALTBYTES]; |
266 | memcpy(salt, data + TOX_ENC_SAVE_MAGIC_LENGTH, crypto_pwhash_scryptsalsa208sha256_SALTBYTES); | 274 | memcpy(salt, data + TOX_ENC_SAVE_MAGIC_LENGTH, crypto_pwhash_scryptsalsa208sha256_SALTBYTES); |
267 | 275 | ||
268 | /* derive the key */ | 276 | /* derive the key */ |
269 | uint8_t key[crypto_box_KEYBYTES + crypto_pwhash_scryptsalsa208sha256_SALTBYTES]; | 277 | TOX_PASS_KEY key; |
270 | 278 | ||
271 | if (crypto_pwhash_scryptsalsa208sha256( | 279 | if (!tox_derive_key_with_salt(passphrase, pplength, salt, &key, NULL)) { |
272 | key + crypto_pwhash_scryptsalsa208sha256_SALTBYTES, | ||
273 | crypto_box_KEYBYTES, (char *)passkey, sizeof(passkey), salt, | ||
274 | crypto_pwhash_scryptsalsa208sha256_OPSLIMIT_INTERACTIVE * 2, /* slightly stronger */ | ||
275 | crypto_pwhash_scryptsalsa208sha256_MEMLIMIT_INTERACTIVE) != 0) { | ||
276 | /* out of memory most likely */ | 280 | /* out of memory most likely */ |
277 | SET_ERROR_PARAMETER(error, TOX_ERR_DECRYPTION_KEY_DERIVATION_FAILED); | 281 | SET_ERROR_PARAMETER(error, TOX_ERR_DECRYPTION_KEY_DERIVATION_FAILED); |
278 | return 0; | 282 | return 0; |
279 | } | 283 | } |
280 | 284 | ||
281 | sodium_memzero(passkey, crypto_hash_sha256_BYTES); /* wipe plaintext pw */ | 285 | return tox_pass_key_decrypt(data, length, &key, out, error); |
282 | |||
283 | return tox_pass_key_decrypt(data, length, key, out, error); | ||
284 | } | 286 | } |
285 | 287 | ||
286 | /* Determines whether or not the given data is encrypted (by checking the magic number) | 288 | /* Determines whether or not the given data is encrypted (by checking the magic number) |