Coverage Report

Created: 2024-01-26 01:52

/work/toxencryptsave/toxencryptsave.h
Line
Count
Source
1
/* SPDX-License-Identifier: GPL-3.0-or-later
2
 * Copyright © 2016-2018 The TokTok team.
3
 * Copyright © 2013-2016 Tox Developers.
4
 */
5
6
/**
7
 * Batch encryption functions.
8
 */
9
10
#ifndef C_TOXCORE_TOXENCRYPTSAVE_TOXENCRYPTSAVE_H
11
#define C_TOXCORE_TOXENCRYPTSAVE_TOXENCRYPTSAVE_H
12
13
#include <stdbool.h>
14
#include <stddef.h>
15
#include <stdint.h>
16
17
18
#ifdef __cplusplus
19
extern "C" {
20
#endif
21
22
/*******************************************************************************
23
 *
24
 * This module is organized into two parts.
25
 *
26
 * 1. A simple API operating on plain text/cipher text data and a password to
27
 *    encrypt or decrypt it.
28
 * 2. A more advanced API that splits key derivation and encryption into two
29
 *    separate function calls.
30
 *
31
 * The first part is implemented in terms of the second part and simply calls
32
 * the separate functions in sequence. Since key derivation is very expensive
33
 * compared to the actual encryption, clients that do a lot of crypto should
34
 * prefer the advanced API and reuse pass-key objects.
35
 *
36
 * To use the second part, first derive an encryption key from a password with
37
 * tox_pass_key_derive, then use the derived key to encrypt the data.
38
 *
39
 * The encrypted data is prepended with a magic number, to aid validity
40
 * checking (no guarantees are made of course). Any data to be decrypted must
41
 * start with the magic number.
42
 *
43
 * Clients should consider alerting their users that, unlike plain data, if
44
 * even one bit becomes corrupted, the data will be entirely unrecoverable.
45
 * Ditto if they forget their password, there is no way to recover the data.
46
 *
47
 ******************************************************************************/
48
49
50
51
/**
52
 * The size of the salt part of a pass-key.
53
 */
54
2
#define TOX_PASS_SALT_LENGTH           32
55
56
uint32_t tox_pass_salt_length(void);
57
58
/**
59
 * The size of the key part of a pass-key.
60
 */
61
1
#define TOX_PASS_KEY_LENGTH            32
62
63
uint32_t tox_pass_key_length(void);
64
65
/**
66
 * The amount of additional data required to store any encrypted byte array.
67
 * Encrypting an array of N bytes requires N + TOX_PASS_ENCRYPTION_EXTRA_LENGTH
68
 * bytes in the encrypted byte array.
69
 */
70
206
#define TOX_PASS_ENCRYPTION_EXTRA_LENGTH 80
71
72
uint32_t tox_pass_encryption_extra_length(void);
73
74
typedef enum Tox_Err_Key_Derivation {
75
76
    /**
77
     * The function returned successfully.
78
     */
79
    TOX_ERR_KEY_DERIVATION_OK,
80
81
    /**
82
     * One of the arguments to the function was NULL when it was not expected.
83
     */
84
    TOX_ERR_KEY_DERIVATION_NULL,
85
86
    /**
87
     * The crypto lib was unable to derive a key from the given passphrase,
88
     * which is usually a lack of memory issue.
89
     */
90
    TOX_ERR_KEY_DERIVATION_FAILED,
91
92
} Tox_Err_Key_Derivation;
93
94
95
typedef enum Tox_Err_Encryption {
96
97
    /**
98
     * The function returned successfully.
99
     */
100
    TOX_ERR_ENCRYPTION_OK,
101
102
    /**
103
     * One of the arguments to the function was NULL when it was not expected.
104
     */
105
    TOX_ERR_ENCRYPTION_NULL,
106
107
    /**
108
     * The crypto lib was unable to derive a key from the given passphrase,
109
     * which is usually a lack of memory issue. The functions accepting keys
110
     * do not produce this error.
111
     */
112
    TOX_ERR_ENCRYPTION_KEY_DERIVATION_FAILED,
113
114
    /**
115
     * The encryption itself failed.
116
     */
117
    TOX_ERR_ENCRYPTION_FAILED,
118
119
} Tox_Err_Encryption;
120
121
122
typedef enum Tox_Err_Decryption {
123
124
    /**
125
     * The function returned successfully.
126
     */
127
    TOX_ERR_DECRYPTION_OK,
128
129
    /**
130
     * One of the arguments to the function was NULL when it was not expected.
131
     */
132
    TOX_ERR_DECRYPTION_NULL,
133
134
    /**
135
     * The input data was shorter than TOX_PASS_ENCRYPTION_EXTRA_LENGTH bytes
136
     */
137
    TOX_ERR_DECRYPTION_INVALID_LENGTH,
138
139
    /**
140
     * The input data is missing the magic number (i.e. wasn't created by this
141
     * module, or is corrupted).
142
     */
143
    TOX_ERR_DECRYPTION_BAD_FORMAT,
144
145
    /**
146
     * The crypto lib was unable to derive a key from the given passphrase,
147
     * which is usually a lack of memory issue. The functions accepting keys
148
     * do not produce this error.
149
     */
150
    TOX_ERR_DECRYPTION_KEY_DERIVATION_FAILED,
151
152
    /**
153
     * The encrypted byte array could not be decrypted. Either the data was
154
     * corrupted or the password/key was incorrect.
155
     */
156
    TOX_ERR_DECRYPTION_FAILED,
157
158
} Tox_Err_Decryption;
159
160
161
162
/*******************************************************************************
163
 *
164
 *                                BEGIN PART 1
165
 *
166
 * The simple API is presented first. If your code spends too much time using
167
 * these functions, consider using the advanced functions instead and caching
168
 * the generated pass-key.
169
 *
170
 ******************************************************************************/
171
172
173
174
/**
175
 * Encrypts the given data with the given passphrase.
176
 *
177
 * The output array must be at least `plaintext_len + TOX_PASS_ENCRYPTION_EXTRA_LENGTH`
178
 * bytes long. This delegates to tox_pass_key_derive and
179
 * tox_pass_key_encrypt.
180
 *
181
 * @param plaintext A byte array of length `plaintext_len`.
182
 * @param plaintext_len The length of the plain text array. Bigger than 0.
183
 * @param passphrase The user-provided password. Can be empty.
184
 * @param passphrase_len The length of the password.
185
 * @param ciphertext The cipher text array to write the encrypted data to.
186
 *
187
 * @return true on success.
188
 */
189
bool tox_pass_encrypt(const uint8_t plaintext[], size_t plaintext_len, const uint8_t passphrase[], size_t passphrase_len,
190
                      uint8_t ciphertext[/*! plaintext_len + TOX_PASS_ENCRYPTION_EXTRA_LENGTH */], Tox_Err_Encryption *error);
191
192
/**
193
 * Decrypts the given data with the given passphrase.
194
 *
195
 * The output array must be at least `ciphertext_len - TOX_PASS_ENCRYPTION_EXTRA_LENGTH`
196
 * bytes long. This delegates to tox_pass_key_decrypt.
197
 *
198
 * @param ciphertext A byte array of length `ciphertext_len`.
199
 * @param ciphertext_len The length of the cipher text array. At least TOX_PASS_ENCRYPTION_EXTRA_LENGTH.
200
 * @param passphrase The user-provided password. Can be empty.
201
 * @param passphrase_len The length of the password.
202
 * @param plaintext The plain text array to write the decrypted data to.
203
 *
204
 * @return true on success.
205
 */
206
bool tox_pass_decrypt(const uint8_t ciphertext[], size_t ciphertext_len, const uint8_t passphrase[],
207
                      size_t passphrase_len, uint8_t plaintext[/*! ciphertext_len - TOX_PASS_ENCRYPTION_EXTRA_LENGTH */], Tox_Err_Decryption *error);
208
209
210
/*******************************************************************************
211
 *
212
 *                                BEGIN PART 2
213
 *
214
 * And now part 2, which does the actual encryption, and can be used to write
215
 * less CPU intensive client code than part one.
216
 *
217
 ******************************************************************************/
218
219
220
221
/**
222
 * This type represents a pass-key.
223
 *
224
 * A pass-key and a password are two different concepts: a password is given
225
 * by the user in plain text. A pass-key is the generated symmetric key used
226
 * for encryption and decryption. It is derived from a salt and the
227
 * user-provided password.
228
 *
229
 * The Tox_Pass_Key structure is hidden in the implementation. It can be created
230
 * using tox_pass_key_derive or tox_pass_key_derive_with_salt and must be deallocated using tox_pass_key_free.
231
 */
232
#ifndef TOX_PASS_KEY_DEFINED
233
#define TOX_PASS_KEY_DEFINED
234
typedef struct Tox_Pass_Key Tox_Pass_Key;
235
#endif /* TOX_PASS_KEY_DEFINED */
236
237
/**
238
 * Deallocate a Tox_Pass_Key. This function behaves like `free()`, so NULL is an
239
 * acceptable argument value.
240
 */
241
void tox_pass_key_free(Tox_Pass_Key *key);
242
243
/**
244
 * Generates a secret symmetric key from the given passphrase.
245
 *
246
 * Be sure to not compromise the key! Only keep it in memory, do not write
247
 * it to disk.
248
 *
249
 * Note that this function is not deterministic; to derive the same key from
250
 * a password, you also must know the random salt that was used. A
251
 * deterministic version of this function is `tox_pass_key_derive_with_salt`.
252
 *
253
 * @param passphrase The user-provided password. Can be empty.
254
 * @param passphrase_len The length of the password.
255
 *
256
 * @return new symmetric key on success, NULL on failure.
257
 */
258
Tox_Pass_Key *tox_pass_key_derive(
259
        const uint8_t passphrase[], size_t passphrase_len,
260
        Tox_Err_Key_Derivation *error);
261
262
/**
263
 * Same as above, except use the given salt for deterministic key derivation.
264
 *
265
 * @param passphrase The user-provided password. Can be empty.
266
 * @param passphrase_len The length of the password.
267
 * @param salt An array of at least TOX_PASS_SALT_LENGTH bytes.
268
 *
269
 * @return new symmetric key on success, NULL on failure.
270
 */
271
Tox_Pass_Key *tox_pass_key_derive_with_salt(
272
        const uint8_t passphrase[], size_t passphrase_len,
273
        const uint8_t salt[TOX_PASS_SALT_LENGTH], Tox_Err_Key_Derivation *error);
274
275
/**
276
 * Encrypt a plain text with a key produced by tox_pass_key_derive or tox_pass_key_derive_with_salt.
277
 *
278
 * The output array must be at least `plaintext_len + TOX_PASS_ENCRYPTION_EXTRA_LENGTH`
279
 * bytes long.
280
 *
281
 * @param plaintext A byte array of length `plaintext_len`.
282
 * @param plaintext_len The length of the plain text array. Bigger than 0.
283
 * @param ciphertext The cipher text array to write the encrypted data to.
284
 *
285
 * @return true on success.
286
 */
287
bool tox_pass_key_encrypt(const Tox_Pass_Key *key, const uint8_t plaintext[], size_t plaintext_len,
288
                          uint8_t ciphertext[/*! plaintext_len + TOX_PASS_ENCRYPTION_EXTRA_LENGTH */], Tox_Err_Encryption *error);
289
290
/**
291
 * This is the inverse of tox_pass_key_encrypt, also using only keys produced by
292
 * tox_pass_key_derive or tox_pass_key_derive_with_salt.
293
 *
294
 * @param ciphertext A byte array of length `ciphertext_len`.
295
 * @param ciphertext_len The length of the cipher text array. At least TOX_PASS_ENCRYPTION_EXTRA_LENGTH.
296
 * @param plaintext The plain text array to write the decrypted data to.
297
 *
298
 * @return true on success.
299
 */
300
bool tox_pass_key_decrypt(const Tox_Pass_Key *key, const uint8_t ciphertext[], size_t ciphertext_len,
301
                          uint8_t plaintext[/*! ciphertext_len - TOX_PASS_ENCRYPTION_EXTRA_LENGTH */], Tox_Err_Decryption *error);
302
303
typedef enum Tox_Err_Get_Salt {
304
305
    /**
306
     * The function returned successfully.
307
     */
308
    TOX_ERR_GET_SALT_OK,
309
310
    /**
311
     * One of the arguments to the function was NULL when it was not expected.
312
     */
313
    TOX_ERR_GET_SALT_NULL,
314
315
    /**
316
     * The input data is missing the magic number (i.e. wasn't created by this
317
     * module, or is corrupted).
318
     */
319
    TOX_ERR_GET_SALT_BAD_FORMAT,
320
321
} Tox_Err_Get_Salt;
322
323
324
/**
325
 * Retrieves the salt used to encrypt the given data.
326
 *
327
 * The retrieved salt can then be passed to tox_pass_key_derive_with_salt to
328
 * produce the same key as was previously used. Any data encrypted with this
329
 * module can be used as input.
330
 *
331
 * The cipher text must be at least TOX_PASS_ENCRYPTION_EXTRA_LENGTH bytes in length.
332
 * The salt must be TOX_PASS_SALT_LENGTH bytes in length.
333
 * If the passed byte arrays are smaller than required, the behaviour is
334
 * undefined.
335
 *
336
 * If the cipher text pointer or the salt is NULL, this function returns false.
337
 *
338
 * Success does not say anything about the validity of the data, only that
339
 * data of the appropriate size was copied.
340
 *
341
 * @return true on success.
342
 */
343
bool tox_get_salt(
344
        const uint8_t ciphertext[TOX_PASS_ENCRYPTION_EXTRA_LENGTH],
345
        uint8_t salt[TOX_PASS_SALT_LENGTH], Tox_Err_Get_Salt *error);
346
347
/**
348
 * Determines whether or not the given data is encrypted by this module.
349
 *
350
 * It does this check by verifying that the magic number is the one put in
351
 * place by the encryption functions.
352
 *
353
 * The data must be at least TOX_PASS_ENCRYPTION_EXTRA_LENGTH bytes in length.
354
 * If the passed byte array is smaller than required, the behaviour is
355
 * undefined.
356
 *
357
 * If the data pointer is NULL, the behaviour is undefined
358
 *
359
 * @return true if the data is encrypted by this module.
360
 */
361
bool tox_is_data_encrypted(const uint8_t data[TOX_PASS_ENCRYPTION_EXTRA_LENGTH]);
362
363
364
#ifdef __cplusplus
365
} /* extern "C" */
366
#endif
367
368
//!TOKSTYLE-
369
370
typedef Tox_Err_Key_Derivation TOX_ERR_KEY_DERIVATION;
371
typedef Tox_Err_Encryption TOX_ERR_ENCRYPTION;
372
typedef Tox_Err_Decryption TOX_ERR_DECRYPTION;
373
typedef Tox_Err_Get_Salt TOX_ERR_GET_SALT;
374
375
//!TOKSTYLE+
376
377
#endif /* C_TOXCORE_TOXENCRYPTSAVE_TOXENCRYPTSAVE_H */