summaryrefslogtreecommitdiff
path: root/toxencryptsave/toxencryptsave.c
diff options
context:
space:
mode:
authorirungentoo <irungentoo@gmail.com>2015-04-01 19:57:31 -0400
committerirungentoo <irungentoo@gmail.com>2015-04-01 19:57:31 -0400
commitabff31d2ad3d10df59de72c67a2100e2ad9effb4 (patch)
treeb622d5bd597bf70c2ccc76d42fae00793a3f86bc /toxencryptsave/toxencryptsave.c
parenta2df5f2f5716e1288ff1cde054fba5651a35f570 (diff)
parent36ed4956fdeacd73243d9348dcb7ef279f22c726 (diff)
Merge branch 'master' of https://github.com/dubslow/toxcore
Diffstat (limited to 'toxencryptsave/toxencryptsave.c')
-rw-r--r--toxencryptsave/toxencryptsave.c70
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 */
86bool tox_derive_key_from_pass(uint8_t *passphrase, size_t pplength, uint8_t *out_key, TOX_ERR_KEY_DERIVATION *error) 85bool 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 */
96bool tox_derive_key_with_salt(uint8_t *passphrase, size_t pplength, uint8_t *salt, uint8_t *out_key, 96bool 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 */
137bool tox_pass_key_encrypt(const uint8_t *data, size_t data_len, const uint8_t *key, uint8_t *out, 137bool 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
184bool tox_pass_encrypt(const uint8_t *data, size_t data_len, uint8_t *passphrase, size_t pplength, uint8_t *out, 183bool 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 */
210bool tox_pass_key_decrypt(const uint8_t *data, size_t length, const uint8_t *key, uint8_t *out, 209bool 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
254bool tox_pass_decrypt(const uint8_t *data, size_t length, uint8_t *passphrase, size_t pplength, uint8_t *out, 255bool 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)