summaryrefslogtreecommitdiff
path: root/toxencryptsave
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
parenta2df5f2f5716e1288ff1cde054fba5651a35f570 (diff)
parent36ed4956fdeacd73243d9348dcb7ef279f22c726 (diff)
Merge branch 'master' of https://github.com/dubslow/toxcore
Diffstat (limited to 'toxencryptsave')
-rw-r--r--toxencryptsave/toxencryptsave.c70
-rw-r--r--toxencryptsave/toxencryptsave.h32
2 files changed, 61 insertions, 41 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)
diff --git a/toxencryptsave/toxencryptsave.h b/toxencryptsave/toxencryptsave.h
index 2ee4af46..c077d899 100644
--- a/toxencryptsave/toxencryptsave.h
+++ b/toxencryptsave/toxencryptsave.h
@@ -39,7 +39,7 @@ struct Tox_Options;
39#endif 39#endif
40 40
41#define TOX_PASS_SALT_LENGTH 32 41#define TOX_PASS_SALT_LENGTH 32
42#define TOX_PASS_KEY_LENGTH 64 42#define TOX_PASS_KEY_LENGTH 32
43#define TOX_PASS_ENCRYPTION_EXTRA_LENGTH 80 43#define TOX_PASS_ENCRYPTION_EXTRA_LENGTH 80
44 44
45/* This module is conceptually organized into two parts. The first part are the functions 45/* This module is conceptually organized into two parts. The first part are the functions
@@ -60,6 +60,15 @@ struct Tox_Options;
60 * Ditto if they forget their password, there is no way to recover the data. 60 * Ditto if they forget their password, there is no way to recover the data.
61 */ 61 */
62 62
63/* Since apparently no one actually bothered to learn about the module previously,
64 * the recently removed functions tox_encrypted_new and tox_get_encrypted_savedata
65 * may be trivially replaced by calls to tox_pass_decrypt -> tox_new or
66 * tox_get_savedata -> tox_pass_encrypt as appropriate. The removed functions
67 * were never more than 5 line wrappers of the other public API functions anyways.
68 * (As has always been, tox_pass_decrypt and tox_pass_encrypt are interchangeable
69 * with tox_pass_key_decrypt and tox_pass_key_encrypt, as the client program requires.)
70 */
71
63typedef enum TOX_ERR_KEY_DERIVATION { 72typedef enum TOX_ERR_KEY_DERIVATION {
64 TOX_ERR_KEY_DERIVATION_OK, 73 TOX_ERR_KEY_DERIVATION_OK,
65 /** 74 /**
@@ -155,6 +164,14 @@ bool tox_pass_decrypt(const uint8_t *data, size_t length, uint8_t *passphrase, s
155 * intensive than part one. The first 3 functions are for key handling. 164 * intensive than part one. The first 3 functions are for key handling.
156 */ 165 */
157 166
167/* This key structure's internals should not be used by any client program, even
168 * if they are straightforward here.
169 */
170typedef struct {
171 uint8_t salt[TOX_PASS_SALT_LENGTH];
172 uint8_t key[TOX_PASS_KEY_LENGTH];
173} TOX_PASS_KEY;
174
158/* Generates a secret symmetric key from the given passphrase. out_key must be at least 175/* Generates a secret symmetric key from the given passphrase. out_key must be at least
159 * TOX_PASS_KEY_LENGTH bytes long. 176 * TOX_PASS_KEY_LENGTH bytes long.
160 * Be sure to not compromise the key! Only keep it in memory, do not write to disk. 177 * Be sure to not compromise the key! Only keep it in memory, do not write to disk.
@@ -166,12 +183,13 @@ bool tox_pass_decrypt(const uint8_t *data, size_t length, uint8_t *passphrase, s
166 * 183 *
167 * returns true on success 184 * returns true on success
168 */ 185 */
169bool tox_derive_key_from_pass(uint8_t *passphrase, size_t pplength, uint8_t *out_key, TOX_ERR_KEY_DERIVATION *error); 186bool tox_derive_key_from_pass(uint8_t *passphrase, size_t pplength, TOX_PASS_KEY *out_key,
187 TOX_ERR_KEY_DERIVATION *error);
170 188
171/* Same as above, except with use the given salt for deterministic key derivation. 189/* Same as above, except use the given salt for deterministic key derivation.
172 * The salt must be tox_salt_length() bytes in length. 190 * The salt must be TOX_PASS_SALT_LENGTH bytes in length.
173 */ 191 */
174bool tox_derive_key_with_salt(uint8_t *passphrase, size_t pplength, uint8_t *salt, uint8_t *out_key, 192bool tox_derive_key_with_salt(uint8_t *passphrase, size_t pplength, uint8_t *salt, TOX_PASS_KEY *out_key,
175 TOX_ERR_KEY_DERIVATION *error); 193 TOX_ERR_KEY_DERIVATION *error);
176 194
177/* This retrieves the salt used to encrypt the given data, which can then be passed to 195/* This retrieves the salt used to encrypt the given data, which can then be passed to
@@ -194,7 +212,7 @@ bool tox_get_salt(const uint8_t *data, uint8_t *salt);
194 * 212 *
195 * returns true on success 213 * returns true on success
196 */ 214 */
197bool tox_pass_key_encrypt(const uint8_t *data, size_t data_len, const uint8_t *key, uint8_t *out, 215bool tox_pass_key_encrypt(const uint8_t *data, size_t data_len, const TOX_PASS_KEY *key, uint8_t *out,
198 TOX_ERR_ENCRYPTION *error); 216 TOX_ERR_ENCRYPTION *error);
199 217
200/* This is the inverse of tox_pass_key_encrypt, also using only keys produced by 218/* This is the inverse of tox_pass_key_encrypt, also using only keys produced by
@@ -204,7 +222,7 @@ bool tox_pass_key_encrypt(const uint8_t *data, size_t data_len, const uint8_t *k
204 * 222 *
205 * returns true on success 223 * returns true on success
206 */ 224 */
207bool tox_pass_key_decrypt(const uint8_t *data, size_t length, const uint8_t *key, uint8_t *out, 225bool tox_pass_key_decrypt(const uint8_t *data, size_t length, const TOX_PASS_KEY *key, uint8_t *out,
208 TOX_ERR_DECRYPTION *error); 226 TOX_ERR_DECRYPTION *error);
209 227
210/* Determines whether or not the given data is encrypted (by checking the magic number) 228/* Determines whether or not the given data is encrypted (by checking the magic number)