Renamed the C++ wrapper classes + updated README file.

This commit is contained in:
LoRd_MuldeR 2021-03-24 21:34:46 +01:00
parent 7fb9a517fe
commit baa6705f85
Signed by: mulder
GPG Key ID: 2B5913365F57E03F
4 changed files with 431 additions and 365 deletions

587
README.md
View File

@ -151,6 +151,321 @@ The SlunkCrypt algorithm is based on concepts of the well-known [**Enigma**](htt
Programming Interface (API)
===========================
This section describes the SlunkCypt library interface for software developers.
Getting started
---------------
In order to use the SlunkCypt library in your C++ code, include **`<slunkcrypt.hpp>`** header and instantiate the appropriate SlunkCypt classes:
### Example #1
Here is a simple example on how to use the SlunkCrypt [**`Encryptor`**](#encryptor) class:
#include <slunkcrypt.hpp>
#include <fstream>
#include <iostream>
int main()
{
/* Open input and output files here */
uint8_t buffer[BUFF_SIZE];
slunkcrypt::Encryptor slunk_encrypt(passphrase);
while (input.good())
{
input.read(reinterpret_cast<char*>(buffer), BUFF_SIZE);
if ((!input.bad()) && (input.gcount() > 0))
{
if (!slunk_encrypt.encrypt_inplace(buffer, (size_t)input.gcount()))
{
/* Implement error handling here */
}
output.write(reinterpret_cast<char*>(buffer), count);
}
}
std::cout << std::hex << slunk_encrypt.get_nonce() << std::endl;
}
### Example #2
Here is a simple example on how to use the SlunkCrypt [**`Decryptor`**](#decryptor) class:
#include <slunkcrypt.hpp>
#include <fstream>
#include <iostream>
int main()
{
/* Open input and output files here */
uint8_t buffer[BUFF_SIZE];
slunkcrypt::Decryptor slunk_decrypt(nonce, passphrase);
while (input.good())
{
input.read(reinterpret_cast<char*>(buffer), BUFF_SIZE);
if ((!input.bad()) && (input.gcount() > 0))
{
if (!slunk_decrypt.decrypt_inplace(buffer, (size_t)input.gcount()))
{
/* Implement error handling here */
}
output.write(reinterpret_cast<char*>(buffer), count);
}
}
}
C++11 API
---------
This section describes the "high-level" C++11 API of the SlunkCrypt library. All SlunkCrypt classes live in the **`slunkcrypt`** namespace.
### Encryptor
Class for *encrypting* data using the SlunkCrypt library.
#### Constructor
Create and initialize a new **``Encryptor``** instance. Also generated a new, random nonce.
Encryptor::Encryptor(
const std::string &passwd
);
***Parameters:***
* `passwd`
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!
*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.
***Exceptions:***
* Throws `std::runtime_error`, if the nonce could not be generated, or if the SlunkCrypt context could not be allocated.
#### Encryptor::encrypt() [1]
Encrypt the next message chunk, using separate input/output buffers.
bool encrypt(
const uint8_t* const input,
uint8_t* const output,
size_t length
);
***Parameters:***
* `input`
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.
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!
* `output`
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.
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!
* `length`
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.
***Return value:***
* If successful, `true` is returned; otherwise `false` is returned.
#### Encryptor::encrypt() [2]
Encrypt the next message chunk, using separate input/output containers (`std::vector`).
bool encrypt(
const std::vector<uint8_t> &input,
std::vector<uint8_t> &output
);
***Parameters:***
* `input`
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.
* `output`
A reference to the `std::vector<uint8_t>` instance where the ciphertext that corresponds to the given plaintext will be stored.
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!
***Return value:***
* If successful, `true` is returned; otherwise `false` is returned. The function fails, if the *output* `std::vector` is too small.
#### Encryptor::encrypt_inplace() [1]
Encrypt the next message chunk, using a single buffer.
bool encrypt_inplace(
uint8_t* const buffer,
size_t length
);
***Parameters:***
* `buffer`
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.
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.
* `length`
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.
***Return value:***
* If successful, `true` is returned; otherwise `false` is returned.
#### Encryptor::encrypt_inplace() [2]
Encrypt the next message chunk, using a single container (`std::vector`).
bool encrypt_inplace(
std::vector<uint8_t> &buffer
);
***Parameters:***
* `buffer`
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.
***Return value:***
* If successful, `true` is returned; otherwise `false` is returned.
#### Encryptor::get_nonce()
Retrieve the random nonce that is used to encrypt the message.
uint64_t get_nonce();
***Return value:***
* 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.
*Note:* The `Encryptor` 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 `Decryptor` for decryption later.
### Decryptor
Class for *decrypting* data using the SlunkCrypt library.
#### Constructor
Create and initialize a new **``Decryptor``** instance.
Decryptor::Decryptor(
const uint64_t nonce,
const std::string& passwd
);
***Parameters:***
* `nonce`
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.
*Note:* The `Encryptor` class automatically generates a new, random nonce for each message to be encrypted. Use `Encryptor::get_nonce()` to retrieve that nonce, so that it can be passed to `Decryptor` for decryption later.
* `passwd`
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!
*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.
***Exceptions:***
* Throws `std::runtime_error`, if the SlunkCrypt context could not be allocated.
#### Decryptor::decrypt() [1]
Decrypt the next message chunk, using separate input/output buffers.
bool decrypt(
const uint8_t* const input,
uint8_t* const output,
size_t length
);
***Parameters:***
* `input`
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`).
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!
* `output`
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.
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!
* `length`
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.
***Return value:***
* If successful, `true` is returned; otherwise `false` is returned.
#### Decryptor::decrypt() [2]
Decrypt the next message chunk, using separate input/output containers (`std::vector`).
bool decrypt(
const std::vector<uint8_t> &input,
std::vector<uint8_t> &output
);
***Parameters:***
* `input`
A reference to the `std::vector<uint8_t>` instance containing the next chunk of the ciphertext to be decrypted.
* `output`
A reference to the `std::vector<uint8_t>` instance where the plaintext that corresponds to the given ciphertext will be stored.
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!
***Return value:***
* If successful, `true` is returned; otherwise `false` is returned. The function fails, if the *output* `std::vector` is too small.
#### Decryptor::decrypt_inplace() [1]
Decrypt the next message chunk, using a single buffer.
bool decrypt_inplace(
uint8_t* const buffer,
size_t length
);
***Parameters:***
* `buffer`
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.
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.
* `length`
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.
***Return value:***
* If successful, `true` is returned; otherwise `false` is returned.
#### Decryptor::decrypt_inplace() [2]
Decrypt the next message chunk, using a single container (`std::vector`).
bool decrypt_inplace(
std::vector<uint8_t> &buffer
);
***Parameters:***
* `buffer`
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.
***Return value:***
* If successful, `true` is returned; otherwise `false` is returned.
C99 API
-------
@ -413,260 +728,6 @@ Erase the contents of a byte array, by overwriting it with *zero* bytes. Compile
* `length`
The size of the buffer to be erased, in bytes.
C++11 API
---------
This section describes the "high-level" C++11 API of the SlunkCypt library.
### SlunkCryptEncr
Class for *encrypting* data using the SlunkCrypt library.
#### Constructor
Create and initialize a new **``SlunkCryptEncr``** instance. Also generated a new, random nonce.
SlunkCryptEncr::SlunkCryptEncr(
const std::string &passwd
);
***Parameters:***
* `passwd`
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!
*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.
***Exceptions:***
* Throws `std::runtime_error`, if the nonce could not be generated, or if the SlunkCrypt context could not be allocated.
#### SlunkCryptEncr::encrypt() [1]
Encrypt the next message chunk, using separate input/output buffers.
bool encrypt(
const uint8_t* const input,
uint8_t* const output,
size_t length
);
***Parameters:***
* `input`
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.
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!
* `output`
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.
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!
* `length`
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.
***Return value:***
* If successful, `true` is returned; otherwise `false` is returned.
#### SlunkCryptEncr::encrypt() [2]
Encrypt the next message chunk, using separate input/output containers (`std::vector`).
bool encrypt(
const std::vector<uint8_t> &input,
std::vector<uint8_t> &output
);
***Parameters:***
* `input`
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.
* `output`
A reference to the `std::vector<uint8_t>` instance where the ciphertext that corresponds to the given plaintext will be stored.
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!
***Return value:***
* If successful, `true` is returned; otherwise `false` is returned. The function fails, if the *output* `std::vector` is too small.
#### SlunkCryptEncr::encrypt_inplace() [1]
Encrypt the next message chunk, using a single buffer.
bool encrypt_inplace(
uint8_t* const buffer,
size_t length
);
***Parameters:***
* `buffer`
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.
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.
* `length`
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.
***Return value:***
* If successful, `true` is returned; otherwise `false` is returned.
#### SlunkCryptEncr::encrypt_inplace() [2]
Encrypt the next message chunk, using a single container (`std::vector`).
bool encrypt_inplace(
std::vector<uint8_t> &buffer
);
***Parameters:***
* `buffer`
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.
***Return value:***
* If successful, `true` is returned; otherwise `false` is returned.
#### SlunkCryptEncr::get_nonce()
Retrieve the random nonce that is used to encrypt the message.
uint64_t get_nonce();
***Return value:***
* 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.
*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.
### SlunkCryptDecr
Class for *decrypting* data using the SlunkCrypt library.
#### Constructor
Create and initialize a new **``SlunkCryptDecr``** instance.
SlunkCryptDecr::SlunkCryptDecr(
const uint64_t nonce,
const std::string& passwd
);
***Parameters:***
* `nonce`
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.
*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.
* `passwd`
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!
*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.
***Exceptions:***
* Throws `std::runtime_error`, if the SlunkCrypt context could not be allocated.
#### SlunkCryptDecr::decrypt() [1]
Decrypt the next message chunk, using separate input/output buffers.
bool decrypt(
const uint8_t* const input,
uint8_t* const output,
size_t length
);
***Parameters:***
* `input`
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`).
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!
* `output`
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.
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!
* `length`
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.
***Return value:***
* If successful, `true` is returned; otherwise `false` is returned.
#### SlunkCryptDecr::decrypt() [2]
Decrypt the next message chunk, using separate input/output containers (`std::vector`).
bool decrypt(
const std::vector<uint8_t> &input,
std::vector<uint8_t> &output
);
***Parameters:***
* `input`
A reference to the `std::vector<uint8_t>` instance containing the next chunk of the ciphertext to be decrypted.
* `output`
A reference to the `std::vector<uint8_t>` instance where the plaintext that corresponds to the given ciphertext will be stored.
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!
***Return value:***
* If successful, `true` is returned; otherwise `false` is returned. The function fails, if the *output* `std::vector` is too small.
#### SlunkCryptDecr::decrypt_inplace() [1]
Decrypt the next message chunk, using a single buffer.
bool decrypt_inplace(
uint8_t* const buffer,
size_t length
);
***Parameters:***
* `buffer`
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.
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.
* `length`
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.
***Return value:***
* If successful, `true` is returned; otherwise `false` is returned.
#### SlunkCryptDecr::decrypt_inplace() [2]
Decrypt the next message chunk, using a single container (`std::vector`).
bool decrypt_inplace(
std::vector<uint8_t> &buffer
);
***Parameters:***
* `buffer`
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.
***Return value:***
* If successful, `true` is returned; otherwise `false` is returned.
Thread safety
-------------
@ -675,10 +736,10 @@ The following functions are fully "thread-safe" and thus may safely be called by
* `slunkcrypt_alloc()`
* `slunkcrypt_random_bytes()`
* `slunkcrypt_bzero()`
* `SlunkCryptEncr::SlunkCryptEncr()`
* `SlunkCryptDecr::SlunkCryptDecr()`
* `Encryptor::Encryptor()`
* `Decryptor::Decryptor()`
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:
The following functions are "reentrant" and thus may safely be called by *any* thread at *any* time ***without*** the need for synchronization &ndash; provided that each instance of `slunkcrypt_t`, `Encryptor` or `Decryptor` is "owned" by a *single* thread **and** each instance will *exclusively* be access by its respective "owner" thread:
* `slunkcrypt_reset()`
* `slunkcrypt_free()`
@ -686,13 +747,13 @@ The following functions are "reentrant" and thus may safely be called by *any* t
* `slunkcrypt_encrypt_inplace()`
* `slunkcrypt_decrypt()`
* `slunkcrypt_decrypt_inplace()`
* `SlunkCryptEncr::encrypt()`
* `SlunkCryptEncr::encrypt_inplace()`
* `SlunkCryptEncr::get_nonce()`
* `SlunkCryptDecr::decrypt()`
* `SlunkCryptDecr::decrypt_inplace()`
* `Encryptor::encrypt()`
* `Encryptor::encrypt_inplace()`
* `Encryptor::get_nonce()`
* `Decryptor::decrypt()`
* `Decryptor::decrypt_inplace()`
***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!
***Note:*** If the same `slunkcrypt_t`, `Encryptor` or `Decryptor` instance needs to be shared across *multiple* threads (i.e. the same instance is accessed by *concurrent* threads), then the application **must** *serialize* any invocation of the above functions on that shared instance, by using a suitable synchronization mechanism! This can be achieved by using a [*mutex*](https://linux.die.net/man/3/pthread_mutex_lock).
License

View File

@ -55,7 +55,7 @@ static int decrypt_main(int argc, char *argv[])
std::cerr << "Initializing key, please wait... " << std::flush;
uint8_t buffer[BUFF_SIZE];
SlunkCryptDecr slunk_decrypt(nonce, EXAMPLE_PASSWORD);
slunkcrypt::Decryptor slunk_decrypt(nonce, EXAMPLE_PASSWORD);
std::cerr << "done.\nSlunk-decrypting the file contents, please wait... " << std::flush;

View File

@ -53,7 +53,7 @@ static int encrypt_main(int argc, char *argv[])
std::cerr << "Initializing key, please wait... " << std::flush;
uint8_t buffer[BUFF_SIZE];
SlunkCryptEncr slunk_encrypt(EXAMPLE_PASSWORD);
slunkcrypt::Encryptor slunk_encrypt(EXAMPLE_PASSWORD);
std::cerr << "done.\nSlunk-encrypting the file contents, please wait... " << std::flush;

View File

@ -22,131 +22,136 @@
#include <stdexcept>
/*
* SlunkCrypt class for encryption
* Namespace
*/
class SlunkCryptEncr
namespace slunkcrypt
{
public:
SlunkCryptEncr(const std::string &passwd)
/*
* Class for encryption
*/
class Encryptor
{
if (slunkcrypt_generate_nonce(&m_nonce) != SLUNKCRYPT_SUCCESS)
public:
Encryptor(const std::string& passwd)
{
throw std::runtime_error("SlunkCryptEncr: Failed to generate the seed value!");
if (slunkcrypt_generate_nonce(&m_nonce) != SLUNKCRYPT_SUCCESS)
{
throw std::runtime_error("SlunkCryptEncr: Failed to generate the seed value!");
}
if ((m_instance = slunkcrypt_alloc(m_nonce, (const uint8_t*)passwd.c_str(), passwd.length())) == SLUNKCRYPT_NULL)
{
throw std::runtime_error("SlunkCryptEncr: Failed to create encoder instance!");
}
}
if ((m_instance = slunkcrypt_alloc(m_nonce, (const uint8_t*)passwd.c_str(), passwd.length())) == SLUNKCRYPT_NULL)
Encryptor(Encryptor&& other) noexcept
{
throw std::runtime_error("SlunkCryptEncr: Failed to create encoder instance!");
this->m_instance = other.m_instance;
this->m_nonce = other.m_nonce;
other.m_instance = SLUNKCRYPT_NULL;
other.m_nonce = (uint64_t)(-1);
}
}
SlunkCryptEncr(SlunkCryptEncr &&other) noexcept
{
this->m_instance = other.m_instance;
this->m_nonce = other.m_nonce;
other.m_instance = SLUNKCRYPT_NULL;
other.m_nonce = (uint64_t)(-1);
}
~SlunkCryptEncr(void)
{
if (m_instance != SLUNKCRYPT_NULL)
~Encryptor(void)
{
slunkcrypt_free(m_instance);
if (m_instance != SLUNKCRYPT_NULL)
{
slunkcrypt_free(m_instance);
}
}
}
bool encrypt(const uint8_t* const input, uint8_t* const output, size_t length)
{
return (slunkcrypt_encrypt(m_instance, input, output, length) == SLUNKCRYPT_SUCCESS);
}
bool encrypt(const std::vector<uint8_t> &input, std::vector<uint8_t> &output)
{
if (output.size() >= input.size())
bool encrypt(const uint8_t* const input, uint8_t* const output, size_t length)
{
return (slunkcrypt_encrypt(m_instance, input.data(), output.data(), input.size()) == SLUNKCRYPT_SUCCESS);
return (slunkcrypt_encrypt(m_instance, input, output, length) == SLUNKCRYPT_SUCCESS);
}
return false;
}
bool encrypt_inplace(uint8_t* const buffer, size_t length)
{
return (slunkcrypt_encrypt_inplace(m_instance, buffer, length) == SLUNKCRYPT_SUCCESS);
}
bool encrypt_inplace(std::vector<uint8_t> &buffer)
{
return (slunkcrypt_encrypt_inplace(m_instance, buffer.data(), buffer.size()) == SLUNKCRYPT_SUCCESS);
}
uint64_t get_nonce(void) const
{
return m_nonce;
}
private:
SlunkCryptEncr(const SlunkCryptEncr&) = delete;
SlunkCryptEncr& operator=(const SlunkCryptEncr&) = delete;
uint64_t m_nonce;
slunkcrypt_t m_instance;
};
/*
* SlunkCrypt class for decryption
*/
class SlunkCryptDecr
{
public:
SlunkCryptDecr(const uint64_t nonce, const std::string& passwd)
{
if ((m_instance = slunkcrypt_alloc(nonce, (const uint8_t*)passwd.c_str(), passwd.length())) == SLUNKCRYPT_NULL)
bool encrypt(const std::vector<uint8_t>& input, std::vector<uint8_t>& output)
{
throw std::runtime_error("SlunkCryptDecr: Failed to create decoder instance!");
if (output.size() >= input.size())
{
return (slunkcrypt_encrypt(m_instance, input.data(), output.data(), input.size()) == SLUNKCRYPT_SUCCESS);
}
return false;
}
}
SlunkCryptDecr(SlunkCryptDecr &&other) noexcept
{
this->m_instance = other.m_instance;
other.m_instance = SLUNKCRYPT_NULL;
}
~SlunkCryptDecr(void)
{
if (m_instance != SLUNKCRYPT_NULL)
bool encrypt_inplace(uint8_t* const buffer, size_t length)
{
slunkcrypt_free(m_instance);
return (slunkcrypt_encrypt_inplace(m_instance, buffer, length) == SLUNKCRYPT_SUCCESS);
}
}
bool decrypt(const uint8_t* const input, uint8_t* const output, size_t length)
{
return (slunkcrypt_decrypt(m_instance, input, output, length) == SLUNKCRYPT_SUCCESS);
}
bool decrypt(const std::vector<uint8_t>& input, std::vector<uint8_t>& output)
{
if (output.size() >= input.size())
bool encrypt_inplace(std::vector<uint8_t>& buffer)
{
return (slunkcrypt_decrypt(m_instance, input.data(), output.data(), input.size()) == SLUNKCRYPT_SUCCESS);
return (slunkcrypt_encrypt_inplace(m_instance, buffer.data(), buffer.size()) == SLUNKCRYPT_SUCCESS);
}
return false;
}
bool decrypt_inplace(uint8_t* const buffer, size_t length)
uint64_t get_nonce(void) const
{
return m_nonce;
}
private:
Encryptor(const Encryptor&) = delete;
Encryptor& operator=(const Encryptor&) = delete;
uint64_t m_nonce;
slunkcrypt_t m_instance;
};
/*
* Class for decryption
*/
class Decryptor
{
return (slunkcrypt_decrypt_inplace(m_instance, buffer, length) == SLUNKCRYPT_SUCCESS);
}
public:
Decryptor(const uint64_t nonce, const std::string& passwd)
{
if ((m_instance = slunkcrypt_alloc(nonce, (const uint8_t*)passwd.c_str(), passwd.length())) == SLUNKCRYPT_NULL)
{
throw std::runtime_error("SlunkCryptDecr: Failed to create decoder instance!");
}
}
bool decrypt_inplace(std::vector<uint8_t>& buffer)
{
return (slunkcrypt_decrypt_inplace(m_instance, buffer.data(), buffer.size()) == SLUNKCRYPT_SUCCESS);
}
Decryptor(Decryptor&& other) noexcept
{
this->m_instance = other.m_instance;
other.m_instance = SLUNKCRYPT_NULL;
}
private:
SlunkCryptDecr(const SlunkCryptDecr&) = delete;
SlunkCryptDecr& operator=(const SlunkCryptDecr&) = delete;
slunkcrypt_t m_instance;
};
~Decryptor(void)
{
if (m_instance != SLUNKCRYPT_NULL)
{
slunkcrypt_free(m_instance);
}
}
bool decrypt(const uint8_t* const input, uint8_t* const output, size_t length)
{
return (slunkcrypt_decrypt(m_instance, input, output, length) == SLUNKCRYPT_SUCCESS);
}
bool decrypt(const std::vector<uint8_t>& input, std::vector<uint8_t>& output)
{
if (output.size() >= input.size())
{
return (slunkcrypt_decrypt(m_instance, input.data(), output.data(), input.size()) == SLUNKCRYPT_SUCCESS);
}
return false;
}
bool decrypt_inplace(uint8_t* const buffer, size_t length)
{
return (slunkcrypt_decrypt_inplace(m_instance, buffer, length) == SLUNKCRYPT_SUCCESS);
}
bool decrypt_inplace(std::vector<uint8_t>& buffer)
{
return (slunkcrypt_decrypt_inplace(m_instance, buffer.data(), buffer.size()) == SLUNKCRYPT_SUCCESS);
}
private:
Decryptor(const Decryptor&) = delete;
Decryptor& operator=(const Decryptor&) = delete;
slunkcrypt_t m_instance;
};
}
#endif