summaryrefslogtreecommitdiff
path: root/toxencryptsave
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
parent2c8fb05f6e1631403053ef8648d5860e0ec15cc3 (diff)
Change toxencryptsave API to never overwrite pass keys.
Diffstat (limited to 'toxencryptsave')
-rw-r--r--toxencryptsave/toxencryptsave.api.h20
-rw-r--r--toxencryptsave/toxencryptsave.c47
-rw-r--r--toxencryptsave/toxencryptsave.h24
3 files changed, 39 insertions, 52 deletions
diff --git a/toxencryptsave/toxencryptsave.api.h b/toxencryptsave/toxencryptsave.api.h
index 61f685f8..3adf3a9d 100644
--- a/toxencryptsave/toxencryptsave.api.h
+++ b/toxencryptsave/toxencryptsave.api.h
@@ -82,8 +82,7 @@ error for key_derivation {
82 NULL, 82 NULL,
83 /** 83 /**
84 * The crypto lib was unable to derive a key from the given passphrase, 84 * The crypto lib was unable to derive a key from the given passphrase,
85 * which is usually a lack of memory issue. The functions accepting keys 85 * which is usually a lack of memory issue.
86 * do not produce this error.
87 */ 86 */
88 FAILED, 87 FAILED,
89} 88}
@@ -192,21 +191,12 @@ class pass_Key {
192 * for encryption and decryption. It is derived from a salt and the user- 191 * for encryption and decryption. It is derived from a salt and the user-
193 * provided password. 192 * provided password.
194 * 193 *
195 * The $this structure is hidden in the implementation. It can be allocated 194 * The $this structure is hidden in the implementation. It can be created
196 * using $new and must be deallocated using $free. 195 * using $derive or $derive_with_salt and must be deallocated using $free.
197 */ 196 */
198 struct this; 197 struct this;
199 198
200 /** 199 /**
201 * Create a new $this. The initial value of it is indeterminate. To
202 * initialise it, use one of the derive_* functions below.
203 *
204 * In case of failure, this function returns NULL. The only failure mode at
205 * this time is memory allocation failure, so this function has no error code.
206 */
207 static this new();
208
209 /**
210 * Deallocate a $this. This function behaves like free(), so NULL is an 200 * Deallocate a $this. This function behaves like free(), so NULL is an
211 * acceptable argument value. 201 * acceptable argument value.
212 */ 202 */
@@ -227,7 +217,7 @@ class pass_Key {
227 * 217 *
228 * @return true on success. 218 * @return true on success.
229 */ 219 */
230 bool derive(const uint8_t[passphrase_len] passphrase) 220 static this derive(const uint8_t[passphrase_len] passphrase)
231 with error for key_derivation; 221 with error for key_derivation;
232 222
233 /** 223 /**
@@ -239,7 +229,7 @@ class pass_Key {
239 * 229 *
240 * @return true on success. 230 * @return true on success.
241 */ 231 */
242 bool derive_with_salt(const uint8_t[passphrase_len] passphrase, const uint8_t[PASS_SALT_LENGTH] salt) 232 static this derive_with_salt(const uint8_t[passphrase_len] passphrase, const uint8_t[PASS_SALT_LENGTH] salt)
243 with error for key_derivation; 233 with error for key_derivation;
244 234
245 /** 235 /**
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)
diff --git a/toxencryptsave/toxencryptsave.h b/toxencryptsave/toxencryptsave.h
index ef1ab152..c5a1dff9 100644
--- a/toxencryptsave/toxencryptsave.h
+++ b/toxencryptsave/toxencryptsave.h
@@ -99,8 +99,7 @@ typedef enum TOX_ERR_KEY_DERIVATION {
99 99
100 /** 100 /**
101 * The crypto lib was unable to derive a key from the given passphrase, 101 * The crypto lib was unable to derive a key from the given passphrase,
102 * which is usually a lack of memory issue. The functions accepting keys 102 * which is usually a lack of memory issue.
103 * do not produce this error.
104 */ 103 */
105 TOX_ERR_KEY_DERIVATION_FAILED, 104 TOX_ERR_KEY_DERIVATION_FAILED,
106 105
@@ -241,8 +240,8 @@ bool tox_pass_decrypt(const uint8_t *ciphertext, size_t ciphertext_len, const ui
241 * for encryption and decryption. It is derived from a salt and the user- 240 * for encryption and decryption. It is derived from a salt and the user-
242 * provided password. 241 * provided password.
243 * 242 *
244 * The Tox_Pass_Key structure is hidden in the implementation. It can be allocated 243 * The Tox_Pass_Key structure is hidden in the implementation. It can be created
245 * using tox_pass_key_new and must be deallocated using tox_pass_key_free. 244 * using tox_pass_key_derive or tox_pass_key_derive_with_salt and must be deallocated using tox_pass_key_free.
246 */ 245 */
247#ifndef TOX_PASS_KEY_DEFINED 246#ifndef TOX_PASS_KEY_DEFINED
248#define TOX_PASS_KEY_DEFINED 247#define TOX_PASS_KEY_DEFINED
@@ -250,15 +249,6 @@ typedef struct Tox_Pass_Key Tox_Pass_Key;
250#endif /* TOX_PASS_KEY_DEFINED */ 249#endif /* TOX_PASS_KEY_DEFINED */
251 250
252/** 251/**
253 * Create a new Tox_Pass_Key. The initial value of it is indeterminate. To
254 * initialise it, use one of the derive_* functions below.
255 *
256 * In case of failure, this function returns NULL. The only failure mode at
257 * this time is memory allocation failure, so this function has no error code.
258 */
259struct Tox_Pass_Key *tox_pass_key_new(void);
260
261/**
262 * Deallocate a Tox_Pass_Key. This function behaves like free(), so NULL is an 252 * Deallocate a Tox_Pass_Key. This function behaves like free(), so NULL is an
263 * acceptable argument value. 253 * acceptable argument value.
264 */ 254 */
@@ -279,8 +269,8 @@ void tox_pass_key_free(struct Tox_Pass_Key *_key);
279 * 269 *
280 * @return true on success. 270 * @return true on success.
281 */ 271 */
282bool tox_pass_key_derive(struct Tox_Pass_Key *_key, const uint8_t *passphrase, size_t passphrase_len, 272struct Tox_Pass_Key *tox_pass_key_derive(const uint8_t *passphrase, size_t passphrase_len,
283 TOX_ERR_KEY_DERIVATION *error); 273 TOX_ERR_KEY_DERIVATION *error);
284 274
285/** 275/**
286 * Same as above, except use the given salt for deterministic key derivation. 276 * Same as above, except use the given salt for deterministic key derivation.
@@ -291,8 +281,8 @@ bool tox_pass_key_derive(struct Tox_Pass_Key *_key, const uint8_t *passphrase, s
291 * 281 *
292 * @return true on success. 282 * @return true on success.
293 */ 283 */
294bool tox_pass_key_derive_with_salt(struct Tox_Pass_Key *_key, const uint8_t *passphrase, size_t passphrase_len, 284struct Tox_Pass_Key *tox_pass_key_derive_with_salt(const uint8_t *passphrase, size_t passphrase_len,
295 const uint8_t *salt, TOX_ERR_KEY_DERIVATION *error); 285 const uint8_t *salt, TOX_ERR_KEY_DERIVATION *error);
296 286
297/** 287/**
298 * Encrypt a plain text with a key produced by tox_pass_key_derive or tox_pass_key_derive_with_salt. 288 * Encrypt a plain text with a key produced by tox_pass_key_derive or tox_pass_key_derive_with_salt.