OSDN Git Service

More thorough cleaning of encryption/decryption state and buffers.
[slunkcrypt/SlunkCrypt.git] / README.md
1 ---
2 title: "![SlunkCrypt](etc/img/SlunkCrypt-Logo.png)"
3 ---
4
5
6 Introduction
7 ============
8
9 SlunkCrypt is an experimental cryptography library and command-line tool. See [*encryption algorithm*](#encryption-algorithm) for details.
10
11
12 Legal Warning
13 =============
14
15 Use of SlunkCrypt may be illegal in countries where encryption is outlawed. We believe it is legal to use SlunkCrypt in many countries all around the world, but we are not lawyers, and so if in doubt you should seek legal advice before downloading it. You may find useful information at [cryptolaw.org](http://www.cryptolaw.org/), which collects information on cryptography laws in many countries.
16
17
18 Command-line Usage
19 ==================
20
21 This section describes the SlunkCypt command-line application.
22
23 Synopsis
24 --------
25
26 The SlunkCypt command-line program is invoked as follows:
27
28     slunkcrypt --encrypt [[@][:]<passphrase>] <input> <output>
29     slunkcrypt --decrypt [[@][:]<passphrase>] <input> <output>
30     slunkcrypt --make-pw [<length>]
31
32 Commands
33 --------
34
35 One of the following commands must be chosen:
36
37 - **`--encrypt` (`-e`):**  
38   Run application in ***encrypt*** mode. Reads the given *plaintext* and generates *ciphertext*.
39 - **`--decrypt` (`-d`):**  
40   Run application in ***decrypt*** mode. Reads the given *ciphertext* and restores *plaintext*.
41 - **`--make-pw` (`-p`):**  
42   Generate and output a "strong" random passphrase suitable for use with SlunkCrypt.
43 - **`--self-test` (`-t`):**  
44   Run application in ***self-test*** mode. Program will exit when test is completed.
45
46 Options
47 -------
48
49 The following options are available:
50
51 - **`<passphrase>`**:  
52   * The passphrase used to "protect" the message. The same passphrase must be used for both, ***encrypt*** and ***decrypt*** mode.
53   * It will only be possible decrypt the ciphertext, if the "correct" passphrase is known.
54   * Use **`--make-pw`** to generate a random passphrase. The passphrase must be kept confidential under all circumstances!
55   * **Syntax:**
56     - If the passphrase is prefixed with an **`@`** character, then it specifies the file to read the passphrase from.
57     - If the passphrase is set to **`@-`**, then the passphrase is read from the standard input stream.
58     - If the passphrase is prefixed with an **`:`** character, then the leading character is ignored; use if passphrase contains **`@`** character.
59     - If the parameter is *omitted*, then the passphrase is read from the `SLUNK_PASSPHRASE` environment variable.
60   * *Note:* In order to thwart brute force attacks, it is recommended to choose a "random" password that is at least 12 characters in length and that consists of upper-case characters, lower-case characters, digits as well as other "special" characters.
61 - **`<input>`**:  
62   * In ***encrypt*** mode, specifies the *plaintext* (unencrypted information) file that is to be encrypted.
63   * In ***decrypt*** mode, specifies the *ciphertext* (result of encryption) file that is to be decrypted.
64 - **`<output>`**:  
65   * In ***encrypt*** mode, specifies the file where the *ciphertext* (result of encryption) will be stored.
66   * In ***decrypt*** mode, specifies the file where the *plaintext* (unencrypted information) will be stored.
67 - **`<length>`**:  
68   * Speicifes the length of the passphrase to be generated, in characters. If *not* specified, defaults to 24.
69
70 Examples
71 --------
72
73 Examples on how to use the SlunkCrypt command-line application:
74
75 1. Let's generate a new secure password first:
76
77        slunkcrypt --make-pw
78
79    Example output:
80
81        cdG2=fh<C=3[SSCzf[)iDjIV
82
83 2. Now, encrypt the plaintext message, using the generated password:
84
85        slunkcrypt --encrypt "cdG2=fh<C=3[SSCzf[)iDjIV" plaintext.txt ciphertext.enc
86
87    Optionally, let's have a look at the ciphertext:
88
89        hexdump -C ciphertext.enc
90
91 3. Finally, decrypt the ciphertext, using the same password as before:
92
93        slunkcrypt --decrypt "cdG2=fh<C=3[SSCzf[)iDjIV" ciphertext.enc plaintext.out
94
95    Optionally, verify that files are actually the same:
96
97        cmp --silent plaintext.txt plaintext.out && echo "files are the same"
98
99
100 Encryption algorithm
101 ====================
102
103 The SlunkCrypt algorithm is based on concepts of the well-known [**Enigma**](https://en.wikipedia.org/wiki/Enigma_machine) machine, but with various improvements:
104
105 - The original Enigma machine had only *three* (or somtimes *four*) rotors, plus a static "reflector" wheel. In SlunkCrypt, we uses **256** simulated rotors for an improved security.
106
107 - The original Enigma machine supported only 26 distinct symbols, i.e. the letters `A` to `Z`. In SlunkCrypt, we use **256** distinct symbols, i.e. the byte values `0x00` to `0xFF`, which allows the encryption (and decryption) of arbitrary streams of bytes, rather than just plain text. Of course, SlunkCrypt can encrypt (and decrypt) text files as well.
108
109 - In the original Enigma machine, the signal passes through the rotors *twice*, once in forward direction and then again in backwards direction &ndash; thus the "reflector" wheel. This way, the Enigma's encryption was made *involutory*, i.e. encryption and decryption were the same operation. While this was highly convenient, it also severely weakened the cryptographic strength of the Enigma machine, because the number of possible permutations was reduced drastically! This is one of the main reasons why the Enigma machine eventually was defeated. In SlunkCrypt, the signal passes through the simulated rotors just *once*, in order to maximize the number of possible permutations. This eliminates the most important known weakness of the Enigma machine. Obviously, in SlunkCrypt, separate modes for encryption and decryption need to be provided, because encryption and decryption *no* longer are the same.
110
111 - In the original Enigma machine, *only* the rightmost rotor was stepped after every symbol. The other rotors were stepped infrequently. Specifically, if one rotor had completed a full turn, it caused the next rotor to move by one step &ndash; much like the odometer in a car. The fact that most of the rotors remained in the same "static" position for a long time was another important weakness of the Enigma machine that ultimately lead to its demise. Furthermore, the positions of the Enigma's rotors would start to repeat after "only" 16,900 characters. In SlunkCrypt, an improved stepping algorithm is used, which ensures that *all* rotors are stepped often. At the same time, the rotor positions in SlunkCrypt *never* repeat (practically).
112
113 - The internal wiring of each of the original Enigma machine's rotors was *fixed*. Each rotor "type" came with a different internal wiring (i.e. permutation). Some models had up to eight rotor "types" to choose from, but only three or four rotors were used at a time. Nonetheless, the internal wiring (i.e. permutation) of each of the supplied rotors was **not** modifiable. This severely restricted the key space of the Enigma machine, as far as the rotors are concerned, because *only* the order of the rotors and the initial position of each rotor could be varied. In SlunkCrypt, a fully *randomized* wiring (i.e. permutation) is generated from the password for each of the 256 simulated rotors. The initial rotor positions are *randomized* as well.
114
115 - SlunkCrypt does **not** currently implement the *plugboard* of the original Enigma machine. That is because, even though the plugboard has a large key space, it is just a *fixed* substitution cipher that does *not* contribute too much to the cryptographic strength of the Enigma machine. In fact, the plugboard could be "erased" by Welchman's [diagonal board](https://en.wikipedia.org/wiki/Bombe#Stecker_values).
116
117
118 Programming Interface (API)
119 ===========================
120
121 C99 API
122 -------
123
124 This section describes the "low-level" C99 API of the SlunkCypt library.
125
126 ### slunkcrypt_alloc()
127
128 Allocate and initialize a new SlunkCrypt encryption/decryption context.
129
130     slunkcrypt_t slunkcrypt_alloc(
131         const uint64_t nonce,
132         const uint8_t *const passwd,
133         const size_t passwd_len
134     );
135
136 ***Parameters:***
137
138   * `nonce`  
139     The *nonce* (number used once) to be used for the encryption/decryption process. The purpose of the nonce is to ensure that each message will be encrypted differently, even when the same password is used to encrypt *multiple* (possibly identical) messages. Therefore, a new *random* nonce **must** be chosen for each message to be encrypted! It is *not* necessary to keep the nonce confidential, but the same nonce **must** be used for both, encryption *and* decryption. Typically, the nonce is stored/transmitted alongside the ciphertext.
140     
141     *Note:* It is recommended to generate a random nonce via the `slunkcrypt_generate_nonce()` function for each message!
142   
143   * `passwd`  
144     The password to "protect" the message. The password is given as a byte array (`uint8_t`), e.g. UTF-8 encoded characters; a terminating NULL character is *not* required, as the length of the password is specified explicitly. The same password **may** be used to encrypt *multiple* messages. Also, the same password **must** be used for both, encryption *and* decryption; it will *only* be possible decrypt the ciphertext, if the "correct" password is known. The password must be kept confidential under all circumstances!
145     
146     *Note:* In order to thwart *brute force* attacks, it is recommended to choose a "random" password that is at least 12 characters in length and that consists of upper-case characters, lower-case characters, digits as well as other "special" characters.
147   
148   * `passwd_len`  
149     The length of password given by the `passwd` parameter, in bytes, **not** counting a terminating NULL character. The minimum/maximum length of the password are given by the `SLUNKCRYPT_PWDLEN_MIN` and `SLUNKCRYPT_PWDLEN_MAX` constants, respectively.
150
151 ***Return value:***
152
153   * If successful, a handle to the new SlunkCrypt context is return; otherwise `SLUNKCRYPT_NULL` is returned.
154     
155     *Note:* Applications **should** treat `slunkcrypt_t` as an *opaque* handle type. Also, as soon as the SlunkCrypt context is *not* needed anymore, the application **shall** call `slunkcrypt_free()` in order to "clear" and de-allocate that context.
156
157 ### slunkcrypt_reset()
158   
159 Re-initialize an existing SlunkCrypt encryption/decryption context.
160
161     int slunkcrypt_reset(
162         const slunkcrypt_t context,
163         const uint64_t nonce,
164         const uint8_t *const passwd,
165         const size_t passwd_len
166     );
167
168 ***Parameters:***
169
170   * `context`  
171     The existing SlunkCrypt context to be re-initialized. This must be a valid handle that was returned by a previous invocation of the `slunkcrypt_alloc()` function.
172
173   * `nonce`  
174     Please refer to the  `slunkcrypt_alloc()` function for details!
175
176   * `passwd`  
177     Please refer to the  `slunkcrypt_alloc()` function for details!
178
179   * `passwd_len`  
180     Please refer to the  `slunkcrypt_alloc()` function for details!
181
182 ***Return value:***
183
184   * If successful, `SLUNKCRYPT_SUCCESS` is returned; otherwise `SLUNKCRYPT_FAILURE` or `SLUNKCRYPT_ABORTED` is returned.
185
186 ### slunkcrypt_free()
187
188 De-allocate an existing SlunkCrypt encryption/decryption context. This will "clear" and release any memory occupied by the context.
189
190     void slunkcrypt_free(
191         const slunkcrypt_t context
192     );
193
194 ***Parameters:***
195
196  * `context`  
197     The existing SlunkCrypt context to be de-allocated. This must be a valid handle that was returned by a previous invocation of the `slunkcrypt_alloc()` function.
198     
199     *Note:* Once a handle has been passed to this function, that handle is *invalidated* and **must not** be used again!
200
201 ### slunkcrypt_generate_nonce()
202
203 Generate a new random *nonce* (number used once), using the system's "cryptographically secure" entropy source.
204
205     int slunkcrypt_generate_nonce(
206       int64_t* const nonce
207     );
208
209 ***Parameters:***
210
211  * `nonce`  
212    A pointer to a variable of type `int64_t` that receives the new random nonce.
213
214 ***Return value:***
215
216   * If successful, `SLUNKCRYPT_SUCCESS` is returned; otherwise `SLUNKCRYPT_FAILURE` or `SLUNKCRYPT_ABORTED` is returned.
217
218 ### slunkcrypt_encrypt()
219
220 Encrypt the next message chunk, using separate input/output buffers.
221
222     int slunkcrypt_encrypt(
223         const slunkcrypt_t context,
224         const uint8_t *const input,
225         uint8_t* const output,
226         size_t length
227     );
228
229 ***Parameters:***
230
231  * `context`  
232     The existing SlunkCrypt context to be used for encrypting the message chunk. This context will be updated.
233
234  * `input`  
235     A pointer to the *input* buffer containing the next chunk of the plaintext to be encrypted. The plaintext is given as a byte array (`uint8_t`). This can be arbitrary binary data, e.g. UTF-8 encoded text. NULL bytes are **not** treated specially.
236     
237     The *input* buffer must contain *at least* `length` bytes of data. If the buffer is longer than `length` bytes, then only the first `length` bytes will be processed and the remainder is ignored!
238
239  * `output`  
240     A pointer to the *output* buffer where the ciphertext chunk that corresponds to the given plaintext chunk will be stored. The ciphertext is stored as a byte array (`uint8_t`); it has the same length as the plaintext data.
241     
242     The *output* buffer must provide sufficient space for storing *at least* `length` bytes of encrypted data. If the buffer is longer than `length` bytes, then only the first `length` bytes of the buffer will be filled with encrypted data!
243
244  * `length`  
245    The length of the plaintext chunk contained in the *input* buffer given by the `input` parameter, in bytes. At the same time, this determines the minimum required size of the *output* buffer given by the `output` parameters, in bytes.
246
247 ***Return value:***
248
249   * If successful, `SLUNKCRYPT_SUCCESS` is returned; otherwise `SLUNKCRYPT_FAILURE` or `SLUNKCRYPT_ABORTED` is returned.
250
251 ### slunkcrypt_encrypt_inplace()
252
253 Encrypt the next message chunk, using a single buffer.
254
255     int slunkcrypt_encrypt_inplace(
256         const slunkcrypt_t context,
257         uint8_t* const buffer,
258         size_t length
259     );
260
261 ***Parameters:***
262
263  * `context`  
264     The existing SlunkCrypt context to be used for encrypting the message chunk. This context will be updated.
265
266  * `buffer`  
267     A pointer to the buffer initially containing the next chunk of the plaintext to be encrypted. The plaintext is given as a byte array (`uint8_t`). This can be arbitrary binary data, e.g. UTF-8 encoded text. NULL bytes are **not** treated specially. The ciphertext chunk that corresponds to the given plaintext chunk will be stored to the *same* buffer, thus replacing the plaintext data.
268     
269     The buffer must initially contain *at least* `length` bytes of input data; the first `length` bytes of the buffer will be overwritten with the encrypted data. If the buffer is longer than `length` bytes, then only the first `length` bytes will be processed and overwritten.
270
271  * `length`  
272    The length of the plaintext chunk initially contained in the input/output buffer given by the `buffer` parameter, in bytes. At the same time, this determines the portion of the input/output buffer that will be overwritten with encrypted data, in bytes.
273
274 ***Return value:***
275
276   * If successful, `SLUNKCRYPT_SUCCESS` is returned; otherwise `SLUNKCRYPT_FAILURE` or `SLUNKCRYPT_ABORTED` is returned.
277
278 ### slunkcrypt_decrypt()
279
280 Decrypt the next ciphertext chunk, using separate input/output buffers.
281
282     int slunkcrypt_decrypt(
283         const slunkcrypt_t context,
284         const uint8_t *const input,
285         uint8_t* const output,
286         size_t length
287     );
288
289 ***Parameters:***
290
291  * `context`  
292     The existing SlunkCrypt context to be used for decrypting the ciphertext chunk. This context will be updated.
293
294  * `input`  
295     A pointer to the *input* buffer containing the next chunk of the ciphertext to be decrypted. The ciphertext is given as a byte array (`uint8_t`).
296     
297     The *input* buffer must contain *at least* `length` bytes of data. If the buffer is longer than `length` bytes, then only the first `length` bytes will be processed and the remainder is ignored!
298
299  * `output`  
300     A pointer to the *output* buffer where the plaintext chunk that corresponds to the given ciphertext chunk will be stored. The plaintext is stored as a byte array (`uint8_t`); it has the same length as the plaintext data.
301     
302     The *output* buffer must provide sufficient space for storing *at least* `length` bytes of decrypted data. If the buffer is longer than `length` bytes, then only the first `length` bytes of the buffer will be filled with decrypted data!
303
304  * `length`  
305    The length of the ciphertext chunk contained in the *input* buffer given by the `input` parameter, in bytes. At the same time, this determines the minimum required size of the *output* buffer given by the `output` parameters, in bytes.
306
307 ***Return value:***
308
309   * If successful, `SLUNKCRYPT_SUCCESS` is returned; otherwise `SLUNKCRYPT_FAILURE` or `SLUNKCRYPT_ABORTED` is returned.
310
311 ### slunkcrypt_decrypt_inplace()
312
313 Decrypt the next ciphertext chunk, using a single buffer.
314
315     int slunkcrypt_decrypt_inplace(
316         const slunkcrypt_t context,
317         uint8_t* const buffer,
318         size_t length
319     );
320
321 ***Parameters:***
322
323  * `context`  
324     The existing SlunkCrypt context to be used for decrypting the ciphertext chunk. This context will be updated.
325
326  * `buffer`  
327     A pointer to the buffer initially containing the next chunk of the ciphertext to be decrypted. The ciphertext is given as a byte array (`uint8_t`). The plaintext that corresponds to the given ciphertext will be stored to the *same* buffer, thus replacing the plaintext data.
328     
329     The buffer must initially contain *at least* `length` bytes of input data; the first `length` bytes of the buffer will be overwritten with the decrypted data. If the buffer is longer than `length` bytes, then only the first `length` bytes will be processed and overwritten.
330
331  * `length`  
332    The length of the ciphertext chunk initially contained in the input/output buffer given by the `buffer` parameter, in bytes. At the same time, this determines the portion of the input/output buffer that will be overwritten with decrypted data, in bytes.
333
334 ***Return value:***
335
336   * If successful, `SLUNKCRYPT_SUCCESS` is returned; otherwise `SLUNKCRYPT_FAILURE` or `SLUNKCRYPT_ABORTED` is returned.
337
338 ### slunkcrypt_random_bytes()
339
340 Generate a sequence of random bytes, using the system's "cryptographically secure" entropy source.
341
342     size_t slunkcrypt_random_bytes(
343       uint8_t* const buffer,
344       const size_t length
345     );
346
347 ***Parameters:***
348
349  * `buffer`  
350    A pointer to the *output* buffer where the random bytes will be stored.
351
352    The *output* buffer must provide sufficient space for storing *at least* `length` bytes of random data. If the buffer is longer than `length` bytes, then *at most* the first `length` bytes of the buffer will be filled with random data!
353
354  * `length`  
355    The number of random bytes to be generated. At the same time, this determines the minimum required size of the *output* buffer given by the `output` parameters, in bytes.
356
357 ***Return value:***
358
359   * If successful, the number of random bytes that have been generated and stored to the *output* buffer is returned; otherwise `0` is returned.
360     
361     The number of generated bytes can be *at most* `length`. Less than `length` bytes *may* be generated, if the entropy source could **not** provide the requested number of bytes at this time. In that case, you can try again.
362
363
364 ### slunkcrypt_bzero()
365
366 Erase the contents of a byte array, by overwriting it with *zero* bytes. Compiler optimizations will **not** remove the erase operation.
367
368     void slunkcrypt_bzero(
369       void* const buffer,
370       const size_t length
371     );
372
373 ***Parameters:***
374
375  * `buffer`  
376    A pointer to the buffer whose content is to be erased.
377
378    The buffer must be *at least* `length` bytes in size. If the buffer is longer than `length` bytes, then *only* the first `length` bytes of the buffer will be erased; the remainder of the buffer will *not* be modified!
379
380  * `length`  
381    The size of the buffer to be erased, in bytes.
382
383
384 C++ API
385 -------
386
387 This section describes the "high-level" C++ API of the SlunkCypt library.
388
389 ### SlunkCryptEncr
390
391 Class for *encrypting* data using the SlunkCrypt library.
392
393 #### Constructor
394
395 Create and initialize a new **``SlunkCryptEncr``** instance. Also generated a new, random nonce.
396
397     SlunkCryptEncr::SlunkCryptEncr(
398       const std::string &passwd
399     );
400
401 ***Parameters:***
402
403   * `passwd`  
404     The password to "protect" the message. The password is given as an `std::string`, e.g. UTF-8 encoded characters. The same password **may** be used to encrypt *multiple* messages. Also, the same password **must** be used for both, encryption *and* decryption; it will *only* be possible decrypt the ciphertext, if the "correct" password is known. The password must be kept confidential under all circumstances!
405     
406     *Note:* In order to thwart *brute force* attacks, it is recommended to choose a "random" password that is at least 12 characters in length and that consists of upper-case characters, lower-case characters, digits as well as other "special" characters.
407
408 ***Exceptions:***
409
410   * Throws `std::runtime_error`, if the nonce could not be generated, or if the SlunkCrypt context could not be allocated.
411
412 #### SlunkCryptEncr::encrypt() [1]
413
414 Encrypt the next message chunk, using separate input/output buffers.
415
416     bool encrypt(
417       const uint8_t* const input,
418       uint8_t* const output,
419       size_t length
420     );
421
422 ***Parameters:***
423
424  * `input`  
425     A pointer to the *input* buffer containing the next chunk of the plaintext to be encrypted. The plaintext is given as a byte array (`uint8_t`). This can be arbitrary binary data, e.g. UTF-8 encoded text. NULL bytes are **not** treated specially.
426     
427     The *input* buffer must contain *at least* `length` bytes of data. If the buffer is longer than `length` bytes, then only the first `length` bytes will be processed and the remainder is ignored!
428
429  * `output`  
430     A pointer to the *output* buffer where the ciphertext chunk that corresponds to the given plaintext chunk will be stored. The ciphertext is stored as a byte array (`uint8_t`); it has the same length as the plaintext data.
431     
432     The *output* buffer must provide sufficient space for storing *at least* `length` bytes of encrypted data. If the buffer is longer than `length` bytes, then only the first `length` bytes of the buffer will be filled with encrypted data!
433
434  * `length`  
435    The length of the plaintext chunk contained in the *input* buffer given by the `input` parameter, in bytes. At the same time, this determines the minimum required size of the *output* buffer given by the `output` parameters, in bytes.
436
437 ***Return value:***
438
439   * If successful, `true` is returned; otherwise `false` is returned.
440
441 #### SlunkCryptEncr::encrypt() [2]
442
443 Encrypt the next message chunk, using separate input/output containers (`std::vector`).
444
445     bool encrypt(
446       const std::vector<uint8_t> &input,
447       std::vector<uint8_t> &output
448     );
449
450 ***Parameters:***
451
452  * `input`  
453     A reference to the `std::vector<uint8_t>` instance containing the next chunk of the plaintext to be encrypted. This can be arbitrary binary data, e.g. UTF-8 encoded text. NULL bytes are **not** treated specially.
454
455  * `output`  
456     A reference to the `std::vector<uint8_t>` instance where the ciphertext that corresponds to the given plaintext will be stored.
457     
458     The `output.size()` must be *greater than or equal* to `input.size()`. If the `output.size()` is larger than the `input.size()`, then only the first `input.size()` elements of `output` will be filled with encrypted data!
459
460 ***Return value:***
461
462   * If successful, `true` is returned; otherwise `false` is returned. The function fails, if the *output* `std::vector` is too small.
463
464 #### SlunkCryptEncr::encrypt_inplace() [1]
465
466 Encrypt the next message chunk, using a single buffer.
467
468     bool encrypt_inplace(
469       uint8_t* const buffer,
470       size_t length
471     );
472
473 ***Parameters:***
474
475  * `buffer`  
476     A pointer to the buffer initially containing the next chunk of the plaintext to be encrypted. The plaintext is given as a byte array (`uint8_t`). This can be arbitrary binary data, e.g. UTF-8 encoded text. NULL bytes are **not** treated specially. The ciphertext chunk that corresponds to the given plaintext chunk will be stored to the *same* buffer, thus replacing the plaintext data.
477     
478     The buffer must initially contain *at least* `length` bytes of input data; the first `length` bytes of the buffer will be overwritten with the encrypted data. If the buffer is longer than `length` bytes, then only the first `length` bytes will be processed and overwritten.
479
480  * `length`  
481    The length of the plaintext chunk initially contained in the input/output buffer given by the `buffer` parameter, in bytes. At the same time, this determines the portion of the input/output buffer that will be overwritten with encrypted data, in bytes.
482
483 ***Return value:***
484
485   * If successful, `true` is returned; otherwise `false` is returned.
486
487 #### SlunkCryptEncr::encrypt_inplace() [2]
488
489 Encrypt the next message chunk, using a single container (`std::vector`).
490
491     bool encrypt_inplace(
492       std::vector<uint8_t> &buffer
493     );
494
495 ***Parameters:***
496
497  * `buffer`  
498     A reference to the `std::vector<uint8_t>` initially containing the next chunk of the plaintext to be encrypted. This can be arbitrary binary data, e.g. UTF-8 encoded text. NULL bytes are **not** treated specially. The ciphertext chunk that corresponds to the given plaintext chunk will be stored to the *same* `std::vector<uint8_t>`, thus replacing all the plaintext data.
499
500 ***Return value:***
501
502   * If successful, `true` is returned; otherwise `false` is returned.
503
504 #### SlunkCryptEncr::get_nonce()
505
506 Retrieve the random nonce that is used to encrypt the message.
507
508     uint64_t get_nonce();
509
510 ***Return value:***
511
512   * Returns the nonce that is used to encrypt the message. The purpose of the nonce is to ensure that each message will be encrypted differently, even when the same password is used to encrypt multiple (possibly identical) messages. Therefore, a new random nonce must be chosen for each message! It is not necessary to keep the nonce confidential, but the same nonce must be used for both, encryption and decryption. Typically, the nonce is stored/transmitted alongside the ciphertext.
513     
514     *Note:* The `SlunkCryptEncr` class automatically generates a new, random nonce for each message to be encrypted. Use *this* function to retrieve that nonce, so that it can be passed to `SlunkCryptDecr` for decryption later.
515
516 ### SlunkCryptDecr
517
518 Class for *decrypting* data using the SlunkCrypt library.
519
520 #### Constructor
521
522 Create and initialize a new **``SlunkCryptDecr``** instance.
523
524     SlunkCryptDecr::SlunkCryptDecr(
525       const uint64_t nonce,
526       const std::string& passwd
527     );
528
529 ***Parameters:***
530
531   * `nonce`  
532     The *nonce* (number used once) to be used for the decryption process. The purpose of the nonce is to ensure that each message will be encrypted differently, even when the same password is used to encrypt *multiple* (possibly identical) messages. Therefore, a new *random* nonce **must** be chosen for each message! It is *not* necessary to keep the nonce confidential, but the same nonce **must** be used for both, encryption *and* decryption. Typically, the nonce is stored/transmitted alongside the ciphertext.
533     
534     *Note:* The `SlunkCryptEncr` class automatically generates a new, random nonce for each message to be encrypted. Use `SlunkCryptEncr::get_nonce()` to retrieve that nonce, so that it can be passed to `SlunkCryptDecr` for decryption later.
535   
536   * `passwd`  
537     The password to "protect" the message. The password is given as an `std::string`, e.g. UTF-8 encoded characters. The same password **may** be used to encrypt *multiple* messages. Also, the same password **must** be used for both, encryption *and* decryption; it will *only* be possible decrypt the ciphertext, if the "correct" password is known. The password must be kept confidential under all circumstances!
538     
539     *Note:* In order to thwart *brute force* attacks, it is recommended to choose a "random" password that is at least 12 characters in length and that consists of upper-case characters, lower-case characters, digits as well as other "special" characters.
540
541 ***Exceptions:***
542
543   * Throws `std::runtime_error`, if the SlunkCrypt context could not be allocated.
544
545 #### SlunkCryptDecr::decrypt() [1]
546
547 Decrypt the next message chunk, using separate input/output buffers.
548
549     bool decrypt(
550       const uint8_t* const input,
551       uint8_t* const output,
552       size_t length
553     );
554
555 ***Parameters:***
556
557  * `input`  
558     A pointer to the *input* buffer containing the next chunk of the ciphertext to be decrypted. The ciphertext is given as a byte array (`uint8_t`).
559     
560     The *input* buffer must contain *at least* `length` bytes of data. If the buffer is longer than `length` bytes, then only the first `length` bytes will be processed and the remainder is ignored!
561
562  * `output`  
563     A pointer to the *output* buffer where the plaintext chunk that corresponds to the given ciphertext chunk will be stored. The plaintext is stored as a byte array (`uint8_t`); it has the same length as the ciphertext data.
564     
565     The *output* buffer must provide sufficient space for storing *at least* `length` bytes of decrypted data. If the buffer is longer than `length` bytes, then only the first `length` bytes of the buffer will be filled with decrypted data!
566
567  * `length`  
568    The length of the ciphertext chunk contained in the *input* buffer given by the `input` parameter, in bytes. At the same time, this determines the minimum required size of the *output* buffer given by the `output` parameters, in bytes.
569
570 ***Return value:***
571
572   * If successful, `true` is returned; otherwise `false` is returned.
573
574 #### SlunkCryptDecr::decrypt() [2]
575
576 Decrypt the next message chunk, using separate input/output containers (`std::vector`).
577
578     bool decrypt(
579       const std::vector<uint8_t> &input,
580       std::vector<uint8_t> &output
581     );
582
583 ***Parameters:***
584
585  * `input`  
586     A reference to the `std::vector<uint8_t>` instance containing the next chunk of the ciphertext to be decrypted.
587
588  * `output`  
589     A reference to the `std::vector<uint8_t>` instance where the plaintext that corresponds to the given ciphertext will be stored.
590     
591     The `output.size()` must be *greater than or equal* to `input.size()`. If the `output.size()` is greater than the `input.size()`, then only the first `input.size()` elements of `output` will be filled with decrypted data!
592
593 ***Return value:***
594
595   * If successful, `true` is returned; otherwise `false` is returned. The function fails, if the *output* `std::vector` is too small.
596
597 #### SlunkCryptDecr::decrypt_inplace() [1]
598
599 Decrypt the next message chunk, using a single buffer.
600
601     bool decrypt_inplace(
602       uint8_t* const buffer,
603       size_t length
604     );
605
606 ***Parameters:***
607
608  * `buffer`  
609     A pointer to the buffer initially containing the next chunk of the ciphertext to be decrypted. The ciphertext is given as a byte array (`uint8_t`). The plaintext that corresponds to the given ciphertext will be stored to the *same* buffer, replacing the plaintext data.
610     
611     The buffer must initially contain *at least* `length` bytes of input data; the first `length` bytes of the buffer will be overwritten with the encrypted data. If the buffer is longer than `length` bytes, then only the first `length` bytes will be processed and overwritten.
612
613  * `length`  
614    The length of the ciphertext chunk initially contained in the input/output buffer given by the `buffer` parameter, in bytes. At the same time, this determines the portion of the input/output buffer that will be overwritten with decrypted data, in bytes.
615
616 ***Return value:***
617
618   * If successful, `true` is returned; otherwise `false` is returned.
619
620 #### SlunkCryptDecr::decrypt_inplace() [2]
621
622 Decrypt the next message chunk, using a single container (`std::vector`).
623
624     bool decrypt_inplace(
625       std::vector<uint8_t> &buffer
626     );
627
628 ***Parameters:***
629
630  * `buffer`  
631     A reference to the `std::vector<uint8_t>` initially containing the next chunk of the ciphertext to be decrypted. The plaintext that corresponds to the given ciphertext will be stored to the *same* `std::vector<uint8_t>`, replacing all the ciphertext data.
632
633 ***Return value:***
634
635   * If successful, `true` is returned; otherwise `false` is returned.
636
637 Thread safety
638 -------------
639
640 The following functions are fully "thread-safe" and thus may safely be called by *any* thread at *any* time ***without*** the need for synchronization:
641
642 * `slunkcrypt_alloc()`
643 * `slunkcrypt_random_bytes()`
644 * `slunkcrypt_bzero()`
645 * `SlunkCryptEncr::SlunkCryptEncr()`
646 * `SlunkCryptDecr::SlunkCryptDecr()`
647
648 The following functions are "reentrant" and thus may safely be called by *any* thread at *any* time, ***without*** the need for synchronization, provided that each `slunkcrypt_t`, `SlunkCryptEncr` or `SlunkCryptDecr` instance is "owned" (i.e. accessed *exclusively*) and by a *single* thread:
649
650 * `slunkcrypt_reset()`
651 * `slunkcrypt_free()`
652 * `slunkcrypt_encrypt()`
653 * `slunkcrypt_encrypt_inplace()`
654 * `slunkcrypt_decrypt()`
655 * `slunkcrypt_decrypt_inplace()`
656 * `SlunkCryptEncr::encrypt()`
657 * `SlunkCryptEncr::encrypt_inplace()`
658 * `SlunkCryptEncr::get_nonce()`
659 * `SlunkCryptDecr::decrypt()`
660 * `SlunkCryptDecr::decrypt_inplace()`
661
662 ***Note:*** Iff the same `slunkcrypt_t`, `SlunkCryptEncr` or `SlunkCryptDecr` instance needs to be shared across *multiple* threads, then the application **must** *serialize* any invocations of the above functions (on the shared instance), by an *explicit* "mutex" synchronization!
663
664
665 License
666 =======
667
668 This work has been released under the **CC0 1.0 Universal** license.
669
670 For details, please refer to:  
671 <https://creativecommons.org/publicdomain/zero/1.0/legalcode>