diff options
author | iphydf <iphydf@users.noreply.github.com> | 2016-12-10 11:21:22 +0000 |
---|---|---|
committer | iphydf <iphydf@users.noreply.github.com> | 2016-12-13 14:24:40 +0000 |
commit | 4cf69996cc16282b13615843febd68ff6355eb7d (patch) | |
tree | a25eabe891617be148a2de433fe1fe08759bea02 /toxencryptsave | |
parent | 3cfe5544b1cb01771b5a1f722311502127265d0b (diff) |
Add apidsl file for toxencryptsave.
This breaks the toxencryptsave API. It hides the Tox_Pass_Key struct
definition.
Diffstat (limited to 'toxencryptsave')
-rw-r--r-- | toxencryptsave/toxencryptsave.api.h | 322 | ||||
-rw-r--r-- | toxencryptsave/toxencryptsave.c | 80 | ||||
-rw-r--r-- | toxencryptsave/toxencryptsave.h | 367 |
3 files changed, 633 insertions, 136 deletions
diff --git a/toxencryptsave/toxencryptsave.api.h b/toxencryptsave/toxencryptsave.api.h new file mode 100644 index 00000000..20b8da06 --- /dev/null +++ b/toxencryptsave/toxencryptsave.api.h | |||
@@ -0,0 +1,322 @@ | |||
1 | %{ | ||
2 | /* toxencryptsave.h | ||
3 | * | ||
4 | * Batch encryption functions. | ||
5 | * | ||
6 | * Copyright (C) 2013-2016 Tox Developers. All Rights Reserved. | ||
7 | * | ||
8 | * This file is part of Tox. | ||
9 | * | ||
10 | * Tox is free software: you can redistribute it and/or modify | ||
11 | * it under the terms of the GNU General Public License as published by | ||
12 | * the Free Software Foundation, either version 3 of the License, or | ||
13 | * (at your option) any later version. | ||
14 | * | ||
15 | * Tox is distributed in the hope that it will be useful, | ||
16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
18 | * GNU General Public License for more details. | ||
19 | * | ||
20 | * You should have received a copy of the GNU General Public License | ||
21 | * along with Tox. If not, see <http://www.gnu.org/licenses/>. | ||
22 | * | ||
23 | */ | ||
24 | |||
25 | #ifndef TOXENCRYPTSAVE_H | ||
26 | #define TOXENCRYPTSAVE_H | ||
27 | |||
28 | #ifdef __cplusplus | ||
29 | extern "C" { | ||
30 | #endif | ||
31 | |||
32 | #include <stdbool.h> | ||
33 | #include <stddef.h> | ||
34 | #include <stdint.h> | ||
35 | %} | ||
36 | |||
37 | /******************************************************************************* | ||
38 | * | ||
39 | * This module is organized into two parts. | ||
40 | * | ||
41 | * 1. A simple API operating on plain text/cipher text data and a password to | ||
42 | * encrypt or decrypt it. | ||
43 | * 2. A more advanced API that splits key derivation and encryption into two | ||
44 | * separate function calls. | ||
45 | * | ||
46 | * The first part is implemented in terms of the second part and simply calls | ||
47 | * the separate functions in sequence. Since key derivation is very expensive | ||
48 | * compared to the actual encryption, clients that do a lot of crypto should | ||
49 | * prefer the advanced API and reuse pass-key objects. | ||
50 | * | ||
51 | * To use the second part, first derive an encryption key from a password with | ||
52 | * ${pass_Key.derive}, then use the derived key to encrypt the data. | ||
53 | * | ||
54 | * The encrypted data is prepended with a magic number, to aid validity | ||
55 | * checking (no guarantees are made of course). Any data to be decrypted must | ||
56 | * start with the magic number. | ||
57 | * | ||
58 | * Clients should consider alerting their users that, unlike plain data, if | ||
59 | * even one bit becomes corrupted, the data will be entirely unrecoverable. | ||
60 | * Ditto if they forget their password, there is no way to recover the data. | ||
61 | * | ||
62 | *******************************************************************************/ | ||
63 | |||
64 | class tox { | ||
65 | |||
66 | /** | ||
67 | * The size of the salt part of a pass-key. | ||
68 | */ | ||
69 | const PASS_SALT_LENGTH = 32; | ||
70 | /** | ||
71 | * The size of the key part of a pass-key. | ||
72 | */ | ||
73 | const PASS_KEY_LENGTH = 32; | ||
74 | /** | ||
75 | * The amount of additional data required to store any encrypted byte array. | ||
76 | * Encrypting an array of N bytes requires N + $PASS_ENCRYPTION_EXTRA_LENGTH | ||
77 | * bytes in the encrypted byte array. | ||
78 | */ | ||
79 | const PASS_ENCRYPTION_EXTRA_LENGTH = 80; | ||
80 | |||
81 | error for key_derivation { | ||
82 | NULL, | ||
83 | /** | ||
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 | ||
86 | * do not produce this error. | ||
87 | */ | ||
88 | FAILED, | ||
89 | } | ||
90 | |||
91 | error for encryption { | ||
92 | NULL, | ||
93 | /** | ||
94 | * The crypto lib was unable to derive a key from the given passphrase, | ||
95 | * which is usually a lack of memory issue. The functions accepting keys | ||
96 | * do not produce this error. | ||
97 | */ | ||
98 | KEY_DERIVATION_FAILED, | ||
99 | /** | ||
100 | * The encryption itself failed. | ||
101 | */ | ||
102 | FAILED, | ||
103 | } | ||
104 | |||
105 | error for decryption { | ||
106 | NULL, | ||
107 | /** | ||
108 | * The input data was shorter than $PASS_ENCRYPTION_EXTRA_LENGTH bytes | ||
109 | */ | ||
110 | INVALID_LENGTH, | ||
111 | /** | ||
112 | * The input data is missing the magic number (i.e. wasn't created by this | ||
113 | * module, or is corrupted). | ||
114 | */ | ||
115 | BAD_FORMAT, | ||
116 | /** | ||
117 | * The crypto lib was unable to derive a key from the given passphrase, | ||
118 | * which is usually a lack of memory issue. The functions accepting keys | ||
119 | * do not produce this error. | ||
120 | */ | ||
121 | KEY_DERIVATION_FAILED, | ||
122 | /** | ||
123 | * The encrypted byte array could not be decrypted. Either the data was | ||
124 | * corrupted or the password/key was incorrect. | ||
125 | */ | ||
126 | FAILED, | ||
127 | } | ||
128 | |||
129 | |||
130 | /******************************************************************************* | ||
131 | * | ||
132 | * BEGIN PART 1 | ||
133 | * | ||
134 | * The simple API is presented first. If your code spends too much time using | ||
135 | * these functions, consider using the advanced functions instead and caching | ||
136 | * the generated pass-key. | ||
137 | * | ||
138 | *******************************************************************************/ | ||
139 | |||
140 | /** | ||
141 | * Encrypts the given data with the given passphrase. | ||
142 | * | ||
143 | * The output array must be at least `plaintext_len + $PASS_ENCRYPTION_EXTRA_LENGTH` | ||
144 | * bytes long. This delegates to ${pass_Key.derive} and | ||
145 | * ${pass_Key.encrypt}. | ||
146 | * | ||
147 | * @param plaintext A byte array of length `plaintext_len`. | ||
148 | * @param plaintext_len The length of the plain text array. May be 0. | ||
149 | * @param passphrase The user-provided password. | ||
150 | * @param passphrase_len The length of the password. | ||
151 | * @param ciphertext The cipher text array to write the encrypted data to. | ||
152 | * | ||
153 | * @return true on success. | ||
154 | */ | ||
155 | static bool pass_encrypt(const uint8_t[plaintext_len] plaintext, const uint8_t[passphrase_len] passphrase, uint8_t *ciphertext) | ||
156 | with error for encryption; | ||
157 | |||
158 | |||
159 | /** | ||
160 | * Decrypts the given data with the given passphrase. | ||
161 | * | ||
162 | * The output array must be at least `ciphertext_len - $PASS_ENCRYPTION_EXTRA_LENGTH` | ||
163 | * bytes long. This delegates to ${pass_Key.decrypt}. | ||
164 | * | ||
165 | * @param ciphertext A byte array of length `ciphertext_len`. | ||
166 | * @param ciphertext_len The length of the cipher text array. May be 0. | ||
167 | * @param passphrase The user-provided password. | ||
168 | * @param passphrase_len The length of the password. | ||
169 | * @param plaintext The plain text array to write the decrypted data to. | ||
170 | * | ||
171 | * @return true on success. | ||
172 | */ | ||
173 | static bool pass_decrypt(const uint8_t[ciphertext_len] ciphertext, const uint8_t[passphrase_len] passphrase, uint8_t *plaintext) | ||
174 | with error for decryption; | ||
175 | |||
176 | |||
177 | /******************************************************************************* | ||
178 | * | ||
179 | * BEGIN PART 2 | ||
180 | * | ||
181 | * And now part 2, which does the actual encryption, and can be used to write | ||
182 | * less CPU intensive client code than part one. | ||
183 | * | ||
184 | *******************************************************************************/ | ||
185 | |||
186 | class pass_Key { | ||
187 | /** | ||
188 | * This type represents a pass-key. | ||
189 | * | ||
190 | * A pass-key and a password are two different concepts: a password is given | ||
191 | * by the user in plain text. A pass-key is the generated symmetric key used | ||
192 | * for encryption and decryption. It is derived from a salt and the user- | ||
193 | * provided password. | ||
194 | * | ||
195 | * The $this structure is hidden in the implementation. It can be allocated | ||
196 | * using $new and must be deallocated using $free. | ||
197 | */ | ||
198 | struct this; | ||
199 | |||
200 | /** | ||
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 | static this new(); | ||
205 | |||
206 | /** | ||
207 | * Deallocate a $this. This function behaves like free(), so NULL is an | ||
208 | * acceptable argument value. | ||
209 | */ | ||
210 | void free(); | ||
211 | |||
212 | /** | ||
213 | * Generates a secret symmetric key from the given passphrase. | ||
214 | * | ||
215 | * Be sure to not compromise the key! Only keep it in memory, do not write | ||
216 | * it to disk. | ||
217 | * | ||
218 | * Note that this function is not deterministic; to derive the same key from | ||
219 | * a password, you also must know the random salt that was used. A | ||
220 | * deterministic version of this function is $derive_with_salt. | ||
221 | * | ||
222 | * @param passphrase The user-provided password. | ||
223 | * @param passphrase_len The length of the password. | ||
224 | * | ||
225 | * @return true on success. | ||
226 | */ | ||
227 | bool derive(const uint8_t[passphrase_len] passphrase) | ||
228 | with error for key_derivation; | ||
229 | |||
230 | /** | ||
231 | * Same as above, except use the given salt for deterministic key derivation. | ||
232 | * | ||
233 | * @param passphrase The user-provided password. | ||
234 | * @param passphrase_len The length of the password. | ||
235 | * @param salt An array of at least $PASS_SALT_LENGTH bytes. | ||
236 | * | ||
237 | * @return true on success. | ||
238 | */ | ||
239 | bool derive_with_salt(const uint8_t[passphrase_len] passphrase, const uint8_t[PASS_SALT_LENGTH] salt) | ||
240 | with error for key_derivation; | ||
241 | |||
242 | /** | ||
243 | * Encrypt a plain text with a key produced by $derive or $derive_with_salt. | ||
244 | * | ||
245 | * The output array must be at least `plaintext_len + $PASS_ENCRYPTION_EXTRA_LENGTH` | ||
246 | * bytes long. | ||
247 | * | ||
248 | * @param plaintext A byte array of length `plaintext_len`. | ||
249 | * @param plaintext_len The length of the plain text array. May be 0. | ||
250 | * @param ciphertext The cipher text array to write the encrypted data to. | ||
251 | * | ||
252 | * @return true on success. | ||
253 | */ | ||
254 | const bool encrypt(const uint8_t[plaintext_len] plaintext, uint8_t *ciphertext) | ||
255 | with error for encryption; | ||
256 | |||
257 | /** | ||
258 | * This is the inverse of $encrypt, also using only keys produced by | ||
259 | * $derive or $derive_with_salt. | ||
260 | * | ||
261 | * @param ciphertext A byte array of length `ciphertext_len`. | ||
262 | * @param ciphertext_len The length of the cipher text array. May be 0. | ||
263 | * @param plaintext The plain text array to write the decrypted data to. | ||
264 | * | ||
265 | * @return true on success. | ||
266 | */ | ||
267 | const bool decrypt(const uint8_t[ciphertext_len] ciphertext, uint8_t *plaintext) | ||
268 | with error for decryption; | ||
269 | } | ||
270 | |||
271 | /** | ||
272 | * Retrieves the salt used to encrypt the given data. | ||
273 | * | ||
274 | * The retrieved salt can then be passed to ${pass_Key.derive_with_salt} to | ||
275 | * produce the same key as was previously used. Any data encrypted with this | ||
276 | * module can be used as input. | ||
277 | * | ||
278 | * The cipher text must be at least $PASS_ENCRYPTION_EXTRA_LENGTH bytes in length. | ||
279 | * The salt must be $PASS_SALT_LENGTH bytes in length. | ||
280 | * If the passed byte arrays are smaller than required, the behaviour is | ||
281 | * undefined. | ||
282 | * | ||
283 | * Success does not say anything about the validity of the data, only that | ||
284 | * data of the appropriate size was copied. | ||
285 | * | ||
286 | * @return true on success. | ||
287 | */ | ||
288 | static bool get_salt(const uint8_t *ciphertext, uint8_t[PASS_SALT_LENGTH] salt) { | ||
289 | NULL, | ||
290 | /** | ||
291 | * The input data is missing the magic number (i.e. wasn't created by this | ||
292 | * module, or is corrupted). | ||
293 | */ | ||
294 | BAD_FORMAT, | ||
295 | } | ||
296 | |||
297 | /** | ||
298 | * Determines whether or not the given data is encrypted by this module. | ||
299 | * | ||
300 | * It does this check by verifying that the magic number is the one put in | ||
301 | * place by the encryption functions. | ||
302 | * | ||
303 | * The data must be at least $PASS_ENCRYPTION_EXTRA_LENGTH bytes in length. | ||
304 | * If the passed byte array is smaller than required, the behaviour is | ||
305 | * undefined. | ||
306 | * | ||
307 | * If the cipher text pointer is NULL, this function returns false. | ||
308 | * | ||
309 | * @return true if the data is encrypted by this module. | ||
310 | */ | ||
311 | static bool is_data_encrypted(const uint8_t *data); | ||
312 | |||
313 | } | ||
314 | |||
315 | %{ | ||
316 | |||
317 | #ifdef __cplusplus | ||
318 | } | ||
319 | #endif | ||
320 | |||
321 | #endif | ||
322 | %} | ||
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) |
diff --git a/toxencryptsave/toxencryptsave.h b/toxencryptsave/toxencryptsave.h index 5b2eea75..584efaed 100644 --- a/toxencryptsave/toxencryptsave.h +++ b/toxencryptsave/toxencryptsave.h | |||
@@ -1,8 +1,8 @@ | |||
1 | /* toxencryptsave.h | 1 | /* toxencryptsave.h |
2 | * | 2 | * |
3 | * The Tox encrypted save functions. | 3 | * Batch encryption functions. |
4 | * | 4 | * |
5 | * Copyright (C) 2013 Tox project All Rights Reserved. | 5 | * Copyright (C) 2013-2016 Tox Developers. All Rights Reserved. |
6 | * | 6 | * |
7 | * This file is part of Tox. | 7 | * This file is part of Tox. |
8 | * | 8 | * |
@@ -32,217 +32,350 @@ extern "C" { | |||
32 | #include <stddef.h> | 32 | #include <stddef.h> |
33 | #include <stdint.h> | 33 | #include <stdint.h> |
34 | 34 | ||
35 | #ifndef TOX_DEFINED | ||
36 | #define TOX_DEFINED | ||
37 | typedef struct Tox Tox; | ||
38 | struct Tox_Options; | ||
39 | #endif | ||
40 | 35 | ||
41 | #define TOX_PASS_SALT_LENGTH 32 | 36 | /******************************************************************************* |
42 | #define TOX_PASS_KEY_LENGTH 32 | 37 | * |
43 | #define TOX_PASS_ENCRYPTION_EXTRA_LENGTH 80 | 38 | * This module is organized into two parts. |
39 | * | ||
40 | * 1. A simple API operating on plain text/cipher text data and a password to | ||
41 | * encrypt or decrypt it. | ||
42 | * 2. A more advanced API that splits key derivation and encryption into two | ||
43 | * separate function calls. | ||
44 | * | ||
45 | * The first part is implemented in terms of the second part and simply calls | ||
46 | * the separate functions in sequence. Since key derivation is very expensive | ||
47 | * compared to the actual encryption, clients that do a lot of crypto should | ||
48 | * prefer the advanced API and reuse pass-key objects. | ||
49 | * | ||
50 | * To use the second part, first derive an encryption key from a password with | ||
51 | * <unresolved>, then use the derived key to encrypt the data. | ||
52 | * | ||
53 | * The encrypted data is prepended with a magic number, to aid validity | ||
54 | * checking (no guarantees are made of course). Any data to be decrypted must | ||
55 | * start with the magic number. | ||
56 | * | ||
57 | * Clients should consider alerting their users that, unlike plain data, if | ||
58 | * even one bit becomes corrupted, the data will be entirely unrecoverable. | ||
59 | * Ditto if they forget their password, there is no way to recover the data. | ||
60 | * | ||
61 | ******************************************************************************/ | ||
62 | |||
63 | |||
44 | 64 | ||
45 | /** | 65 | /** |
46 | * ToxEncryptSave. | 66 | * The size of the salt part of a pass-key. |
47 | */ | 67 | */ |
48 | #ifndef TOXES_DEFINED | 68 | #define TOX_PASS_SALT_LENGTH 32 |
49 | #define TOXES_DEFINED | 69 | |
50 | #endif /* TOXES_DEFINED */ | 70 | uint32_t tox_pass_salt_length(void); |
51 | 71 | ||
52 | /* This module is conceptually organized into two parts. The first part are the functions | 72 | /** |
53 | * with "key" in the name. To use these functions, first derive an encryption key | 73 | * The size of the key part of a pass-key. |
54 | * from a password with tox_derive_key_from_pass, and use the returned key to | ||
55 | * encrypt the data. The second part takes the password itself instead of the key, | ||
56 | * and then delegates to the first part to derive the key before de/encryption, | ||
57 | * which can simplify client code; however, key derivation is very expensive | ||
58 | * compared to the actual encryption, so clients that do a lot of encryption should | ||
59 | * favor using the first part intead of the second part. | ||
60 | * | ||
61 | * The encrypted data is prepended with a magic number, to aid validity checking | ||
62 | * (no guarantees are made of course). Any data to be decrypted must start with | ||
63 | * the magic number. | ||
64 | * | ||
65 | * Clients should consider alerting their users that, unlike plain data, if even one bit | ||
66 | * becomes corrupted, the data will be entirely unrecoverable. | ||
67 | * Ditto if they forget their password, there is no way to recover the data. | ||
68 | */ | 74 | */ |
75 | #define TOX_PASS_KEY_LENGTH 32 | ||
76 | |||
77 | uint32_t tox_pass_key_length(void); | ||
69 | 78 | ||
70 | /* Since apparently no one actually bothered to learn about the module previously, | 79 | /** |
71 | * the recently removed functions tox_encrypted_new and tox_get_encrypted_savedata | 80 | * The amount of additional data required to store any encrypted byte array. |
72 | * may be trivially replaced by calls to tox_pass_decrypt -> tox_new or | 81 | * Encrypting an array of N bytes requires N + TOX_PASS_ENCRYPTION_EXTRA_LENGTH |
73 | * tox_get_savedata -> tox_pass_encrypt as appropriate. The removed functions | 82 | * bytes in the encrypted byte array. |
74 | * were never more than 5 line wrappers of the other public API functions anyways. | ||
75 | * (As has always been, tox_pass_decrypt and tox_pass_encrypt are interchangeable | ||
76 | * with tox_pass_key_decrypt and tox_pass_key_encrypt, as the client program requires.) | ||
77 | */ | 83 | */ |
84 | #define TOX_PASS_ENCRYPTION_EXTRA_LENGTH 80 | ||
85 | |||
86 | uint32_t tox_pass_encryption_extra_length(void); | ||
78 | 87 | ||
79 | typedef enum TOX_ERR_KEY_DERIVATION { | 88 | typedef enum TOX_ERR_KEY_DERIVATION { |
89 | |||
90 | /** | ||
91 | * The function returned successfully. | ||
92 | */ | ||
80 | TOX_ERR_KEY_DERIVATION_OK, | 93 | TOX_ERR_KEY_DERIVATION_OK, |
94 | |||
81 | /** | 95 | /** |
82 | * Some input data, or maybe the output pointer, was null. | 96 | * One of the arguments to the function was NULL when it was not expected. |
83 | */ | 97 | */ |
84 | TOX_ERR_KEY_DERIVATION_NULL, | 98 | TOX_ERR_KEY_DERIVATION_NULL, |
99 | |||
85 | /** | 100 | /** |
86 | * 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, |
87 | * which is usually a lack of memory issue. The functions accepting keys | 102 | * which is usually a lack of memory issue. The functions accepting keys |
88 | * do not produce this error. | 103 | * do not produce this error. |
89 | */ | 104 | */ |
90 | TOX_ERR_KEY_DERIVATION_FAILED | 105 | TOX_ERR_KEY_DERIVATION_FAILED, |
106 | |||
91 | } TOX_ERR_KEY_DERIVATION; | 107 | } TOX_ERR_KEY_DERIVATION; |
92 | 108 | ||
109 | |||
93 | typedef enum TOX_ERR_ENCRYPTION { | 110 | typedef enum TOX_ERR_ENCRYPTION { |
111 | |||
112 | /** | ||
113 | * The function returned successfully. | ||
114 | */ | ||
94 | TOX_ERR_ENCRYPTION_OK, | 115 | TOX_ERR_ENCRYPTION_OK, |
116 | |||
95 | /** | 117 | /** |
96 | * Some input data, or maybe the output pointer, was null. | 118 | * One of the arguments to the function was NULL when it was not expected. |
97 | */ | 119 | */ |
98 | TOX_ERR_ENCRYPTION_NULL, | 120 | TOX_ERR_ENCRYPTION_NULL, |
121 | |||
99 | /** | 122 | /** |
100 | * The crypto lib was unable to derive a key from the given passphrase, | 123 | * The crypto lib was unable to derive a key from the given passphrase, |
101 | * which is usually a lack of memory issue. The functions accepting keys | 124 | * which is usually a lack of memory issue. The functions accepting keys |
102 | * do not produce this error. | 125 | * do not produce this error. |
103 | */ | 126 | */ |
104 | TOX_ERR_ENCRYPTION_KEY_DERIVATION_FAILED, | 127 | TOX_ERR_ENCRYPTION_KEY_DERIVATION_FAILED, |
128 | |||
105 | /** | 129 | /** |
106 | * The encryption itself failed. | 130 | * The encryption itself failed. |
107 | */ | 131 | */ |
108 | TOX_ERR_ENCRYPTION_FAILED | 132 | TOX_ERR_ENCRYPTION_FAILED, |
133 | |||
109 | } TOX_ERR_ENCRYPTION; | 134 | } TOX_ERR_ENCRYPTION; |
110 | 135 | ||
136 | |||
111 | typedef enum TOX_ERR_DECRYPTION { | 137 | typedef enum TOX_ERR_DECRYPTION { |
138 | |||
139 | /** | ||
140 | * The function returned successfully. | ||
141 | */ | ||
112 | TOX_ERR_DECRYPTION_OK, | 142 | TOX_ERR_DECRYPTION_OK, |
143 | |||
113 | /** | 144 | /** |
114 | * Some input data, or maybe the output pointer, was null. | 145 | * One of the arguments to the function was NULL when it was not expected. |
115 | */ | 146 | */ |
116 | TOX_ERR_DECRYPTION_NULL, | 147 | TOX_ERR_DECRYPTION_NULL, |
148 | |||
117 | /** | 149 | /** |
118 | * The input data was shorter than TOX_PASS_ENCRYPTION_EXTRA_LENGTH bytes | 150 | * The input data was shorter than TOX_PASS_ENCRYPTION_EXTRA_LENGTH bytes |
119 | */ | 151 | */ |
120 | TOX_ERR_DECRYPTION_INVALID_LENGTH, | 152 | TOX_ERR_DECRYPTION_INVALID_LENGTH, |
153 | |||
121 | /** | 154 | /** |
122 | * The input data is missing the magic number (i.e. wasn't created by this | 155 | * The input data is missing the magic number (i.e. wasn't created by this |
123 | * module, or is corrupted) | 156 | * module, or is corrupted). |
124 | */ | 157 | */ |
125 | TOX_ERR_DECRYPTION_BAD_FORMAT, | 158 | TOX_ERR_DECRYPTION_BAD_FORMAT, |
159 | |||
126 | /** | 160 | /** |
127 | * The crypto lib was unable to derive a key from the given passphrase, | 161 | * The crypto lib was unable to derive a key from the given passphrase, |
128 | * which is usually a lack of memory issue. The functions accepting keys | 162 | * which is usually a lack of memory issue. The functions accepting keys |
129 | * do not produce this error. | 163 | * do not produce this error. |
130 | */ | 164 | */ |
131 | TOX_ERR_DECRYPTION_KEY_DERIVATION_FAILED, | 165 | TOX_ERR_DECRYPTION_KEY_DERIVATION_FAILED, |
166 | |||
132 | /** | 167 | /** |
133 | * The encrypted byte array could not be decrypted. Either the data was | 168 | * The encrypted byte array could not be decrypted. Either the data was |
134 | * corrupt or the password/key was incorrect. | 169 | * corrupted or the password/key was incorrect. |
135 | */ | 170 | */ |
136 | TOX_ERR_DECRYPTION_FAILED | 171 | TOX_ERR_DECRYPTION_FAILED, |
172 | |||
137 | } TOX_ERR_DECRYPTION; | 173 | } TOX_ERR_DECRYPTION; |
138 | 174 | ||
139 | 175 | ||
140 | /******************************* BEGIN PART 2 ******************************* | 176 | |
141 | * For simplicty, the second part of the module is presented first. The API for | 177 | /******************************************************************************* |
142 | * the first part is analgous, with some extra functions for key handling. If | 178 | * |
143 | * your code spends too much time using these functions, consider using the part | 179 | * BEGIN PART 1 |
144 | * 1 functions instead. | 180 | * |
181 | * The simple API is presented first. If your code spends too much time using | ||
182 | * these functions, consider using the advanced functions instead and caching | ||
183 | * the generated pass-key. | ||
184 | * | ||
185 | ******************************************************************************/ | ||
186 | |||
187 | |||
188 | |||
189 | /** | ||
190 | * Encrypts the given data with the given passphrase. | ||
191 | * | ||
192 | * The output array must be at least `plaintext_len + TOX_PASS_ENCRYPTION_EXTRA_LENGTH` | ||
193 | * bytes long. This delegates to tox_pass_key_derive and | ||
194 | * tox_pass_key_encrypt. | ||
195 | * | ||
196 | * @param plaintext A byte array of length `plaintext_len`. | ||
197 | * @param plaintext_len The length of the plain text array. May be 0. | ||
198 | * @param passphrase The user-provided password. | ||
199 | * @param passphrase_len The length of the password. | ||
200 | * @param ciphertext The cipher text array to write the encrypted data to. | ||
201 | * | ||
202 | * @return true on success. | ||
145 | */ | 203 | */ |
204 | bool tox_pass_encrypt(const uint8_t *plaintext, size_t plaintext_len, const uint8_t *passphrase, size_t passphrase_len, | ||
205 | uint8_t *ciphertext, TOX_ERR_ENCRYPTION *error); | ||
146 | 206 | ||
147 | /* Encrypts the given data with the given passphrase. The output array must be | 207 | /** |
148 | * at least data_len + TOX_PASS_ENCRYPTION_EXTRA_LENGTH bytes long. This delegates | 208 | * Decrypts the given data with the given passphrase. |
149 | * to tox_derive_key_from_pass and tox_pass_key_encrypt. | ||
150 | * | 209 | * |
151 | * returns true on success | 210 | * The output array must be at least `ciphertext_len - TOX_PASS_ENCRYPTION_EXTRA_LENGTH` |
211 | * bytes long. This delegates to tox_pass_key_decrypt. | ||
212 | * | ||
213 | * @param ciphertext A byte array of length `ciphertext_len`. | ||
214 | * @param ciphertext_len The length of the cipher text array. May be 0. | ||
215 | * @param passphrase The user-provided password. | ||
216 | * @param passphrase_len The length of the password. | ||
217 | * @param plaintext The plain text array to write the decrypted data to. | ||
218 | * | ||
219 | * @return true on success. | ||
152 | */ | 220 | */ |
153 | bool tox_pass_encrypt(const uint8_t *data, size_t data_len, const uint8_t *passphrase, size_t pplength, uint8_t *out, | 221 | bool tox_pass_decrypt(const uint8_t *ciphertext, size_t ciphertext_len, const uint8_t *passphrase, |
154 | TOX_ERR_ENCRYPTION *error); | 222 | size_t passphrase_len, uint8_t *plaintext, TOX_ERR_DECRYPTION *error); |
155 | 223 | ||
156 | 224 | ||
157 | /* Decrypts the given data with the given passphrase. The output array must be | 225 | /******************************************************************************* |
158 | * at least data_len - TOX_PASS_ENCRYPTION_EXTRA_LENGTH bytes long. This delegates | ||
159 | * to tox_pass_key_decrypt. | ||
160 | * | 226 | * |
161 | * the output data has size data_length - TOX_PASS_ENCRYPTION_EXTRA_LENGTH | 227 | * BEGIN PART 2 |
162 | * | 228 | * |
163 | * returns true on success | 229 | * And now part 2, which does the actual encryption, and can be used to write |
164 | */ | 230 | * less CPU intensive client code than part one. |
165 | bool tox_pass_decrypt(const uint8_t *data, size_t length, const uint8_t *passphrase, size_t pplength, uint8_t *out, | 231 | * |
166 | TOX_ERR_DECRYPTION *error); | 232 | ******************************************************************************/ |
233 | |||
167 | 234 | ||
168 | 235 | ||
169 | /******************************* BEGIN PART 1 ******************************* | 236 | /** |
170 | * And now part "1", which does the actual encryption, and is rather less cpu | 237 | * This type represents a pass-key. |
171 | * intensive than part one. The first 3 functions are for key handling. | 238 | * |
239 | * A pass-key and a password are two different concepts: a password is given | ||
240 | * by the user in plain text. A pass-key is the generated symmetric key used | ||
241 | * for encryption and decryption. It is derived from a salt and the user- | ||
242 | * provided password. | ||
243 | * | ||
244 | * The Tox_Pass_Key structure is hidden in the implementation. It can be allocated | ||
245 | * using tox_pass_key_new and must be deallocated using tox_pass_key_free. | ||
172 | */ | 246 | */ |
247 | #ifndef TOX_PASS_KEY_DEFINED | ||
248 | #define TOX_PASS_KEY_DEFINED | ||
249 | typedef struct Tox_Pass_Key Tox_Pass_Key; | ||
250 | #endif /* TOX_PASS_KEY_DEFINED */ | ||
173 | 251 | ||
174 | /* This key structure's internals should not be used by any client program, even | 252 | /** |
175 | * if they are straightforward here. | 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. | ||
176 | */ | 255 | */ |
177 | typedef struct { | 256 | struct Tox_Pass_Key *tox_pass_key_new(void); |
178 | uint8_t salt[TOX_PASS_SALT_LENGTH]; | 257 | |
179 | uint8_t key[TOX_PASS_KEY_LENGTH]; | 258 | /** |
180 | } TOX_PASS_KEY; | 259 | * Deallocate a Tox_Pass_Key. This function behaves like free(), so NULL is an |
181 | 260 | * acceptable argument value. | |
182 | /* Generates a secret symmetric key from the given passphrase. out_key must be at least | ||
183 | * TOX_PASS_KEY_LENGTH bytes long. | ||
184 | * Be sure to not compromise the key! Only keep it in memory, do not write to disk. | ||
185 | * The password is zeroed after key derivation. | ||
186 | * The key should only be used with the other functions in this module, as it | ||
187 | * includes a salt. | ||
188 | * Note that this function is not deterministic; to derive the same key from a | ||
189 | * password, you also must know the random salt that was used. See below. | ||
190 | * | ||
191 | * returns true on success | ||
192 | */ | 261 | */ |
193 | bool tox_derive_key_from_pass(const uint8_t *passphrase, size_t pplength, TOX_PASS_KEY *out_key, | 262 | void tox_pass_key_free(struct Tox_Pass_Key *_key); |
194 | TOX_ERR_KEY_DERIVATION *error); | ||
195 | 263 | ||
196 | /* Same as above, except use the given salt for deterministic key derivation. | 264 | /** |
197 | * The salt must be TOX_PASS_SALT_LENGTH bytes in length. | 265 | * Generates a secret symmetric key from the given passphrase. |
266 | * | ||
267 | * Be sure to not compromise the key! Only keep it in memory, do not write | ||
268 | * it to disk. | ||
269 | * | ||
270 | * Note that this function is not deterministic; to derive the same key from | ||
271 | * a password, you also must know the random salt that was used. A | ||
272 | * deterministic version of this function is tox_pass_key_derive_with_salt. | ||
273 | * | ||
274 | * @param passphrase The user-provided password. | ||
275 | * @param passphrase_len The length of the password. | ||
276 | * | ||
277 | * @return true on success. | ||
198 | */ | 278 | */ |
199 | bool tox_derive_key_with_salt(const uint8_t *passphrase, size_t pplength, const uint8_t *salt, TOX_PASS_KEY *out_key, | 279 | bool tox_pass_key_derive(struct Tox_Pass_Key *_key, const uint8_t *passphrase, size_t passphrase_len, |
200 | TOX_ERR_KEY_DERIVATION *error); | 280 | TOX_ERR_KEY_DERIVATION *error); |
201 | 281 | ||
202 | /* This retrieves the salt used to encrypt the given data, which can then be passed to | 282 | /** |
203 | * derive_key_with_salt to produce the same key as was previously used. Any encrpyted | 283 | * Same as above, except use the given salt for deterministic key derivation. |
204 | * data with this module can be used as input. | ||
205 | * | 284 | * |
206 | * The data must be at least TOX_PASS_ENCRYPTION_EXTRA_LENGTH bytes in length. | 285 | * @param passphrase The user-provided password. |
207 | * The salt must be TOX_PASS_SALT_LENGTH bytes in length. | 286 | * @param passphrase_len The length of the password. |
287 | * @param salt An array of at least TOX_PASS_SALT_LENGTH bytes. | ||
208 | * | 288 | * |
209 | * returns true if magic number matches | 289 | * @return true on success. |
210 | * success does not say anything about the validity of the data, only that data of | ||
211 | * the appropriate size was copied | ||
212 | */ | 290 | */ |
213 | bool tox_get_salt(const uint8_t *data, uint8_t *salt); | 291 | bool tox_pass_key_derive_with_salt(struct Tox_Pass_Key *_key, const uint8_t *passphrase, size_t passphrase_len, |
292 | const uint8_t *salt, TOX_ERR_KEY_DERIVATION *error); | ||
214 | 293 | ||
215 | /* Now come the functions that are analogous to the part 2 functions. */ | 294 | /** |
295 | * Encrypt a plain text with a key produced by tox_pass_key_derive or tox_pass_key_derive_with_salt. | ||
296 | * | ||
297 | * The output array must be at least `plaintext_len + TOX_PASS_ENCRYPTION_EXTRA_LENGTH` | ||
298 | * bytes long. | ||
299 | * | ||
300 | * @param plaintext A byte array of length `plaintext_len`. | ||
301 | * @param plaintext_len The length of the plain text array. May be 0. | ||
302 | * @param ciphertext The cipher text array to write the encrypted data to. | ||
303 | * | ||
304 | * @return true on success. | ||
305 | */ | ||
306 | bool tox_pass_key_encrypt(const struct Tox_Pass_Key *_key, const uint8_t *plaintext, size_t plaintext_len, | ||
307 | uint8_t *ciphertext, TOX_ERR_ENCRYPTION *error); | ||
216 | 308 | ||
217 | /* Encrypt arbitrary with a key produced by tox_derive_key_*. The output | 309 | /** |
218 | * array must be at least data_len + TOX_PASS_ENCRYPTION_EXTRA_LENGTH bytes long. | 310 | * This is the inverse of tox_pass_key_encrypt, also using only keys produced by |
219 | * key must be TOX_PASS_KEY_LENGTH bytes. | 311 | * tox_pass_key_derive or tox_pass_key_derive_with_salt. |
220 | * If you already have a symmetric key from somewhere besides this module, simply | ||
221 | * call encrypt_data_symmetric in toxcore/crypto_core directly. | ||
222 | * | 312 | * |
223 | * returns true on success | 313 | * @param ciphertext A byte array of length `ciphertext_len`. |
314 | * @param ciphertext_len The length of the cipher text array. May be 0. | ||
315 | * @param plaintext The plain text array to write the decrypted data to. | ||
316 | * | ||
317 | * @return true on success. | ||
224 | */ | 318 | */ |
225 | bool tox_pass_key_encrypt(const uint8_t *data, size_t data_len, const TOX_PASS_KEY *key, uint8_t *out, | 319 | bool tox_pass_key_decrypt(const struct Tox_Pass_Key *_key, const uint8_t *ciphertext, size_t ciphertext_len, |
226 | TOX_ERR_ENCRYPTION *error); | 320 | uint8_t *plaintext, TOX_ERR_DECRYPTION *error); |
321 | |||
322 | typedef enum TOX_ERR_GET_SALT { | ||
323 | |||
324 | /** | ||
325 | * The function returned successfully. | ||
326 | */ | ||
327 | TOX_ERR_GET_SALT_OK, | ||
328 | |||
329 | /** | ||
330 | * One of the arguments to the function was NULL when it was not expected. | ||
331 | */ | ||
332 | TOX_ERR_GET_SALT_NULL, | ||
333 | |||
334 | /** | ||
335 | * The input data is missing the magic number (i.e. wasn't created by this | ||
336 | * module, or is corrupted). | ||
337 | */ | ||
338 | TOX_ERR_GET_SALT_BAD_FORMAT, | ||
339 | |||
340 | } TOX_ERR_GET_SALT; | ||
227 | 341 | ||
228 | /* This is the inverse of tox_pass_key_encrypt, also using only keys produced by | 342 | |
229 | * tox_derive_key_from_pass. | 343 | /** |
344 | * Retrieves the salt used to encrypt the given data. | ||
230 | * | 345 | * |
231 | * the output data has size data_length - TOX_PASS_ENCRYPTION_EXTRA_LENGTH | 346 | * The retrieved salt can then be passed to tox_pass_key_derive_with_salt to |
347 | * produce the same key as was previously used. Any data encrypted with this | ||
348 | * module can be used as input. | ||
232 | * | 349 | * |
233 | * returns true on success | 350 | * The cipher text must be at least TOX_PASS_ENCRYPTION_EXTRA_LENGTH bytes in length. |
351 | * The salt must be TOX_PASS_SALT_LENGTH bytes in length. | ||
352 | * If the passed byte arrays are smaller than required, the behaviour is | ||
353 | * undefined. | ||
354 | * | ||
355 | * Success does not say anything about the validity of the data, only that | ||
356 | * data of the appropriate size was copied. | ||
357 | * | ||
358 | * @return true on success. | ||
234 | */ | 359 | */ |
235 | bool tox_pass_key_decrypt(const uint8_t *data, size_t length, const TOX_PASS_KEY *key, uint8_t *out, | 360 | bool tox_get_salt(const uint8_t *ciphertext, uint8_t *salt, TOX_ERR_GET_SALT *error); |
236 | TOX_ERR_DECRYPTION *error); | ||
237 | 361 | ||
238 | /* Determines whether or not the given data is encrypted (by checking the magic number). | 362 | /** |
363 | * Determines whether or not the given data is encrypted by this module. | ||
364 | * | ||
365 | * It does this check by verifying that the magic number is the one put in | ||
366 | * place by the encryption functions. | ||
239 | * | 367 | * |
240 | * The data must be at least TOX_PASS_ENCRYPTION_EXTRA_LENGTH bytes in length. | 368 | * The data must be at least TOX_PASS_ENCRYPTION_EXTRA_LENGTH bytes in length. |
369 | * If the passed byte array is smaller than required, the behaviour is | ||
370 | * undefined. | ||
371 | * | ||
372 | * If the cipher text pointer is NULL, this function returns false. | ||
241 | * | 373 | * |
242 | * returns true on success | 374 | * @return true if the data is encrypted by this module. |
243 | */ | 375 | */ |
244 | bool tox_is_data_encrypted(const uint8_t *data); | 376 | bool tox_is_data_encrypted(const uint8_t *data); |
245 | 377 | ||
378 | |||
246 | #ifdef __cplusplus | 379 | #ifdef __cplusplus |
247 | } | 380 | } |
248 | #endif | 381 | #endif |