summaryrefslogtreecommitdiff
path: root/toxencryptsave
diff options
context:
space:
mode:
authorDubslow <bunslow@gmail.com>2015-03-31 21:16:04 -0500
committerDubslow <bunslow@gmail.com>2015-03-31 21:16:04 -0500
commitf7beee495e9c3199ecbae91fde2e92f1698f48b2 (patch)
tree0ca72da3664401a854180bd976e943e4bfc5ea1b /toxencryptsave
parent9b66c57bd0ec8d7e89b7fa751d83ffabd1ce2e75 (diff)
Make keys into a struct for more programmer safety
Diffstat (limited to 'toxencryptsave')
-rw-r--r--toxencryptsave/toxencryptsave.c47
-rw-r--r--toxencryptsave/toxencryptsave.h18
2 files changed, 36 insertions, 29 deletions
diff --git a/toxencryptsave/toxencryptsave.c b/toxencryptsave/toxencryptsave.c
index c086ddb7..b38209a4 100644
--- a/toxencryptsave/toxencryptsave.c
+++ b/toxencryptsave/toxencryptsave.c
@@ -40,8 +40,8 @@
40#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
41#endif 41#endif
42 42
43#if TOX_PASS_KEY_LENGTH != (crypto_pwhash_scryptsalsa208sha256_SALTBYTES + crypto_box_KEYBYTES) 43#if TOX_PASS_KEY_LENGTH != crypto_box_KEYBYTES
44#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
45#endif 45#endif
46 46
47#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)
@@ -82,7 +82,7 @@ bool tox_get_salt(const uint8_t *data, uint8_t *salt)
82 * 82 *
83 * returns true on success 83 * returns true on success
84 */ 84 */
85bool 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, TOX_ERR_KEY_DERIVATION *error)
86{ 86{
87 uint8_t salt[crypto_pwhash_scryptsalsa208sha256_SALTBYTES]; 87 uint8_t salt[crypto_pwhash_scryptsalsa208sha256_SALTBYTES];
88 randombytes(salt, sizeof salt); 88 randombytes(salt, sizeof salt);
@@ -92,7 +92,7 @@ bool tox_derive_key_from_pass(uint8_t *passphrase, size_t pplength, uint8_t *out
92/* Same as above, except with use the given salt for deterministic key derivation. 92/* Same as above, except with use the given salt for deterministic key derivation.
93 * The salt must be TOX_PASS_SALT_LENGTH bytes in length. 93 * The salt must be TOX_PASS_SALT_LENGTH bytes in length.
94 */ 94 */
95bool tox_derive_key_with_salt(uint8_t *passphrase, size_t pplength, uint8_t *salt, uint8_t *out_key, 95bool tox_derive_key_with_salt(uint8_t *passphrase, size_t pplength, uint8_t *salt, TOX_PASS_KEY *out_key,
96 TOX_ERR_KEY_DERIVATION *error) 96 TOX_ERR_KEY_DERIVATION *error)
97{ 97{
98 if (pplength == 0 || !passphrase || !salt || !out_key) { 98 if (pplength == 0 || !passphrase || !salt || !out_key) {
@@ -119,8 +119,8 @@ bool tox_derive_key_with_salt(uint8_t *passphrase, size_t pplength, uint8_t *sal
119 } 119 }
120 120
121 sodium_memzero(passkey, crypto_hash_sha256_BYTES); /* wipe plaintext pw */ 121 sodium_memzero(passkey, crypto_hash_sha256_BYTES); /* wipe plaintext pw */
122 memcpy(out_key, salt, crypto_pwhash_scryptsalsa208sha256_SALTBYTES); 122 memcpy(out_key->salt, salt, crypto_pwhash_scryptsalsa208sha256_SALTBYTES);
123 memcpy(out_key + crypto_pwhash_scryptsalsa208sha256_SALTBYTES, key, crypto_box_KEYBYTES); 123 memcpy(out_key->key, key, crypto_box_KEYBYTES);
124 SET_ERROR_PARAMETER(error, TOX_ERR_KEY_DERIVATION_OK); 124 SET_ERROR_PARAMETER(error, TOX_ERR_KEY_DERIVATION_OK);
125 return 1; 125 return 1;
126} 126}
@@ -133,7 +133,7 @@ bool tox_derive_key_with_salt(uint8_t *passphrase, size_t pplength, uint8_t *sal
133 * 133 *
134 * returns true on success 134 * returns true on success
135 */ 135 */
136bool tox_pass_key_encrypt(const uint8_t *data, size_t data_len, const uint8_t *key, uint8_t *out, 136bool tox_pass_key_encrypt(const uint8_t *data, size_t data_len, const TOX_PASS_KEY *key, uint8_t *out,
137 TOX_ERR_ENCRYPTION *error) 137 TOX_ERR_ENCRYPTION *error)
138{ 138{
139 if (data_len == 0 || !data || !key || !out) { 139 if (data_len == 0 || !data || !key || !out) {
@@ -154,8 +154,7 @@ bool tox_pass_key_encrypt(const uint8_t *data, size_t data_len, const uint8_t *k
154 out += TOX_ENC_SAVE_MAGIC_LENGTH; 154 out += TOX_ENC_SAVE_MAGIC_LENGTH;
155 155
156 /* then add the rest prefix */ 156 /* then add the rest prefix */
157 memcpy(out, key, crypto_pwhash_scryptsalsa208sha256_SALTBYTES); 157 memcpy(out, key->salt, crypto_pwhash_scryptsalsa208sha256_SALTBYTES);
158 key += crypto_pwhash_scryptsalsa208sha256_SALTBYTES;
159 out += crypto_pwhash_scryptsalsa208sha256_SALTBYTES; 158 out += crypto_pwhash_scryptsalsa208sha256_SALTBYTES;
160 159
161 uint8_t nonce[crypto_box_NONCEBYTES]; 160 uint8_t nonce[crypto_box_NONCEBYTES];
@@ -164,7 +163,7 @@ bool tox_pass_key_encrypt(const uint8_t *data, size_t data_len, const uint8_t *k
164 out += crypto_box_NONCEBYTES; 163 out += crypto_box_NONCEBYTES;
165 164
166 /* now encrypt */ 165 /* now encrypt */
167 if (encrypt_data_symmetric(key, nonce, data, data_len, out) 166 if (encrypt_data_symmetric(key->key, nonce, data, data_len, out)
168 != data_len + crypto_box_MACBYTES) { 167 != data_len + crypto_box_MACBYTES) {
169 SET_ERROR_PARAMETER(error, TOX_ERR_ENCRYPTION_FAILED); 168 SET_ERROR_PARAMETER(error, TOX_ERR_ENCRYPTION_FAILED);
170 return 0; 169 return 0;
@@ -183,10 +182,10 @@ bool tox_pass_key_encrypt(const uint8_t *data, size_t data_len, const uint8_t *k
183bool tox_pass_encrypt(const uint8_t *data, size_t data_len, uint8_t *passphrase, size_t pplength, uint8_t *out, 182bool tox_pass_encrypt(const uint8_t *data, size_t data_len, uint8_t *passphrase, size_t pplength, uint8_t *out,
184 TOX_ERR_ENCRYPTION *error) 183 TOX_ERR_ENCRYPTION *error)
185{ 184{
186 uint8_t key[TOX_PASS_KEY_LENGTH]; 185 TOX_PASS_KEY key;
187 TOX_ERR_KEY_DERIVATION _error; 186 TOX_ERR_KEY_DERIVATION _error;
188 187
189 if (!tox_derive_key_from_pass(passphrase, pplength, key, &_error)) { 188 if (!tox_derive_key_from_pass(passphrase, pplength, &key, &_error)) {
190 if (_error == TOX_ERR_KEY_DERIVATION_NULL) { 189 if (_error == TOX_ERR_KEY_DERIVATION_NULL) {
191 SET_ERROR_PARAMETER(error, TOX_ERR_ENCRYPTION_NULL); 190 SET_ERROR_PARAMETER(error, TOX_ERR_ENCRYPTION_NULL);
192 } else if (_error == TOX_ERR_KEY_DERIVATION_FAILED) { 191 } else if (_error == TOX_ERR_KEY_DERIVATION_FAILED) {
@@ -196,7 +195,7 @@ bool tox_pass_encrypt(const uint8_t *data, size_t data_len, uint8_t *passphrase,
196 return 0; 195 return 0;
197 } 196 }
198 197
199 return tox_pass_key_encrypt(data, data_len, key, out, error); 198 return tox_pass_key_encrypt(data, data_len, &key, out, error);
200} 199}
201 200
202/* This is the inverse of tox_pass_key_encrypt, also using only keys produced by 201/* This is the inverse of tox_pass_key_encrypt, also using only keys produced by
@@ -206,33 +205,33 @@ bool tox_pass_encrypt(const uint8_t *data, size_t data_len, uint8_t *passphrase,
206 * 205 *
207 * returns true on success 206 * returns true on success
208 */ 207 */
209bool tox_pass_key_decrypt(const uint8_t *data, size_t length, const uint8_t *key, uint8_t *out, 208bool tox_pass_key_decrypt(const uint8_t *data, size_t length, const TOX_PASS_KEY *key, uint8_t *out,
210 TOX_ERR_DECRYPTION *error) 209 TOX_ERR_DECRYPTION *error)
211{ 210{
212 if (length <= TOX_PASS_ENCRYPTION_EXTRA_LENGTH) { 211 if (length <= TOX_PASS_ENCRYPTION_EXTRA_LENGTH) {
213 SET_ERROR_PARAMETER(error, TOX_ERR_DECRYPTION_INVALID_LENGTH); 212 SET_ERROR_PARAMETER(error, TOX_ERR_DECRYPTION_INVALID_LENGTH);
214 return 0; 213 return 0;
215 } 214 }
216 215 if (!data || !key || !out) {
216 SET_ERROR_PARAMETER(error, TOX_ERR_DECRYPTION_NULL);
217 return 0;
218 }
217 if (memcmp(data, TOX_ENC_SAVE_MAGIC_NUMBER, TOX_ENC_SAVE_MAGIC_LENGTH) != 0) { 219 if (memcmp(data, TOX_ENC_SAVE_MAGIC_NUMBER, TOX_ENC_SAVE_MAGIC_LENGTH) != 0) {
218 SET_ERROR_PARAMETER(error, TOX_ERR_DECRYPTION_BAD_FORMAT); 220 SET_ERROR_PARAMETER(error, TOX_ERR_DECRYPTION_BAD_FORMAT);
219 return 0; 221 return 0;
220 } 222 }
221 223
222 data += TOX_ENC_SAVE_MAGIC_LENGTH; 224 data += TOX_ENC_SAVE_MAGIC_LENGTH;
225 data += crypto_pwhash_scryptsalsa208sha256_SALTBYTES; // salt only affects key derivation
223 226
224 size_t decrypt_length = length - TOX_PASS_ENCRYPTION_EXTRA_LENGTH; 227 size_t decrypt_length = length - TOX_PASS_ENCRYPTION_EXTRA_LENGTH;
225 //uint8_t salt[crypto_pwhash_scryptsalsa208sha256_SALTBYTES];
226 uint8_t nonce[crypto_box_NONCEBYTES];
227 228
228 //memcpy(salt, data, crypto_pwhash_scryptsalsa208sha256_SALTBYTES); 229 uint8_t nonce[crypto_box_NONCEBYTES];
229 key += crypto_pwhash_scryptsalsa208sha256_SALTBYTES; // ignore the salt, which is only needed for kdf
230 data += crypto_pwhash_scryptsalsa208sha256_SALTBYTES;
231 memcpy(nonce, data, crypto_box_NONCEBYTES); 230 memcpy(nonce, data, crypto_box_NONCEBYTES);
232 data += crypto_box_NONCEBYTES; 231 data += crypto_box_NONCEBYTES;
233 232
234 /* decrypt the data */ 233 /* decrypt the data */
235 if (decrypt_data_symmetric(key, nonce, data, decrypt_length + crypto_box_MACBYTES, out) 234 if (decrypt_data_symmetric(key->key, nonce, data, decrypt_length + crypto_box_MACBYTES, out)
236 != decrypt_length) { 235 != decrypt_length) {
237 SET_ERROR_PARAMETER(error, TOX_ERR_DECRYPTION_FAILED); 236 SET_ERROR_PARAMETER(error, TOX_ERR_DECRYPTION_FAILED);
238 return 0; 237 return 0;
@@ -270,15 +269,15 @@ bool tox_pass_decrypt(const uint8_t *data, size_t length, uint8_t *passphrase, s
270 memcpy(salt, data + TOX_ENC_SAVE_MAGIC_LENGTH, crypto_pwhash_scryptsalsa208sha256_SALTBYTES); 269 memcpy(salt, data + TOX_ENC_SAVE_MAGIC_LENGTH, crypto_pwhash_scryptsalsa208sha256_SALTBYTES);
271 270
272 /* derive the key */ 271 /* derive the key */
273 uint8_t key[crypto_box_KEYBYTES + crypto_pwhash_scryptsalsa208sha256_SALTBYTES]; 272 TOX_PASS_KEY key;
274 273
275 if (!tox_derive_key_with_salt(passphrase, pplength, salt, key, NULL)) { 274 if (!tox_derive_key_with_salt(passphrase, pplength, salt, &key, NULL)) {
276 /* out of memory most likely */ 275 /* out of memory most likely */
277 SET_ERROR_PARAMETER(error, TOX_ERR_DECRYPTION_KEY_DERIVATION_FAILED); 276 SET_ERROR_PARAMETER(error, TOX_ERR_DECRYPTION_KEY_DERIVATION_FAILED);
278 return 0; 277 return 0;
279 } 278 }
280 279
281 return tox_pass_key_decrypt(data, length, key, out, error); 280 return tox_pass_key_decrypt(data, length, &key, out, error);
282} 281}
283 282
284/* Determines whether or not the given data is encrypted (by checking the magic number) 283/* 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 51f75c66..103cf874 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
@@ -155,6 +155,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. 155 * intensive than part one. The first 3 functions are for key handling.
156 */ 156 */
157 157
158/* This key structure's internals should not be used by any client program, even
159 * if they are straightforward here.
160 */
161typedef struct {
162 uint8_t salt[TOX_PASS_SALT_LENGTH];
163 uint8_t key[TOX_PASS_KEY_LENGTH];
164} TOX_PASS_KEY;
165
158/* Generates a secret symmetric key from the given passphrase. out_key must be at least 166/* Generates a secret symmetric key from the given passphrase. out_key must be at least
159 * TOX_PASS_KEY_LENGTH bytes long. 167 * TOX_PASS_KEY_LENGTH bytes long.
160 * Be sure to not compromise the key! Only keep it in memory, do not write to disk. 168 * Be sure to not compromise the key! Only keep it in memory, do not write to disk.
@@ -166,12 +174,12 @@ bool tox_pass_decrypt(const uint8_t *data, size_t length, uint8_t *passphrase, s
166 * 174 *
167 * returns true on success 175 * returns true on success
168 */ 176 */
169bool tox_derive_key_from_pass(uint8_t *passphrase, size_t pplength, uint8_t *out_key, TOX_ERR_KEY_DERIVATION *error); 177bool tox_derive_key_from_pass(uint8_t *passphrase, size_t pplength, TOX_PASS_KEY *out_key, TOX_ERR_KEY_DERIVATION *error);
170 178
171/* Same as above, except use the given salt for deterministic key derivation. 179/* Same as above, except use the given salt for deterministic key derivation.
172 * The salt must be TOX_PASS_SALT_LENGTH bytes in length. 180 * The salt must be TOX_PASS_SALT_LENGTH bytes in length.
173 */ 181 */
174bool tox_derive_key_with_salt(uint8_t *passphrase, size_t pplength, uint8_t *salt, uint8_t *out_key, 182bool 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); 183 TOX_ERR_KEY_DERIVATION *error);
176 184
177/* This retrieves the salt used to encrypt the given data, which can then be passed to 185/* This retrieves the salt used to encrypt the given data, which can then be passed to
@@ -194,7 +202,7 @@ bool tox_get_salt(const uint8_t *data, uint8_t *salt);
194 * 202 *
195 * returns true on success 203 * returns true on success
196 */ 204 */
197bool tox_pass_key_encrypt(const uint8_t *data, size_t data_len, const uint8_t *key, uint8_t *out, 205bool 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); 206 TOX_ERR_ENCRYPTION *error);
199 207
200/* This is the inverse of tox_pass_key_encrypt, also using only keys produced by 208/* This is the inverse of tox_pass_key_encrypt, also using only keys produced by
@@ -204,7 +212,7 @@ bool tox_pass_key_encrypt(const uint8_t *data, size_t data_len, const uint8_t *k
204 * 212 *
205 * returns true on success 213 * returns true on success
206 */ 214 */
207bool tox_pass_key_decrypt(const uint8_t *data, size_t length, const uint8_t *key, uint8_t *out, 215bool tox_pass_key_decrypt(const uint8_t *data, size_t length, const TOX_PASS_KEY *key, uint8_t *out,
208 TOX_ERR_DECRYPTION *error); 216 TOX_ERR_DECRYPTION *error);
209 217
210/* Determines whether or not the given data is encrypted (by checking the magic number) 218/* Determines whether or not the given data is encrypted (by checking the magic number)