summaryrefslogtreecommitdiff
path: root/toxencryptsave/toxencryptsave.c
diff options
context:
space:
mode:
Diffstat (limited to 'toxencryptsave/toxencryptsave.c')
-rw-r--r--toxencryptsave/toxencryptsave.c80
1 files changed, 61 insertions, 19 deletions
diff --git a/toxencryptsave/toxencryptsave.c b/toxencryptsave/toxencryptsave.c
index a6a75b0d..19aa2a14 100644
--- a/toxencryptsave/toxencryptsave.c
+++ b/toxencryptsave/toxencryptsave.c
@@ -47,28 +47,70 @@
47#error TOX_PASS_ENCRYPTION_EXTRA_LENGTH is assumed to be equal to (crypto_box_MACBYTES + crypto_box_NONCEBYTES + crypto_pwhash_scryptsalsa208sha256_SALTBYTES + TOX_ENC_SAVE_MAGIC_LENGTH) 47#error TOX_PASS_ENCRYPTION_EXTRA_LENGTH is assumed to be equal to (crypto_box_MACBYTES + crypto_box_NONCEBYTES + crypto_pwhash_scryptsalsa208sha256_SALTBYTES + TOX_ENC_SAVE_MAGIC_LENGTH)
48#endif 48#endif
49 49
50struct Tox_Pass_Key {
51 uint8_t salt[TOX_PASS_SALT_LENGTH];
52 uint8_t key[TOX_PASS_KEY_LENGTH];
53};
54
55Tox_Pass_Key *tox_pass_key_new(void)
56{
57 return (Tox_Pass_Key *)malloc(sizeof(Tox_Pass_Key));
58}
59
60void tox_pass_key_free(Tox_Pass_Key *pass_key)
61{
62 free(pass_key);
63}
64
65void tox_pass_key_get_salt(const Tox_Pass_Key *pass_key, uint8_t *salt)
66{
67 memcpy(salt, pass_key->salt, TOX_PASS_SALT_LENGTH);
68}
69
70void tox_pass_key_set_salt(Tox_Pass_Key *pass_key, const uint8_t *salt)
71{
72 memcpy(pass_key->salt, salt, TOX_PASS_SALT_LENGTH);
73}
74
75void tox_pass_key_get_key(const Tox_Pass_Key *pass_key, uint8_t *key)
76{
77 memcpy(key, pass_key->key, TOX_PASS_KEY_LENGTH);
78}
79
80void tox_pass_key_set_key(Tox_Pass_Key *pass_key, const uint8_t *key)
81{
82 memcpy(pass_key->key, key, TOX_PASS_KEY_LENGTH);
83}
84
50/* Clients should consider alerting their users that, unlike plain data, if even one bit 85/* Clients should consider alerting their users that, unlike plain data, if even one bit
51 * becomes corrupted, the data will be entirely unrecoverable. 86 * becomes corrupted, the data will be entirely unrecoverable.
52 * Ditto if they forget their password, there is no way to recover the data. 87 * Ditto if they forget their password, there is no way to recover the data.
53 */ 88 */
54 89
55/* This retrieves the salt used to encrypt the given data, which can then be passed to 90/* This retrieves the salt used to encrypt the given data, which can then be passed to
56 * derive_key_with_salt to produce the same key as was previously used. Any encrpyted 91 * tox_pass_key_derive_with_salt to produce the same key as was previously used. Any encrpyted
57 * data with this module can be used as input. 92 * data with this module can be used as input.
58 * 93 *
59 * returns true if magic number matches 94 * returns true if magic number matches
60 * success does not say anything about the validity of the data, only that data of 95 * success does not say anything about the validity of the data, only that data of
61 * the appropriate size was copied 96 * the appropriate size was copied
62 */ 97 */
63bool tox_get_salt(const uint8_t *data, uint8_t *salt) 98bool tox_get_salt(const uint8_t *data, uint8_t *salt, TOX_ERR_GET_SALT *error)
64{ 99{
100 if (!data || !salt) {
101 SET_ERROR_PARAMETER(error, TOX_ERR_GET_SALT_NULL);
102 return false;
103 }
104
65 if (memcmp(data, TOX_ENC_SAVE_MAGIC_NUMBER, TOX_ENC_SAVE_MAGIC_LENGTH) != 0) { 105 if (memcmp(data, TOX_ENC_SAVE_MAGIC_NUMBER, TOX_ENC_SAVE_MAGIC_LENGTH) != 0) {
66 return 0; 106 SET_ERROR_PARAMETER(error, TOX_ERR_GET_SALT_BAD_FORMAT);
107 return false;
67 } 108 }
68 109
69 data += TOX_ENC_SAVE_MAGIC_LENGTH; 110 data += TOX_ENC_SAVE_MAGIC_LENGTH;
70 memcpy(salt, data, crypto_pwhash_scryptsalsa208sha256_SALTBYTES); 111 memcpy(salt, data, crypto_pwhash_scryptsalsa208sha256_SALTBYTES);
71 return 1; 112 SET_ERROR_PARAMETER(error, TOX_ERR_GET_SALT_OK);
113 return true;
72} 114}
73 115
74/* Generates a secret symmetric key from the given passphrase. out_key must be at least 116/* Generates a secret symmetric key from the given passphrase. out_key must be at least
@@ -82,19 +124,19 @@ bool tox_get_salt(const uint8_t *data, uint8_t *salt)
82 * 124 *
83 * returns true on success 125 * returns true on success
84 */ 126 */
85bool tox_derive_key_from_pass(const uint8_t *passphrase, size_t pplength, TOX_PASS_KEY *out_key, 127bool tox_pass_key_derive(Tox_Pass_Key *out_key, const uint8_t *passphrase, size_t pplength,
86 TOX_ERR_KEY_DERIVATION *error) 128 TOX_ERR_KEY_DERIVATION *error)
87{ 129{
88 uint8_t salt[crypto_pwhash_scryptsalsa208sha256_SALTBYTES]; 130 uint8_t salt[crypto_pwhash_scryptsalsa208sha256_SALTBYTES];
89 randombytes(salt, sizeof salt); 131 randombytes(salt, sizeof salt);
90 return tox_derive_key_with_salt(passphrase, pplength, salt, out_key, error); 132 return tox_pass_key_derive_with_salt(out_key, passphrase, pplength, salt, error);
91} 133}
92 134
93/* Same as above, except with use the given salt for deterministic key derivation. 135/* Same as above, except with use the given salt for deterministic key derivation.
94 * The salt must be TOX_PASS_SALT_LENGTH bytes in length. 136 * The salt must be TOX_PASS_SALT_LENGTH bytes in length.
95 */ 137 */
96bool tox_derive_key_with_salt(const uint8_t *passphrase, size_t pplength, const uint8_t *salt, TOX_PASS_KEY *out_key, 138bool tox_pass_key_derive_with_salt(Tox_Pass_Key *out_key, const uint8_t *passphrase, size_t pplength,
97 TOX_ERR_KEY_DERIVATION *error) 139 const uint8_t *salt, TOX_ERR_KEY_DERIVATION *error)
98{ 140{
99 if (!salt || !out_key || (!passphrase && pplength != 0)) { 141 if (!salt || !out_key || (!passphrase && pplength != 0)) {
100 SET_ERROR_PARAMETER(error, TOX_ERR_KEY_DERIVATION_NULL); 142 SET_ERROR_PARAMETER(error, TOX_ERR_KEY_DERIVATION_NULL);
@@ -134,7 +176,7 @@ bool tox_derive_key_with_salt(const uint8_t *passphrase, size_t pplength, const
134 * 176 *
135 * returns true on success 177 * returns true on success
136 */ 178 */
137bool tox_pass_key_encrypt(const uint8_t *data, size_t data_len, const TOX_PASS_KEY *key, uint8_t *out, 179bool tox_pass_key_encrypt(const Tox_Pass_Key *key, const uint8_t *data, size_t data_len, uint8_t *out,
138 TOX_ERR_ENCRYPTION *error) 180 TOX_ERR_ENCRYPTION *error)
139{ 181{
140 if (data_len == 0 || !data || !key || !out) { 182 if (data_len == 0 || !data || !key || !out) {
@@ -176,17 +218,17 @@ bool tox_pass_key_encrypt(const uint8_t *data, size_t data_len, const TOX_PASS_K
176 218
177/* Encrypts the given data with the given passphrase. The output array must be 219/* Encrypts the given data with the given passphrase. The output array must be
178 * at least data_len + TOX_PASS_ENCRYPTION_EXTRA_LENGTH bytes long. This delegates 220 * at least data_len + TOX_PASS_ENCRYPTION_EXTRA_LENGTH bytes long. This delegates
179 * to tox_derive_key_from_pass and tox_pass_key_encrypt. 221 * to tox_derive_key and tox_pass_key_encrypt.
180 * 222 *
181 * returns true on success 223 * returns true on success
182 */ 224 */
183bool tox_pass_encrypt(const uint8_t *data, size_t data_len, const uint8_t *passphrase, size_t pplength, uint8_t *out, 225bool tox_pass_encrypt(const uint8_t *data, size_t data_len, const uint8_t *passphrase, size_t pplength, uint8_t *out,
184 TOX_ERR_ENCRYPTION *error) 226 TOX_ERR_ENCRYPTION *error)
185{ 227{
186 TOX_PASS_KEY key; 228 Tox_Pass_Key key;
187 TOX_ERR_KEY_DERIVATION _error; 229 TOX_ERR_KEY_DERIVATION _error;
188 230
189 if (!tox_derive_key_from_pass(passphrase, pplength, &key, &_error)) { 231 if (!tox_pass_key_derive(&key, passphrase, pplength, &_error)) {
190 if (_error == TOX_ERR_KEY_DERIVATION_NULL) { 232 if (_error == TOX_ERR_KEY_DERIVATION_NULL) {
191 SET_ERROR_PARAMETER(error, TOX_ERR_ENCRYPTION_NULL); 233 SET_ERROR_PARAMETER(error, TOX_ERR_ENCRYPTION_NULL);
192 } else if (_error == TOX_ERR_KEY_DERIVATION_FAILED) { 234 } else if (_error == TOX_ERR_KEY_DERIVATION_FAILED) {
@@ -196,17 +238,17 @@ bool tox_pass_encrypt(const uint8_t *data, size_t data_len, const uint8_t *passp
196 return 0; 238 return 0;
197 } 239 }
198 240
199 return tox_pass_key_encrypt(data, data_len, &key, out, error); 241 return tox_pass_key_encrypt(&key, data, data_len, out, error);
200} 242}
201 243
202/* This is the inverse of tox_pass_key_encrypt, also using only keys produced by 244/* This is the inverse of tox_pass_key_encrypt, also using only keys produced by
203 * tox_derive_key_from_pass. 245 * tox_derive_key.
204 * 246 *
205 * the output data has size data_length - TOX_PASS_ENCRYPTION_EXTRA_LENGTH 247 * the output data has size data_length - TOX_PASS_ENCRYPTION_EXTRA_LENGTH
206 * 248 *
207 * returns true on success 249 * returns true on success
208 */ 250 */
209bool tox_pass_key_decrypt(const uint8_t *data, size_t length, const TOX_PASS_KEY *key, uint8_t *out, 251bool tox_pass_key_decrypt(const Tox_Pass_Key *key, const uint8_t *data, size_t length, uint8_t *out,
210 TOX_ERR_DECRYPTION *error) 252 TOX_ERR_DECRYPTION *error)
211{ 253{
212 if (length <= TOX_PASS_ENCRYPTION_EXTRA_LENGTH) { 254 if (length <= TOX_PASS_ENCRYPTION_EXTRA_LENGTH) {
@@ -274,15 +316,15 @@ bool tox_pass_decrypt(const uint8_t *data, size_t length, const uint8_t *passphr
274 memcpy(salt, data + TOX_ENC_SAVE_MAGIC_LENGTH, crypto_pwhash_scryptsalsa208sha256_SALTBYTES); 316 memcpy(salt, data + TOX_ENC_SAVE_MAGIC_LENGTH, crypto_pwhash_scryptsalsa208sha256_SALTBYTES);
275 317
276 /* derive the key */ 318 /* derive the key */
277 TOX_PASS_KEY key; 319 Tox_Pass_Key key;
278 320
279 if (!tox_derive_key_with_salt(passphrase, pplength, salt, &key, NULL)) { 321 if (!tox_pass_key_derive_with_salt(&key, passphrase, pplength, salt, NULL)) {
280 /* out of memory most likely */ 322 /* out of memory most likely */
281 SET_ERROR_PARAMETER(error, TOX_ERR_DECRYPTION_KEY_DERIVATION_FAILED); 323 SET_ERROR_PARAMETER(error, TOX_ERR_DECRYPTION_KEY_DERIVATION_FAILED);
282 return 0; 324 return 0;
283 } 325 }
284 326
285 return tox_pass_key_decrypt(data, length, &key, out, error); 327 return tox_pass_key_decrypt(&key, data, length, out, error);
286} 328}
287 329
288/* Determines whether or not the given data is encrypted (by checking the magic number) 330/* Determines whether or not the given data is encrypted (by checking the magic number)