diff options
Diffstat (limited to 'toxencryptsave/toxencryptsave.c')
-rw-r--r-- | toxencryptsave/toxencryptsave.c | 80 |
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 | ||
50 | struct Tox_Pass_Key { | ||
51 | uint8_t salt[TOX_PASS_SALT_LENGTH]; | ||
52 | uint8_t key[TOX_PASS_KEY_LENGTH]; | ||
53 | }; | ||
54 | |||
55 | Tox_Pass_Key *tox_pass_key_new(void) | ||
56 | { | ||
57 | return (Tox_Pass_Key *)malloc(sizeof(Tox_Pass_Key)); | ||
58 | } | ||
59 | |||
60 | void tox_pass_key_free(Tox_Pass_Key *pass_key) | ||
61 | { | ||
62 | free(pass_key); | ||
63 | } | ||
64 | |||
65 | void 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 | |||
70 | void 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 | |||
75 | void 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 | |||
80 | void 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 | */ |
63 | bool tox_get_salt(const uint8_t *data, uint8_t *salt) | 98 | bool 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 | */ |
85 | bool tox_derive_key_from_pass(const uint8_t *passphrase, size_t pplength, TOX_PASS_KEY *out_key, | 127 | bool 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 | */ |
96 | bool tox_derive_key_with_salt(const uint8_t *passphrase, size_t pplength, const uint8_t *salt, TOX_PASS_KEY *out_key, | 138 | bool 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 | */ |
137 | bool tox_pass_key_encrypt(const uint8_t *data, size_t data_len, const TOX_PASS_KEY *key, uint8_t *out, | 179 | bool 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 | */ |
183 | bool tox_pass_encrypt(const uint8_t *data, size_t data_len, const uint8_t *passphrase, size_t pplength, uint8_t *out, | 225 | bool 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 | */ |
209 | bool tox_pass_key_decrypt(const uint8_t *data, size_t length, const TOX_PASS_KEY *key, uint8_t *out, | 251 | bool 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) |