summaryrefslogtreecommitdiff
path: root/toxencryptsave/toxencryptsave.c
diff options
context:
space:
mode:
authoriphydf <iphydf@users.noreply.github.com>2016-12-16 03:00:55 +0000
committeriphydf <iphydf@users.noreply.github.com>2017-12-29 23:24:54 +0000
commitd26f0eb3bcdd622cc8adae98974a27d7487fc6cb (patch)
tree5643926efde516051ee9fe9efa9e6f9b04ea0548 /toxencryptsave/toxencryptsave.c
parent2c8fb05f6e1631403053ef8648d5860e0ec15cc3 (diff)
Change toxencryptsave API to never overwrite pass keys.
Diffstat (limited to 'toxencryptsave/toxencryptsave.c')
-rw-r--r--toxencryptsave/toxencryptsave.c47
1 files changed, 27 insertions, 20 deletions
diff --git a/toxencryptsave/toxencryptsave.c b/toxencryptsave/toxencryptsave.c
index 5640e82f..b7360b56 100644
--- a/toxencryptsave/toxencryptsave.c
+++ b/toxencryptsave/toxencryptsave.c
@@ -71,11 +71,6 @@ struct Tox_Pass_Key {
71 uint8_t key[TOX_PASS_KEY_LENGTH]; 71 uint8_t key[TOX_PASS_KEY_LENGTH];
72}; 72};
73 73
74Tox_Pass_Key *tox_pass_key_new(void)
75{
76 return (Tox_Pass_Key *)malloc(sizeof(Tox_Pass_Key));
77}
78
79void tox_pass_key_free(Tox_Pass_Key *pass_key) 74void tox_pass_key_free(Tox_Pass_Key *pass_key)
80{ 75{
81 free(pass_key); 76 free(pass_key);
@@ -123,23 +118,23 @@ bool tox_get_salt(const uint8_t *data, uint8_t *salt, TOX_ERR_GET_SALT *error)
123 * 118 *
124 * returns true on success 119 * returns true on success
125 */ 120 */
126bool tox_pass_key_derive(Tox_Pass_Key *out_key, const uint8_t *passphrase, size_t pplength, 121Tox_Pass_Key *tox_pass_key_derive(const uint8_t *passphrase, size_t pplength,
127 TOX_ERR_KEY_DERIVATION *error) 122 TOX_ERR_KEY_DERIVATION *error)
128{ 123{
129 uint8_t salt[crypto_pwhash_scryptsalsa208sha256_SALTBYTES]; 124 uint8_t salt[crypto_pwhash_scryptsalsa208sha256_SALTBYTES];
130 randombytes(salt, sizeof salt); 125 randombytes(salt, sizeof salt);
131 return tox_pass_key_derive_with_salt(out_key, passphrase, pplength, salt, error); 126 return tox_pass_key_derive_with_salt(passphrase, pplength, salt, error);
132} 127}
133 128
134/* Same as above, except with use the given salt for deterministic key derivation. 129/* Same as above, except with use the given salt for deterministic key derivation.
135 * The salt must be TOX_PASS_SALT_LENGTH bytes in length. 130 * The salt must be TOX_PASS_SALT_LENGTH bytes in length.
136 */ 131 */
137bool tox_pass_key_derive_with_salt(Tox_Pass_Key *out_key, const uint8_t *passphrase, size_t pplength, 132Tox_Pass_Key *tox_pass_key_derive_with_salt(const uint8_t *passphrase, size_t pplength,
138 const uint8_t *salt, TOX_ERR_KEY_DERIVATION *error) 133 const uint8_t *salt, TOX_ERR_KEY_DERIVATION *error)
139{ 134{
140 if (!salt || !out_key || (!passphrase && pplength != 0)) { 135 if (!salt || (!passphrase && pplength != 0)) {
141 SET_ERROR_PARAMETER(error, TOX_ERR_KEY_DERIVATION_NULL); 136 SET_ERROR_PARAMETER(error, TOX_ERR_KEY_DERIVATION_NULL);
142 return 0; 137 return NULL;
143 } 138 }
144 139
145 uint8_t passkey[crypto_hash_sha256_BYTES]; 140 uint8_t passkey[crypto_hash_sha256_BYTES];
@@ -157,14 +152,22 @@ bool tox_pass_key_derive_with_salt(Tox_Pass_Key *out_key, const uint8_t *passphr
157 crypto_pwhash_scryptsalsa208sha256_MEMLIMIT_INTERACTIVE) != 0) { 152 crypto_pwhash_scryptsalsa208sha256_MEMLIMIT_INTERACTIVE) != 0) {
158 /* out of memory most likely */ 153 /* out of memory most likely */
159 SET_ERROR_PARAMETER(error, TOX_ERR_KEY_DERIVATION_FAILED); 154 SET_ERROR_PARAMETER(error, TOX_ERR_KEY_DERIVATION_FAILED);
160 return 0; 155 return NULL;
161 } 156 }
162 157
163 sodium_memzero(passkey, crypto_hash_sha256_BYTES); /* wipe plaintext pw */ 158 sodium_memzero(passkey, crypto_hash_sha256_BYTES); /* wipe plaintext pw */
159
160 Tox_Pass_Key *out_key = (Tox_Pass_Key *)malloc(sizeof(Tox_Pass_Key));
161
162 if (!out_key) {
163 SET_ERROR_PARAMETER(error, TOX_ERR_KEY_DERIVATION_FAILED);
164 return NULL;
165 }
166
164 memcpy(out_key->salt, salt, crypto_pwhash_scryptsalsa208sha256_SALTBYTES); 167 memcpy(out_key->salt, salt, crypto_pwhash_scryptsalsa208sha256_SALTBYTES);
165 memcpy(out_key->key, key, CRYPTO_SHARED_KEY_SIZE); 168 memcpy(out_key->key, key, CRYPTO_SHARED_KEY_SIZE);
166 SET_ERROR_PARAMETER(error, TOX_ERR_KEY_DERIVATION_OK); 169 SET_ERROR_PARAMETER(error, TOX_ERR_KEY_DERIVATION_OK);
167 return 1; 170 return out_key;
168} 171}
169 172
170/* Encrypt arbitrary with a key produced by tox_derive_key_*. The output 173/* Encrypt arbitrary with a key produced by tox_derive_key_*. The output
@@ -224,10 +227,10 @@ bool tox_pass_key_encrypt(const Tox_Pass_Key *key, const uint8_t *data, size_t d
224bool tox_pass_encrypt(const uint8_t *data, size_t data_len, const uint8_t *passphrase, size_t pplength, uint8_t *out, 227bool tox_pass_encrypt(const uint8_t *data, size_t data_len, const uint8_t *passphrase, size_t pplength, uint8_t *out,
225 TOX_ERR_ENCRYPTION *error) 228 TOX_ERR_ENCRYPTION *error)
226{ 229{
227 Tox_Pass_Key key;
228 TOX_ERR_KEY_DERIVATION _error; 230 TOX_ERR_KEY_DERIVATION _error;
231 Tox_Pass_Key *key = tox_pass_key_derive(passphrase, pplength, &_error);
229 232
230 if (!tox_pass_key_derive(&key, passphrase, pplength, &_error)) { 233 if (!key) {
231 if (_error == TOX_ERR_KEY_DERIVATION_NULL) { 234 if (_error == TOX_ERR_KEY_DERIVATION_NULL) {
232 SET_ERROR_PARAMETER(error, TOX_ERR_ENCRYPTION_NULL); 235 SET_ERROR_PARAMETER(error, TOX_ERR_ENCRYPTION_NULL);
233 } else if (_error == TOX_ERR_KEY_DERIVATION_FAILED) { 236 } else if (_error == TOX_ERR_KEY_DERIVATION_FAILED) {
@@ -237,7 +240,9 @@ bool tox_pass_encrypt(const uint8_t *data, size_t data_len, const uint8_t *passp
237 return 0; 240 return 0;
238 } 241 }
239 242
240 return tox_pass_key_encrypt(&key, data, data_len, out, error); 243 bool result = tox_pass_key_encrypt(key, data, data_len, out, error);
244 tox_pass_key_free(key);
245 return result;
241} 246}
242 247
243/* This is the inverse of tox_pass_key_encrypt, also using only keys produced by 248/* This is the inverse of tox_pass_key_encrypt, also using only keys produced by
@@ -315,15 +320,17 @@ bool tox_pass_decrypt(const uint8_t *data, size_t length, const uint8_t *passphr
315 memcpy(salt, data + TOX_ENC_SAVE_MAGIC_LENGTH, crypto_pwhash_scryptsalsa208sha256_SALTBYTES); 320 memcpy(salt, data + TOX_ENC_SAVE_MAGIC_LENGTH, crypto_pwhash_scryptsalsa208sha256_SALTBYTES);
316 321
317 /* derive the key */ 322 /* derive the key */
318 Tox_Pass_Key key; 323 Tox_Pass_Key *key = tox_pass_key_derive_with_salt(passphrase, pplength, salt, NULL);
319 324
320 if (!tox_pass_key_derive_with_salt(&key, passphrase, pplength, salt, NULL)) { 325 if (!key) {
321 /* out of memory most likely */ 326 /* out of memory most likely */
322 SET_ERROR_PARAMETER(error, TOX_ERR_DECRYPTION_KEY_DERIVATION_FAILED); 327 SET_ERROR_PARAMETER(error, TOX_ERR_DECRYPTION_KEY_DERIVATION_FAILED);
323 return 0; 328 return 0;
324 } 329 }
325 330
326 return tox_pass_key_decrypt(&key, data, length, out, error); 331 bool result = tox_pass_key_decrypt(key, data, length, out, error);
332 tox_pass_key_free(key);
333 return result;
327} 334}
328 335
329/* Determines whether or not the given data is encrypted (by checking the magic number) 336/* Determines whether or not the given data is encrypted (by checking the magic number)