diff options
author | mannol <eniz_vukovic@hotmail.com> | 2015-04-17 19:19:58 +0200 |
---|---|---|
committer | mannol <eniz_vukovic@hotmail.com> | 2015-04-17 19:19:58 +0200 |
commit | d1fd3e36a6b58d4cd6b3e2a7ccbed7e1e5d2e2a3 (patch) | |
tree | 6ae0aacc5fba56fc356be615b6f459c95647d597 /toxencryptsave | |
parent | 969367b72aebaa2ecfc168cf2e86b20501298c20 (diff) | |
parent | f8087887feaf77577a345ae1be68776459613c03 (diff) |
Updated with upstream
Diffstat (limited to 'toxencryptsave')
-rw-r--r-- | toxencryptsave/defines.h | 2 | ||||
-rw-r--r-- | toxencryptsave/toxencryptsave.c | 289 | ||||
-rw-r--r-- | toxencryptsave/toxencryptsave.h | 200 |
3 files changed, 242 insertions, 249 deletions
diff --git a/toxencryptsave/defines.h b/toxencryptsave/defines.h new file mode 100644 index 00000000..e3fca073 --- /dev/null +++ b/toxencryptsave/defines.h | |||
@@ -0,0 +1,2 @@ | |||
1 | #define TOX_ENC_SAVE_MAGIC_NUMBER "toxEsave" | ||
2 | #define TOX_ENC_SAVE_MAGIC_LENGTH 8 | ||
diff --git a/toxencryptsave/toxencryptsave.c b/toxencryptsave/toxencryptsave.c index 9172f512..e2f28a58 100644 --- a/toxencryptsave/toxencryptsave.c +++ b/toxencryptsave/toxencryptsave.c | |||
@@ -26,8 +26,9 @@ | |||
26 | #endif | 26 | #endif |
27 | 27 | ||
28 | #include "toxencryptsave.h" | 28 | #include "toxencryptsave.h" |
29 | #include "defines.h" | ||
29 | #include "../toxcore/crypto_core.h" | 30 | #include "../toxcore/crypto_core.h" |
30 | #include "../toxcore/tox.h" | 31 | #define SET_ERROR_PARAMETER(param, x) {if(param) {*param = x;}} |
31 | 32 | ||
32 | #ifdef VANILLA_NACL | 33 | #ifdef VANILLA_NACL |
33 | #include "crypto_pwhash_scryptsalsa208sha256/crypto_pwhash_scryptsalsa208sha256.h" | 34 | #include "crypto_pwhash_scryptsalsa208sha256/crypto_pwhash_scryptsalsa208sha256.h" |
@@ -35,81 +36,70 @@ | |||
35 | #include <crypto_hash_sha256.h> | 36 | #include <crypto_hash_sha256.h> |
36 | #endif | 37 | #endif |
37 | 38 | ||
38 | #define TOX_PASS_ENCRYPTION_EXTRA_LENGTH (crypto_box_MACBYTES + crypto_box_NONCEBYTES \ | 39 | #if TOX_PASS_SALT_LENGTH != crypto_pwhash_scryptsalsa208sha256_SALTBYTES |
39 | + crypto_pwhash_scryptsalsa208sha256_SALTBYTES + TOX_ENC_SAVE_MAGIC_LENGTH) | 40 | #error TOX_PASS_SALT_LENGTH is assumed to be equal to crypto_pwhash_scryptsalsa208sha256_SALTBYTES |
40 | 41 | #endif | |
41 | #define TOX_PASS_KEY_LENGTH (crypto_pwhash_scryptsalsa208sha256_SALTBYTES + crypto_box_KEYBYTES) | ||
42 | |||
43 | int tox_pass_encryption_extra_length() | ||
44 | { | ||
45 | return TOX_PASS_ENCRYPTION_EXTRA_LENGTH; | ||
46 | } | ||
47 | 42 | ||
48 | int tox_pass_key_length() | 43 | #if TOX_PASS_KEY_LENGTH != crypto_box_KEYBYTES |
49 | { | 44 | #error TOX_PASS_KEY_LENGTH is assumed to be equal to crypto_box_KEYBYTES |
50 | return TOX_PASS_KEY_LENGTH; | 45 | #endif |
51 | } | ||
52 | 46 | ||
53 | int tox_pass_salt_length() | 47 | #if TOX_PASS_ENCRYPTION_EXTRA_LENGTH != (crypto_box_MACBYTES + crypto_box_NONCEBYTES + crypto_pwhash_scryptsalsa208sha256_SALTBYTES + TOX_ENC_SAVE_MAGIC_LENGTH) |
54 | { | 48 | #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) |
55 | return crypto_pwhash_scryptsalsa208sha256_SALTBYTES; | 49 | #endif |
56 | } | ||
57 | 50 | ||
58 | /* This "module" provides functions analogous to tox_load and tox_save in toxcore | 51 | /* Clients should consider alerting their users that, unlike plain data, if even one bit |
59 | * Clients should consider alerting their users that, unlike plain data, if even one bit | ||
60 | * becomes corrupted, the data will be entirely unrecoverable. | 52 | * becomes corrupted, the data will be entirely unrecoverable. |
61 | * Ditto if they forget their password, there is no way to recover the data. | 53 | * Ditto if they forget their password, there is no way to recover the data. |
62 | */ | 54 | */ |
63 | 55 | ||
64 | /* return size of the messenger data (for encrypted saving). */ | ||
65 | uint32_t tox_encrypted_size(const Tox *tox) | ||
66 | { | ||
67 | return tox_size(tox) + TOX_PASS_ENCRYPTION_EXTRA_LENGTH; | ||
68 | } | ||
69 | |||
70 | /* This retrieves the salt used to encrypt the given data, which can then be passed to | 56 | /* This retrieves the salt used to encrypt the given data, which can then be passed to |
71 | * derive_key_with_salt to produce the same key as was previously used. Any encrpyted | 57 | * derive_key_with_salt to produce the same key as was previously used. Any encrpyted |
72 | * data with this module can be used as input. | 58 | * data with this module can be used as input. |
73 | * | 59 | * |
74 | * returns -1 if the magic number is wrong | 60 | * returns true if magic number matches |
75 | * returns 0 otherwise (no guarantee about validity of data) | 61 | * success does not say anything about the validity of the data, only that data of |
62 | * the appropriate size was copied | ||
76 | */ | 63 | */ |
77 | int tox_get_salt(uint8_t *data, uint8_t *salt) | 64 | bool tox_get_salt(const uint8_t *data, uint8_t *salt) |
78 | { | 65 | { |
79 | if (memcmp(data, TOX_ENC_SAVE_MAGIC_NUMBER, TOX_ENC_SAVE_MAGIC_LENGTH) != 0) | 66 | if (memcmp(data, TOX_ENC_SAVE_MAGIC_NUMBER, TOX_ENC_SAVE_MAGIC_LENGTH) != 0) |
80 | return -1; | 67 | return 0; |
81 | 68 | ||
82 | data += TOX_ENC_SAVE_MAGIC_LENGTH; | 69 | data += TOX_ENC_SAVE_MAGIC_LENGTH; |
83 | memcpy(salt, data, crypto_pwhash_scryptsalsa208sha256_SALTBYTES); | 70 | memcpy(salt, data, crypto_pwhash_scryptsalsa208sha256_SALTBYTES); |
84 | return 0; | 71 | return 1; |
85 | } | 72 | } |
86 | 73 | ||
87 | /* Generates a secret symmetric key from the given passphrase. out_key must be at least | 74 | /* Generates a secret symmetric key from the given passphrase. out_key must be at least |
88 | * TOX_PASS_KEY_LENGTH bytes long. | 75 | * TOX_PASS_KEY_LENGTH bytes long. |
89 | * Be sure to not compromise the key! Only keep it in memory, do not write to disk. | 76 | * Be sure to not compromise the key! Only keep it in memory, do not write to disk. |
90 | * This function is fairly cheap, but irungentoo insists that you be allowed to | ||
91 | * cache the result if you want, to minimize computation for repeated encryptions. | ||
92 | * The password is zeroed after key derivation. | 77 | * The password is zeroed after key derivation. |
93 | * The key should only be used with the other functions in this module, as it | 78 | * The key should only be used with the other functions in this module, as it |
94 | * includes a salt. | 79 | * includes a salt. |
80 | * Note that this function is not deterministic; to derive the same key from a | ||
81 | * password, you also must know the random salt that was used. See below. | ||
95 | * | 82 | * |
96 | * returns 0 on success | 83 | * returns true on success |
97 | * returns -1 on failure | ||
98 | */ | 84 | */ |
99 | int tox_derive_key_from_pass(uint8_t *passphrase, uint32_t pplength, uint8_t *out_key) | 85 | bool tox_derive_key_from_pass(uint8_t *passphrase, size_t pplength, TOX_PASS_KEY *out_key, |
86 | TOX_ERR_KEY_DERIVATION *error) | ||
100 | { | 87 | { |
101 | uint8_t salt[crypto_pwhash_scryptsalsa208sha256_SALTBYTES]; | 88 | uint8_t salt[crypto_pwhash_scryptsalsa208sha256_SALTBYTES]; |
102 | randombytes(salt, sizeof salt); | 89 | randombytes(salt, sizeof salt); |
103 | return tox_derive_key_with_salt(passphrase, pplength, salt, out_key); | 90 | return tox_derive_key_with_salt(passphrase, pplength, salt, out_key, error); |
104 | } | 91 | } |
105 | 92 | ||
106 | /* Same as above, except with use the given salt for deterministic key derivation. | 93 | /* Same as above, except with use the given salt for deterministic key derivation. |
107 | * The salt must be tox_salt_length() bytes in length. | 94 | * The salt must be TOX_PASS_SALT_LENGTH bytes in length. |
108 | */ | 95 | */ |
109 | int tox_derive_key_with_salt(uint8_t *passphrase, uint32_t pplength, uint8_t *salt, uint8_t *out_key) | 96 | bool tox_derive_key_with_salt(uint8_t *passphrase, size_t pplength, uint8_t *salt, TOX_PASS_KEY *out_key, |
97 | TOX_ERR_KEY_DERIVATION *error) | ||
110 | { | 98 | { |
111 | if (pplength == 0) | 99 | if (pplength == 0 || !passphrase || !salt || !out_key) { |
112 | return -1; | 100 | SET_ERROR_PARAMETER(error, TOX_ERR_KEY_DERIVATION_NULL); |
101 | return 0; | ||
102 | } | ||
113 | 103 | ||
114 | uint8_t passkey[crypto_hash_sha256_BYTES]; | 104 | uint8_t passkey[crypto_hash_sha256_BYTES]; |
115 | crypto_hash_sha256(passkey, passphrase, pplength); | 105 | crypto_hash_sha256(passkey, passphrase, pplength); |
@@ -125,27 +115,33 @@ int tox_derive_key_with_salt(uint8_t *passphrase, uint32_t pplength, uint8_t *sa | |||
125 | crypto_pwhash_scryptsalsa208sha256_OPSLIMIT_INTERACTIVE * 2, /* slightly stronger */ | 115 | crypto_pwhash_scryptsalsa208sha256_OPSLIMIT_INTERACTIVE * 2, /* slightly stronger */ |
126 | crypto_pwhash_scryptsalsa208sha256_MEMLIMIT_INTERACTIVE) != 0) { | 116 | crypto_pwhash_scryptsalsa208sha256_MEMLIMIT_INTERACTIVE) != 0) { |
127 | /* out of memory most likely */ | 117 | /* out of memory most likely */ |
128 | return -1; | 118 | SET_ERROR_PARAMETER(error, TOX_ERR_KEY_DERIVATION_FAILED); |
119 | return 0; | ||
129 | } | 120 | } |
130 | 121 | ||
131 | sodium_memzero(passkey, crypto_hash_sha256_BYTES); /* wipe plaintext pw */ | 122 | sodium_memzero(passkey, crypto_hash_sha256_BYTES); /* wipe plaintext pw */ |
132 | memcpy(out_key, salt, crypto_pwhash_scryptsalsa208sha256_SALTBYTES); | 123 | memcpy(out_key->salt, salt, crypto_pwhash_scryptsalsa208sha256_SALTBYTES); |
133 | memcpy(out_key + crypto_pwhash_scryptsalsa208sha256_SALTBYTES, key, crypto_box_KEYBYTES); | 124 | memcpy(out_key->key, key, crypto_box_KEYBYTES); |
134 | return 0; | 125 | SET_ERROR_PARAMETER(error, TOX_ERR_KEY_DERIVATION_OK); |
126 | return 1; | ||
135 | } | 127 | } |
136 | 128 | ||
137 | /* Encrypt arbitrary with a key produced by tox_derive_key_from_pass. The output | 129 | /* Encrypt arbitrary with a key produced by tox_derive_key_*. The output |
138 | * array must be at least data_len + TOX_PASS_ENCRYPTION_EXTRA_LENGTH bytes long. | 130 | * array must be at least data_len + TOX_PASS_ENCRYPTION_EXTRA_LENGTH bytes long. |
139 | * key must be TOX_PASS_KEY_LENGTH bytes. | 131 | * key must be TOX_PASS_KEY_LENGTH bytes. |
140 | * If you already have a symmetric key from somewhere besides this module, simply | 132 | * If you already have a symmetric key from somewhere besides this module, simply |
141 | * call encrypt_data_symmetric in toxcore/crypto_core directly. | 133 | * call encrypt_data_symmetric in toxcore/crypto_core directly. |
142 | * | 134 | * |
143 | * | 135 | * returns true on success |
144 | * returns 0 on success | ||
145 | * returns -1 on failure | ||
146 | */ | 136 | */ |
147 | int tox_pass_key_encrypt(const uint8_t *data, uint32_t data_len, const uint8_t *key, uint8_t *out) | 137 | bool tox_pass_key_encrypt(const uint8_t *data, size_t data_len, const TOX_PASS_KEY *key, uint8_t *out, |
138 | TOX_ERR_ENCRYPTION *error) | ||
148 | { | 139 | { |
140 | if (data_len == 0 || !data || !key || !out) { | ||
141 | SET_ERROR_PARAMETER(error, TOX_ERR_ENCRYPTION_NULL); | ||
142 | return 0; | ||
143 | } | ||
144 | |||
149 | /* the output data consists of, in order: | 145 | /* the output data consists of, in order: |
150 | * salt, nonce, mac, enc_data | 146 | * salt, nonce, mac, enc_data |
151 | * where the mac is automatically prepended by the encrypt() | 147 | * where the mac is automatically prepended by the encrypt() |
@@ -159,8 +155,7 @@ int tox_pass_key_encrypt(const uint8_t *data, uint32_t data_len, const uint8_t * | |||
159 | out += TOX_ENC_SAVE_MAGIC_LENGTH; | 155 | out += TOX_ENC_SAVE_MAGIC_LENGTH; |
160 | 156 | ||
161 | /* then add the rest prefix */ | 157 | /* then add the rest prefix */ |
162 | memcpy(out, key, crypto_pwhash_scryptsalsa208sha256_SALTBYTES); | 158 | memcpy(out, key->salt, crypto_pwhash_scryptsalsa208sha256_SALTBYTES); |
163 | key += crypto_pwhash_scryptsalsa208sha256_SALTBYTES; | ||
164 | out += crypto_pwhash_scryptsalsa208sha256_SALTBYTES; | 159 | out += crypto_pwhash_scryptsalsa208sha256_SALTBYTES; |
165 | 160 | ||
166 | uint8_t nonce[crypto_box_NONCEBYTES]; | 161 | uint8_t nonce[crypto_box_NONCEBYTES]; |
@@ -169,177 +164,133 @@ int tox_pass_key_encrypt(const uint8_t *data, uint32_t data_len, const uint8_t * | |||
169 | out += crypto_box_NONCEBYTES; | 164 | out += crypto_box_NONCEBYTES; |
170 | 165 | ||
171 | /* now encrypt */ | 166 | /* now encrypt */ |
172 | if (encrypt_data_symmetric(key, nonce, data, data_len, out) | 167 | if (encrypt_data_symmetric(key->key, nonce, data, data_len, out) |
173 | != data_len + crypto_box_MACBYTES) { | 168 | != data_len + crypto_box_MACBYTES) { |
174 | return -1; | 169 | SET_ERROR_PARAMETER(error, TOX_ERR_ENCRYPTION_FAILED); |
170 | return 0; | ||
175 | } | 171 | } |
176 | 172 | ||
177 | return 0; | 173 | SET_ERROR_PARAMETER(error, TOX_ERR_ENCRYPTION_OK); |
174 | return 1; | ||
178 | } | 175 | } |
179 | 176 | ||
180 | /* Encrypts the given data with the given passphrase. The output array must be | 177 | /* Encrypts the given data with the given passphrase. The output array must be |
181 | * at least data_len + TOX_PASS_ENCRYPTION_EXTRA_LENGTH bytes long. This delegates | 178 | * at least data_len + TOX_PASS_ENCRYPTION_EXTRA_LENGTH bytes long. This delegates |
182 | * to tox_derive_key_from_pass and tox_pass_key_encrypt. | 179 | * to tox_derive_key_from_pass and tox_pass_key_encrypt. |
183 | * | 180 | * |
184 | * returns 0 on success | 181 | * returns true on success |
185 | * returns -1 on failure | ||
186 | */ | 182 | */ |
187 | int tox_pass_encrypt(const uint8_t *data, uint32_t data_len, uint8_t *passphrase, uint32_t pplength, uint8_t *out) | 183 | bool 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) | ||
188 | { | 185 | { |
189 | uint8_t key[TOX_PASS_KEY_LENGTH]; | 186 | TOX_PASS_KEY key; |
190 | 187 | TOX_ERR_KEY_DERIVATION _error; | |
191 | if (tox_derive_key_from_pass(passphrase, pplength, key) == -1) | ||
192 | return -1; | ||
193 | 188 | ||
194 | return tox_pass_key_encrypt(data, data_len, key, out); | 189 | if (!tox_derive_key_from_pass(passphrase, pplength, &key, &_error)) { |
195 | } | 190 | if (_error == TOX_ERR_KEY_DERIVATION_NULL) { |
196 | 191 | SET_ERROR_PARAMETER(error, TOX_ERR_ENCRYPTION_NULL); | |
197 | /* Save the messenger data encrypted with the given password. | 192 | } else if (_error == TOX_ERR_KEY_DERIVATION_FAILED) { |
198 | * data must be at least tox_encrypted_size(). | 193 | SET_ERROR_PARAMETER(error, TOX_ERR_ENCRYPTION_KEY_DERIVATION_FAILED); |
199 | * | 194 | } |
200 | * returns 0 on success | ||
201 | * returns -1 on failure | ||
202 | */ | ||
203 | int tox_encrypted_save(const Tox *tox, uint8_t *data, uint8_t *passphrase, uint32_t pplength) | ||
204 | { | ||
205 | /* first get plain save data */ | ||
206 | uint32_t temp_size = tox_size(tox); | ||
207 | uint8_t temp_data[temp_size]; | ||
208 | tox_save(tox, temp_data); | ||
209 | |||
210 | /* now encrypt */ | ||
211 | return tox_pass_encrypt(temp_data, temp_size, passphrase, pplength, data); | ||
212 | } | ||
213 | 195 | ||
214 | /* Save the messenger data encrypted with the given key from tox_derive_key. | 196 | return 0; |
215 | * data must be at least tox_encrypted_size(). | 197 | } |
216 | * | ||
217 | * returns 0 on success | ||
218 | * returns -1 on failure | ||
219 | */ | ||
220 | int tox_encrypted_key_save(const Tox *tox, uint8_t *data, uint8_t *key) | ||
221 | { | ||
222 | /* first get plain save data */ | ||
223 | uint32_t temp_size = tox_size(tox); | ||
224 | uint8_t temp_data[temp_size]; | ||
225 | tox_save(tox, temp_data); | ||
226 | 198 | ||
227 | /* encrypt */ | 199 | return tox_pass_key_encrypt(data, data_len, &key, out, error); |
228 | return tox_pass_key_encrypt(temp_data, temp_size, key, data); | ||
229 | } | 200 | } |
230 | 201 | ||
231 | /* This is the inverse of tox_pass_key_encrypt, also using only keys produced by | 202 | /* This is the inverse of tox_pass_key_encrypt, also using only keys produced by |
232 | * tox_derive_key_from_pass. | 203 | * tox_derive_key_from_pass. |
233 | * | 204 | * |
234 | * returns the length of the output data (== data_len - TOX_PASS_ENCRYPTION_EXTRA_LENGTH) on success | 205 | * the output data has size data_length - TOX_PASS_ENCRYPTION_EXTRA_LENGTH |
235 | * returns -1 on failure | 206 | * |
207 | * returns true on success | ||
236 | */ | 208 | */ |
237 | int tox_pass_key_decrypt(const uint8_t *data, uint32_t length, const uint8_t *key, uint8_t *out) | 209 | bool tox_pass_key_decrypt(const uint8_t *data, size_t length, const TOX_PASS_KEY *key, uint8_t *out, |
210 | TOX_ERR_DECRYPTION *error) | ||
238 | { | 211 | { |
239 | if (length <= TOX_PASS_ENCRYPTION_EXTRA_LENGTH | 212 | if (length <= TOX_PASS_ENCRYPTION_EXTRA_LENGTH) { |
240 | || 0 != memcmp(data, TOX_ENC_SAVE_MAGIC_NUMBER, TOX_ENC_SAVE_MAGIC_LENGTH)) | 213 | SET_ERROR_PARAMETER(error, TOX_ERR_DECRYPTION_INVALID_LENGTH); |
241 | return -1; | 214 | return 0; |
215 | } | ||
216 | |||
217 | if (!data || !key || !out) { | ||
218 | SET_ERROR_PARAMETER(error, TOX_ERR_DECRYPTION_NULL); | ||
219 | return 0; | ||
220 | } | ||
221 | |||
222 | if (memcmp(data, TOX_ENC_SAVE_MAGIC_NUMBER, TOX_ENC_SAVE_MAGIC_LENGTH) != 0) { | ||
223 | SET_ERROR_PARAMETER(error, TOX_ERR_DECRYPTION_BAD_FORMAT); | ||
224 | return 0; | ||
225 | } | ||
242 | 226 | ||
243 | data += TOX_ENC_SAVE_MAGIC_LENGTH; | 227 | data += TOX_ENC_SAVE_MAGIC_LENGTH; |
228 | data += crypto_pwhash_scryptsalsa208sha256_SALTBYTES; // salt only affects key derivation | ||
244 | 229 | ||
245 | uint32_t decrypt_length = length - TOX_PASS_ENCRYPTION_EXTRA_LENGTH; | 230 | size_t decrypt_length = length - TOX_PASS_ENCRYPTION_EXTRA_LENGTH; |
246 | //uint8_t salt[crypto_pwhash_scryptsalsa208sha256_SALTBYTES]; | ||
247 | uint8_t nonce[crypto_box_NONCEBYTES]; | ||
248 | 231 | ||
249 | //memcpy(salt, data, crypto_pwhash_scryptsalsa208sha256_SALTBYTES); | 232 | uint8_t nonce[crypto_box_NONCEBYTES]; |
250 | key += crypto_pwhash_scryptsalsa208sha256_SALTBYTES; // ignore the salt, which is only needed for kdf | ||
251 | data += crypto_pwhash_scryptsalsa208sha256_SALTBYTES; | ||
252 | memcpy(nonce, data, crypto_box_NONCEBYTES); | 233 | memcpy(nonce, data, crypto_box_NONCEBYTES); |
253 | data += crypto_box_NONCEBYTES; | 234 | data += crypto_box_NONCEBYTES; |
254 | 235 | ||
255 | /* decrypt the data */ | 236 | /* decrypt the data */ |
256 | if (decrypt_data_symmetric(key, nonce, data, decrypt_length + crypto_box_MACBYTES, out) | 237 | if (decrypt_data_symmetric(key->key, nonce, data, decrypt_length + crypto_box_MACBYTES, out) |
257 | != decrypt_length) { | 238 | != decrypt_length) { |
258 | return -1; | 239 | SET_ERROR_PARAMETER(error, TOX_ERR_DECRYPTION_FAILED); |
240 | return 0; | ||
259 | } | 241 | } |
260 | 242 | ||
261 | return decrypt_length; | 243 | SET_ERROR_PARAMETER(error, TOX_ERR_DECRYPTION_OK); |
244 | return 1; | ||
262 | } | 245 | } |
263 | 246 | ||
264 | /* Decrypts the given data with the given passphrase. The output array must be | 247 | /* Decrypts the given data with the given passphrase. The output array must be |
265 | * at least data_len - TOX_PASS_ENCRYPTION_EXTRA_LENGTH bytes long. | 248 | * at least data_len - TOX_PASS_ENCRYPTION_EXTRA_LENGTH bytes long. This delegates |
249 | * to tox_pass_key_decrypt. | ||
250 | * | ||
251 | * the output data has size data_length - TOX_PASS_ENCRYPTION_EXTRA_LENGTH | ||
266 | * | 252 | * |
267 | * returns the length of the output data (== data_len - TOX_PASS_ENCRYPTION_EXTRA_LENGTH) on success | 253 | * returns true on success |
268 | * returns -1 on failure | ||
269 | */ | 254 | */ |
270 | int tox_pass_decrypt(const uint8_t *data, uint32_t length, uint8_t *passphrase, uint32_t pplength, uint8_t *out) | 255 | bool tox_pass_decrypt(const uint8_t *data, size_t length, uint8_t *passphrase, size_t pplength, uint8_t *out, |
256 | TOX_ERR_DECRYPTION *error) | ||
271 | { | 257 | { |
272 | uint8_t passkey[crypto_hash_sha256_BYTES]; | 258 | if (length <= TOX_PASS_ENCRYPTION_EXTRA_LENGTH || pplength == 0) { |
273 | crypto_hash_sha256(passkey, passphrase, pplength); | 259 | SET_ERROR_PARAMETER(error, TOX_ERR_DECRYPTION_INVALID_LENGTH); |
260 | return 0; | ||
261 | } | ||
262 | |||
263 | if (!data || !passphrase || !out) { | ||
264 | SET_ERROR_PARAMETER(error, TOX_ERR_DECRYPTION_NULL); | ||
265 | return 0; | ||
266 | } | ||
267 | |||
268 | if (memcmp(data, TOX_ENC_SAVE_MAGIC_NUMBER, TOX_ENC_SAVE_MAGIC_LENGTH) != 0) { | ||
269 | SET_ERROR_PARAMETER(error, TOX_ERR_DECRYPTION_BAD_FORMAT); | ||
270 | return 0; | ||
271 | } | ||
274 | 272 | ||
275 | uint8_t salt[crypto_pwhash_scryptsalsa208sha256_SALTBYTES]; | 273 | uint8_t salt[crypto_pwhash_scryptsalsa208sha256_SALTBYTES]; |
276 | memcpy(salt, data + TOX_ENC_SAVE_MAGIC_LENGTH, crypto_pwhash_scryptsalsa208sha256_SALTBYTES); | 274 | memcpy(salt, data + TOX_ENC_SAVE_MAGIC_LENGTH, crypto_pwhash_scryptsalsa208sha256_SALTBYTES); |
277 | 275 | ||
278 | /* derive the key */ | 276 | /* derive the key */ |
279 | uint8_t key[crypto_box_KEYBYTES + crypto_pwhash_scryptsalsa208sha256_SALTBYTES]; | 277 | TOX_PASS_KEY key; |
280 | 278 | ||
281 | if (crypto_pwhash_scryptsalsa208sha256( | 279 | if (!tox_derive_key_with_salt(passphrase, pplength, salt, &key, NULL)) { |
282 | key + crypto_pwhash_scryptsalsa208sha256_SALTBYTES, | ||
283 | crypto_box_KEYBYTES, (char *)passkey, sizeof(passkey), salt, | ||
284 | crypto_pwhash_scryptsalsa208sha256_OPSLIMIT_INTERACTIVE * 2, /* slightly stronger */ | ||
285 | crypto_pwhash_scryptsalsa208sha256_MEMLIMIT_INTERACTIVE) != 0) { | ||
286 | /* out of memory most likely */ | 280 | /* out of memory most likely */ |
287 | return -1; | 281 | SET_ERROR_PARAMETER(error, TOX_ERR_DECRYPTION_KEY_DERIVATION_FAILED); |
282 | return 0; | ||
288 | } | 283 | } |
289 | 284 | ||
290 | sodium_memzero(passkey, crypto_hash_sha256_BYTES); /* wipe plaintext pw */ | 285 | return tox_pass_key_decrypt(data, length, &key, out, error); |
291 | |||
292 | return tox_pass_key_decrypt(data, length, key, out); | ||
293 | } | ||
294 | |||
295 | /* Load the messenger from encrypted data of size length. | ||
296 | * | ||
297 | * returns 0 on success | ||
298 | * returns -1 on failure | ||
299 | */ | ||
300 | int tox_encrypted_load(Tox *tox, const uint8_t *data, uint32_t length, uint8_t *passphrase, uint32_t pplength) | ||
301 | { | ||
302 | uint32_t decrypt_length = length - TOX_PASS_ENCRYPTION_EXTRA_LENGTH; | ||
303 | uint8_t temp_data[decrypt_length]; | ||
304 | |||
305 | if (tox_pass_decrypt(data, length, passphrase, pplength, temp_data) | ||
306 | != decrypt_length) | ||
307 | return -1; | ||
308 | |||
309 | return tox_load(tox, temp_data, decrypt_length); | ||
310 | } | ||
311 | |||
312 | /* Load the messenger from encrypted data of size length, with key from tox_derive_key. | ||
313 | * | ||
314 | * returns 0 on success | ||
315 | * returns -1 on failure | ||
316 | */ | ||
317 | int tox_encrypted_key_load(Tox *tox, const uint8_t *data, uint32_t length, uint8_t *key) | ||
318 | { | ||
319 | uint32_t decrypt_length = length - TOX_PASS_ENCRYPTION_EXTRA_LENGTH; | ||
320 | uint8_t temp_data[decrypt_length]; | ||
321 | |||
322 | if (tox_pass_key_decrypt(data, length, key, temp_data) | ||
323 | != decrypt_length) | ||
324 | return -1; | ||
325 | |||
326 | return tox_load(tox, temp_data, decrypt_length); | ||
327 | } | 286 | } |
328 | 287 | ||
329 | /* Determines whether or not the given data is encrypted (by checking the magic number) | 288 | /* Determines whether or not the given data is encrypted (by checking the magic number) |
330 | * | ||
331 | * returns 1 if it is encrypted | ||
332 | * returns 0 otherwise | ||
333 | */ | 289 | */ |
334 | int tox_is_data_encrypted(const uint8_t *data) | 290 | bool tox_is_data_encrypted(const uint8_t *data) |
335 | { | 291 | { |
336 | if (memcmp(data, TOX_ENC_SAVE_MAGIC_NUMBER, TOX_ENC_SAVE_MAGIC_LENGTH) == 0) | 292 | if (memcmp(data, TOX_ENC_SAVE_MAGIC_NUMBER, TOX_ENC_SAVE_MAGIC_LENGTH) == 0) |
337 | return 1; | 293 | return 1; |
338 | else | 294 | else |
339 | return 0; | 295 | return 0; |
340 | } | 296 | } |
341 | |||
342 | int tox_is_save_encrypted(const uint8_t *data) | ||
343 | { | ||
344 | return tox_is_data_encrypted(data); | ||
345 | } | ||
diff --git a/toxencryptsave/toxencryptsave.h b/toxencryptsave/toxencryptsave.h index 169f736c..c077d899 100644 --- a/toxencryptsave/toxencryptsave.h +++ b/toxencryptsave/toxencryptsave.h | |||
@@ -29,27 +29,20 @@ extern "C" { | |||
29 | #endif | 29 | #endif |
30 | 30 | ||
31 | #include <stdint.h> | 31 | #include <stdint.h> |
32 | #include <stddef.h> | ||
33 | #include <stdbool.h> | ||
32 | 34 | ||
33 | #ifndef __TOX_DEFINED__ | 35 | #ifndef TOX_DEFINED |
34 | #define __TOX_DEFINED__ | 36 | #define TOX_DEFINED |
35 | typedef struct Tox Tox; | 37 | typedef struct Tox Tox; |
38 | struct Tox_Options; | ||
36 | #endif | 39 | #endif |
37 | 40 | ||
38 | // these functions provide access to these defines in toxencryptsave.c, which | 41 | #define TOX_PASS_SALT_LENGTH 32 |
39 | // otherwise aren't actually available in clients... | 42 | #define TOX_PASS_KEY_LENGTH 32 |
40 | int tox_pass_encryption_extra_length(); | 43 | #define TOX_PASS_ENCRYPTION_EXTRA_LENGTH 80 |
41 | 44 | ||
42 | int tox_pass_key_length(); | 45 | /* This module is conceptually organized into two parts. The first part are the functions |
43 | |||
44 | int tox_pass_salt_length(); | ||
45 | |||
46 | /* return size of the messenger data (for encrypted Messenger saving). */ | ||
47 | uint32_t tox_encrypted_size(const Tox *tox); | ||
48 | |||
49 | /* This "module" provides functions analogous to tox_load and tox_save in toxcore, | ||
50 | * as well as functions for encryption of arbitrary client data (e.g. chat logs). | ||
51 | * | ||
52 | * It is conceptually organized into two parts. The first part are the functions | ||
53 | * with "key" in the name. To use these functions, first derive an encryption key | 46 | * with "key" in the name. To use these functions, first derive an encryption key |
54 | * from a password with tox_derive_key_from_pass, and use the returned key to | 47 | * 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, | 48 | * encrypt the data. The second part takes the password itself instead of the key, |
@@ -59,13 +52,83 @@ uint32_t tox_encrypted_size(const Tox *tox); | |||
59 | * favor using the first part intead of the second part. | 52 | * favor using the first part intead of the second part. |
60 | * | 53 | * |
61 | * The encrypted data is prepended with a magic number, to aid validity checking | 54 | * The encrypted data is prepended with a magic number, to aid validity checking |
62 | * (no guarantees are made of course). | 55 | * (no guarantees are made of course). Any data to be decrypted must start with |
56 | * the magic number. | ||
63 | * | 57 | * |
64 | * Clients should consider alerting their users that, unlike plain data, if even one bit | 58 | * Clients should consider alerting their users that, unlike plain data, if even one bit |
65 | * becomes corrupted, the data will be entirely unrecoverable. | 59 | * becomes corrupted, the data will be entirely unrecoverable. |
66 | * Ditto if they forget their password, there is no way to recover the data. | 60 | * Ditto if they forget their password, there is no way to recover the data. |
67 | */ | 61 | */ |
68 | 62 | ||
63 | /* Since apparently no one actually bothered to learn about the module previously, | ||
64 | * the recently removed functions tox_encrypted_new and tox_get_encrypted_savedata | ||
65 | * may be trivially replaced by calls to tox_pass_decrypt -> tox_new or | ||
66 | * tox_get_savedata -> tox_pass_encrypt as appropriate. The removed functions | ||
67 | * were never more than 5 line wrappers of the other public API functions anyways. | ||
68 | * (As has always been, tox_pass_decrypt and tox_pass_encrypt are interchangeable | ||
69 | * with tox_pass_key_decrypt and tox_pass_key_encrypt, as the client program requires.) | ||
70 | */ | ||
71 | |||
72 | typedef enum TOX_ERR_KEY_DERIVATION { | ||
73 | TOX_ERR_KEY_DERIVATION_OK, | ||
74 | /** | ||
75 | * Some input data, or maybe the output pointer, was null. | ||
76 | */ | ||
77 | TOX_ERR_KEY_DERIVATION_NULL, | ||
78 | /** | ||
79 | * The crypto lib was unable to derive a key from the given passphrase, | ||
80 | * which is usually a lack of memory issue. The functions accepting keys | ||
81 | * do not produce this error. | ||
82 | */ | ||
83 | TOX_ERR_KEY_DERIVATION_FAILED | ||
84 | } TOX_ERR_KEY_DERIVATION; | ||
85 | |||
86 | typedef enum TOX_ERR_ENCRYPTION { | ||
87 | TOX_ERR_ENCRYPTION_OK, | ||
88 | /** | ||
89 | * Some input data, or maybe the output pointer, was null. | ||
90 | */ | ||
91 | TOX_ERR_ENCRYPTION_NULL, | ||
92 | /** | ||
93 | * The crypto lib was unable to derive a key from the given passphrase, | ||
94 | * which is usually a lack of memory issue. The functions accepting keys | ||
95 | * do not produce this error. | ||
96 | */ | ||
97 | TOX_ERR_ENCRYPTION_KEY_DERIVATION_FAILED, | ||
98 | /** | ||
99 | * The encryption itself failed. | ||
100 | */ | ||
101 | TOX_ERR_ENCRYPTION_FAILED | ||
102 | } TOX_ERR_ENCRYPTION; | ||
103 | |||
104 | typedef enum TOX_ERR_DECRYPTION { | ||
105 | TOX_ERR_DECRYPTION_OK, | ||
106 | /** | ||
107 | * Some input data, or maybe the output pointer, was null. | ||
108 | */ | ||
109 | TOX_ERR_DECRYPTION_NULL, | ||
110 | /** | ||
111 | * The input data was shorter than TOX_PASS_ENCRYPTION_EXTRA_LENGTH bytes | ||
112 | */ | ||
113 | TOX_ERR_DECRYPTION_INVALID_LENGTH, | ||
114 | /** | ||
115 | * The input data is missing the magic number (i.e. wasn't created by this | ||
116 | * module, or is corrupted) | ||
117 | */ | ||
118 | TOX_ERR_DECRYPTION_BAD_FORMAT, | ||
119 | /** | ||
120 | * The crypto lib was unable to derive a key from the given passphrase, | ||
121 | * which is usually a lack of memory issue. The functions accepting keys | ||
122 | * do not produce this error. | ||
123 | */ | ||
124 | TOX_ERR_DECRYPTION_KEY_DERIVATION_FAILED, | ||
125 | /** | ||
126 | * The encrypted byte array could not be decrypted. Either the data was | ||
127 | * corrupt or the password/key was incorrect. | ||
128 | */ | ||
129 | TOX_ERR_DECRYPTION_FAILED | ||
130 | } TOX_ERR_DECRYPTION; | ||
131 | |||
69 | 132 | ||
70 | /******************************* BEGIN PART 2 ******************************* | 133 | /******************************* BEGIN PART 2 ******************************* |
71 | * For simplicty, the second part of the module is presented first. The API for | 134 | * For simplicty, the second part of the module is presented first. The API for |
@@ -75,41 +138,25 @@ uint32_t tox_encrypted_size(const Tox *tox); | |||
75 | */ | 138 | */ |
76 | 139 | ||
77 | /* Encrypts the given data with the given passphrase. The output array must be | 140 | /* Encrypts the given data with the given passphrase. The output array must be |
78 | * at least data_len + tox_pass_encryption_extra_length() bytes long. This delegates | 141 | * at least data_len + TOX_PASS_ENCRYPTION_EXTRA_LENGTH bytes long. This delegates |
79 | * to tox_derive_key_from_pass and tox_pass_key_encrypt. | 142 | * to tox_derive_key_from_pass and tox_pass_key_encrypt. |
80 | * | 143 | * |
81 | * tox_encrypted_save() is a good example of how to use this function. | 144 | * returns true on success |
82 | * | ||
83 | * returns 0 on success | ||
84 | * returns -1 on failure | ||
85 | */ | 145 | */ |
86 | int tox_pass_encrypt(const uint8_t *data, uint32_t data_len, uint8_t *passphrase, uint32_t pplength, uint8_t *out); | 146 | bool tox_pass_encrypt(const uint8_t *data, size_t data_len, uint8_t *passphrase, size_t pplength, uint8_t *out, |
147 | TOX_ERR_ENCRYPTION *error); | ||
87 | 148 | ||
88 | /* Save the messenger data encrypted with the given password. | ||
89 | * data must be at least tox_encrypted_size(). | ||
90 | * | ||
91 | * returns 0 on success | ||
92 | * returns -1 on failure | ||
93 | */ | ||
94 | int tox_encrypted_save(const Tox *tox, uint8_t *data, uint8_t *passphrase, uint32_t pplength); | ||
95 | 149 | ||
96 | /* Decrypts the given data with the given passphrase. The output array must be | 150 | /* Decrypts the given data with the given passphrase. The output array must be |
97 | * at least data_len - tox_pass_encryption_extra_length() bytes long. This delegates | 151 | * at least data_len - TOX_PASS_ENCRYPTION_EXTRA_LENGTH bytes long. This delegates |
98 | * to tox_pass_key_decrypt. | 152 | * to tox_pass_key_decrypt. |
99 | * | 153 | * |
100 | * tox_encrypted_load() is a good example of how to use this function. | 154 | * the output data has size data_length - TOX_PASS_ENCRYPTION_EXTRA_LENGTH |
101 | * | 155 | * |
102 | * returns the length of the output data (== data_len - tox_pass_encryption_extra_length()) on success | 156 | * returns true on success |
103 | * returns -1 on failure | ||
104 | */ | 157 | */ |
105 | int tox_pass_decrypt(const uint8_t *data, uint32_t length, uint8_t *passphrase, uint32_t pplength, uint8_t *out); | 158 | bool tox_pass_decrypt(const uint8_t *data, size_t length, uint8_t *passphrase, size_t pplength, uint8_t *out, |
106 | 159 | TOX_ERR_DECRYPTION *error); | |
107 | /* Load the messenger from encrypted data of size length. | ||
108 | * | ||
109 | * returns 0 on success | ||
110 | * returns -1 on failure | ||
111 | */ | ||
112 | int tox_encrypted_load(Tox *tox, const uint8_t *data, uint32_t length, uint8_t *passphrase, uint32_t pplength); | ||
113 | 160 | ||
114 | 161 | ||
115 | /******************************* BEGIN PART 1 ******************************* | 162 | /******************************* BEGIN PART 1 ******************************* |
@@ -117,8 +164,16 @@ int tox_encrypted_load(Tox *tox, const uint8_t *data, uint32_t length, uint8_t * | |||
117 | * intensive than part one. The first 3 functions are for key handling. | 164 | * intensive than part one. The first 3 functions are for key handling. |
118 | */ | 165 | */ |
119 | 166 | ||
167 | /* This key structure's internals should not be used by any client program, even | ||
168 | * if they are straightforward here. | ||
169 | */ | ||
170 | typedef struct { | ||
171 | uint8_t salt[TOX_PASS_SALT_LENGTH]; | ||
172 | uint8_t key[TOX_PASS_KEY_LENGTH]; | ||
173 | } TOX_PASS_KEY; | ||
174 | |||
120 | /* Generates a secret symmetric key from the given passphrase. out_key must be at least | 175 | /* Generates a secret symmetric key from the given passphrase. out_key must be at least |
121 | * tox_pass_key_length() bytes long. | 176 | * TOX_PASS_KEY_LENGTH bytes long. |
122 | * Be sure to not compromise the key! Only keep it in memory, do not write to disk. | 177 | * Be sure to not compromise the key! Only keep it in memory, do not write to disk. |
123 | * The password is zeroed after key derivation. | 178 | * The password is zeroed after key derivation. |
124 | * The key should only be used with the other functions in this module, as it | 179 | * The key should only be used with the other functions in this module, as it |
@@ -126,68 +181,53 @@ int tox_encrypted_load(Tox *tox, const uint8_t *data, uint32_t length, uint8_t * | |||
126 | * Note that this function is not deterministic; to derive the same key from a | 181 | * Note that this function is not deterministic; to derive the same key from a |
127 | * password, you also must know the random salt that was used. See below. | 182 | * password, you also must know the random salt that was used. See below. |
128 | * | 183 | * |
129 | * returns 0 on success | 184 | * returns true on success |
130 | * returns -1 on failure | ||
131 | */ | 185 | */ |
132 | int tox_derive_key_from_pass(uint8_t *passphrase, uint32_t pplength, uint8_t *out_key); | 186 | bool tox_derive_key_from_pass(uint8_t *passphrase, size_t pplength, TOX_PASS_KEY *out_key, |
187 | TOX_ERR_KEY_DERIVATION *error); | ||
133 | 188 | ||
134 | /* Same as above, except with use the given salt for deterministic key derivation. | 189 | /* Same as above, except use the given salt for deterministic key derivation. |
135 | * The salt must be tox_salt_length() bytes in length. | 190 | * The salt must be TOX_PASS_SALT_LENGTH bytes in length. |
136 | */ | 191 | */ |
137 | int tox_derive_key_with_salt(uint8_t *passphrase, uint32_t pplength, uint8_t *salt, uint8_t *out_key); | 192 | bool tox_derive_key_with_salt(uint8_t *passphrase, size_t pplength, uint8_t *salt, TOX_PASS_KEY *out_key, |
193 | TOX_ERR_KEY_DERIVATION *error); | ||
138 | 194 | ||
139 | /* This retrieves the salt used to encrypt the given data, which can then be passed to | 195 | /* This retrieves the salt used to encrypt the given data, which can then be passed to |
140 | * derive_key_with_salt to produce the same key as was previously used. Any encrpyted | 196 | * derive_key_with_salt to produce the same key as was previously used. Any encrpyted |
141 | * data with this module can be used as input. | 197 | * data with this module can be used as input. |
142 | * | 198 | * |
143 | * returns -1 if the magic number is wrong | 199 | * returns true if magic number matches |
144 | * returns 0 otherwise (no guarantee about validity of data) | 200 | * success does not say anything about the validity of the data, only that data of |
201 | * the appropriate size was copied | ||
145 | */ | 202 | */ |
146 | int tox_get_salt(uint8_t *data, uint8_t *salt); | 203 | bool tox_get_salt(const uint8_t *data, uint8_t *salt); |
147 | 204 | ||
148 | /* Now come the functions that are analogous to the part 2 functions. */ | 205 | /* Now come the functions that are analogous to the part 2 functions. */ |
149 | 206 | ||
150 | /* Encrypt arbitrary with a key produced by tox_derive_key_. The output | 207 | /* Encrypt arbitrary with a key produced by tox_derive_key_*. The output |
151 | * array must be at least data_len + tox_pass_encryption_extra_length() bytes long. | 208 | * array must be at least data_len + TOX_PASS_ENCRYPTION_EXTRA_LENGTH bytes long. |
152 | * key must be tox_pass_key_length() bytes. | 209 | * key must be TOX_PASS_KEY_LENGTH bytes. |
153 | * If you already have a symmetric key from somewhere besides this module, simply | 210 | * If you already have a symmetric key from somewhere besides this module, simply |
154 | * call encrypt_data_symmetric in toxcore/crypto_core directly. | 211 | * call encrypt_data_symmetric in toxcore/crypto_core directly. |
155 | * | 212 | * |
156 | * returns 0 on success | 213 | * returns true on success |
157 | * returns -1 on failure | ||
158 | */ | 214 | */ |
159 | int tox_pass_key_encrypt(const uint8_t *data, uint32_t data_len, const uint8_t *key, uint8_t *out); | 215 | bool tox_pass_key_encrypt(const uint8_t *data, size_t data_len, const TOX_PASS_KEY *key, uint8_t *out, |
160 | 216 | TOX_ERR_ENCRYPTION *error); | |
161 | /* Save the messenger data encrypted with the given key from tox_derive_key. | ||
162 | * data must be at least tox_encrypted_size(). | ||
163 | * | ||
164 | * returns 0 on success | ||
165 | * returns -1 on failure | ||
166 | */ | ||
167 | int tox_encrypted_key_save(const Tox *tox, uint8_t *data, uint8_t *key); | ||
168 | 217 | ||
169 | /* This is the inverse of tox_pass_key_encrypt, also using only keys produced by | 218 | /* This is the inverse of tox_pass_key_encrypt, also using only keys produced by |
170 | * tox_derive_key_from_pass. | 219 | * tox_derive_key_from_pass. |
171 | * | 220 | * |
172 | * returns the length of the output data (== data_len - tox_pass_encryption_extra_length()) on success | 221 | * the output data has size data_length - TOX_PASS_ENCRYPTION_EXTRA_LENGTH |
173 | * returns -1 on failure | ||
174 | */ | ||
175 | int tox_pass_key_decrypt(const uint8_t *data, uint32_t length, const uint8_t *key, uint8_t *out); | ||
176 | |||
177 | /* Load the messenger from encrypted data of size length, with key from tox_derive_key. | ||
178 | * | 222 | * |
179 | * returns 0 on success | 223 | * returns true on success |
180 | * returns -1 on failure | ||
181 | */ | 224 | */ |
182 | int tox_encrypted_key_load(Tox *tox, const uint8_t *data, uint32_t length, uint8_t *key); | 225 | bool tox_pass_key_decrypt(const uint8_t *data, size_t length, const TOX_PASS_KEY *key, uint8_t *out, |
226 | TOX_ERR_DECRYPTION *error); | ||
183 | 227 | ||
184 | /* Determines whether or not the given data is encrypted (by checking the magic number) | 228 | /* Determines whether or not the given data is encrypted (by checking the magic number) |
185 | * | ||
186 | * returns 1 if it is encrypted | ||
187 | * returns 0 otherwise | ||
188 | */ | 229 | */ |
189 | int tox_is_data_encrypted(const uint8_t *data); | 230 | bool tox_is_data_encrypted(const uint8_t *data); |
190 | int tox_is_save_encrypted(const uint8_t *data); // poorly-named alias for backwards compat (oh irony...) | ||
191 | 231 | ||
192 | #ifdef __cplusplus | 232 | #ifdef __cplusplus |
193 | } | 233 | } |