diff options
author | iphydf <iphydf@users.noreply.github.com> | 2016-12-16 03:00:55 +0000 |
---|---|---|
committer | iphydf <iphydf@users.noreply.github.com> | 2017-12-29 23:24:54 +0000 |
commit | d26f0eb3bcdd622cc8adae98974a27d7487fc6cb (patch) | |
tree | 5643926efde516051ee9fe9efa9e6f9b04ea0548 /toxencryptsave | |
parent | 2c8fb05f6e1631403053ef8648d5860e0ec15cc3 (diff) |
Change toxencryptsave API to never overwrite pass keys.
Diffstat (limited to 'toxencryptsave')
-rw-r--r-- | toxencryptsave/toxencryptsave.api.h | 20 | ||||
-rw-r--r-- | toxencryptsave/toxencryptsave.c | 47 | ||||
-rw-r--r-- | toxencryptsave/toxencryptsave.h | 24 |
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 | ||
74 | Tox_Pass_Key *tox_pass_key_new(void) | ||
75 | { | ||
76 | return (Tox_Pass_Key *)malloc(sizeof(Tox_Pass_Key)); | ||
77 | } | ||
78 | |||
79 | void tox_pass_key_free(Tox_Pass_Key *pass_key) | 74 | void 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 | */ |
126 | bool tox_pass_key_derive(Tox_Pass_Key *out_key, const uint8_t *passphrase, size_t pplength, | 121 | Tox_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 | */ |
137 | bool tox_pass_key_derive_with_salt(Tox_Pass_Key *out_key, const uint8_t *passphrase, size_t pplength, | 132 | Tox_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 | |||
224 | bool tox_pass_encrypt(const uint8_t *data, size_t data_len, const uint8_t *passphrase, size_t pplength, uint8_t *out, | 227 | bool 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 | */ | ||
259 | struct 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 | */ |
282 | bool tox_pass_key_derive(struct Tox_Pass_Key *_key, const uint8_t *passphrase, size_t passphrase_len, | 272 | struct 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 | */ |
294 | bool tox_pass_key_derive_with_salt(struct Tox_Pass_Key *_key, const uint8_t *passphrase, size_t passphrase_len, | 284 | struct 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. |