Add doxygen style comments
This commit is contained in:
parent
aa6f287a19
commit
e02f4507fc
@ -12,7 +12,9 @@
|
||||
#include "utils.h"
|
||||
|
||||
namespace horcrux {
|
||||
|
||||
/** Cipher context class
|
||||
* This is a wrapper for OpenSSL context object, just for RAII pattern
|
||||
*/
|
||||
class EvpCipherCtx {
|
||||
EVP_CIPHER_CTX *ptr;
|
||||
|
||||
@ -158,15 +160,7 @@ std::vector<unsigned char> AES256_CBC::encrypt(
|
||||
return output;
|
||||
}
|
||||
|
||||
|
||||
int AES256_CBC::encrypt(const std::vector<unsigned char>& key,
|
||||
const std::vector<unsigned char>& iv,
|
||||
const std::vector<unsigned char>& input,
|
||||
std::vector<unsigned char>& output) {
|
||||
auto ctx = init(Mode::kEncrypt, key, iv);
|
||||
process_all(Mode::kEncrypt, ctx, input.begin(), input.end(), output, 0);
|
||||
return 0;
|
||||
}
|
||||
/*
|
||||
|
||||
int AES256_CBC::encrypt(const std::vector<unsigned char>& key,
|
||||
const std::vector<unsigned char>& iv,
|
||||
@ -183,14 +177,7 @@ int AES256_CBC::encrypt(const std::vector<unsigned char>& key,
|
||||
return 0;
|
||||
}
|
||||
|
||||
int AES256_CBC::decrypt(const std::vector<unsigned char>& key,
|
||||
const std::vector<unsigned char>& iv,
|
||||
const std::vector<unsigned char>& input,
|
||||
std::vector<unsigned char>& output) {
|
||||
auto ctx = init(Mode::kDecrypt, key, iv);
|
||||
process_all(Mode::kDecrypt, ctx, input.begin(), input.end(), output, 0);
|
||||
return 0;
|
||||
}
|
||||
*/
|
||||
std::vector<unsigned char> AES256_CBC::decrypt(
|
||||
const std::vector<unsigned char>& key,
|
||||
const std::vector<unsigned char>& ciphertext) {
|
||||
@ -198,6 +185,14 @@ std::vector<unsigned char> AES256_CBC::decrypt(
|
||||
ciphertext.begin() + kIvSize);
|
||||
return decrypt(key, iv, ciphertext.begin() + kIvSize, ciphertext.end());
|
||||
}
|
||||
|
||||
std::vector<unsigned char> AES256_CBC::decrypt(
|
||||
const std::vector<unsigned char>& key,
|
||||
const std::vector<unsigned char>& iv,
|
||||
const std::vector<unsigned char>& ciphertext) {
|
||||
return decrypt(key, iv, ciphertext.begin(), ciphertext.end());
|
||||
}
|
||||
|
||||
std::vector<unsigned char> AES256_CBC::decrypt(
|
||||
const std::vector<unsigned char>& key,
|
||||
const std::vector<unsigned char>& iv,
|
||||
|
161
src/crypto.h
161
src/crypto.h
@ -10,89 +10,171 @@ namespace horcrux {
|
||||
|
||||
enum class Mode { kEncrypt, kDecrypt };
|
||||
|
||||
/** @brief Base Class for Ciphers.
|
||||
* @details Derive from this class to add other Cipher implementations
|
||||
*/
|
||||
class Cipher {
|
||||
public:
|
||||
/** @brief default constructor */
|
||||
Cipher() = delete;
|
||||
|
||||
/** @brief create Cipher
|
||||
* @param m Cipher mode (encrypt/decrypt) */
|
||||
explicit Cipher(Mode m) : mode(m) { }
|
||||
|
||||
/** @brief create Cipher
|
||||
* @param m Cipher mode (encrypt/decrypt)
|
||||
* @param key use provided key for encryption/decryption */
|
||||
Cipher(Mode m, const std::vector<unsigned char>& key) :
|
||||
mode(m), encryption_key(key) {}
|
||||
|
||||
Cipher(Mode m, std::vector<unsigned char>&& key) :
|
||||
mode(m), encryption_key(key) {}
|
||||
|
||||
/** @brief default destructor */
|
||||
virtual ~Cipher() = default;
|
||||
|
||||
protected:
|
||||
/** @brief key used for encryption / decryption */
|
||||
std::vector<unsigned char> encryption_key;
|
||||
|
||||
public:
|
||||
/** @brief Cipher mode (encrypt or decrypt) */
|
||||
const Mode mode;
|
||||
|
||||
/** @brief get Cipher encryption key
|
||||
* @return the encryption key
|
||||
*/
|
||||
const std::vector<unsigned char>& get_encryption_key() {
|
||||
return encryption_key;
|
||||
}
|
||||
|
||||
/** @brief process inputdata according to Cipher mode
|
||||
* @param inputdata buffer containing data to process
|
||||
* @return processed data
|
||||
*/
|
||||
virtual std::vector<unsigned char> process(
|
||||
const std::vector<unsigned char>& inputdata) = 0;
|
||||
|
||||
/** @brief encrypt the content of a buffer using Cipher key
|
||||
* @param plaintext the input buffer
|
||||
* @return encrypted data
|
||||
*/
|
||||
virtual std::vector<unsigned char> encrypt(
|
||||
const std::vector<unsigned char>& plaintext) = 0;
|
||||
|
||||
/** @brief decrypt the content of a buffer using Cipher key
|
||||
* @param decrypt the input buffer
|
||||
* @return decrypted data
|
||||
*/
|
||||
virtual std::vector<unsigned char> decrypt(
|
||||
const std::vector<unsigned char>& ciphertext) = 0;
|
||||
};
|
||||
|
||||
// forward declaration
|
||||
class EvpCipherCtx;
|
||||
|
||||
/** @brief AES256 Cipher
|
||||
* @details
|
||||
* This Cipher uses an encryption key and an initilization vector.
|
||||
* The initialization vector is as large as the cipher block size (16 bytes).
|
||||
* The initialization vector is stored as the first 16 bytes of the encrypted
|
||||
* data and it is always randomly generated in order to always produce different
|
||||
* encrypted data.
|
||||
* The encryption key must be kept secret and it is randomly generated if not
|
||||
* provided
|
||||
* The encrypted data is always slightly bigger than the plaintext data because
|
||||
* it contains the initialization vector at the beginning and it may cointain
|
||||
* some cipher block padding at the end.
|
||||
*/
|
||||
class AES256_CBC : public Cipher {
|
||||
/** AES256 CBC key size, from AES256 specs */
|
||||
const size_t kKeySize = 32;
|
||||
/** AES256 CBC initialization vector size, from AES256 specs */
|
||||
const size_t kIvSize = 16;
|
||||
|
||||
public:
|
||||
/** @brief Create cipher in encrypt mode with random key */
|
||||
AES256_CBC() : Cipher(Mode::kEncrypt) {
|
||||
encryption_key = horcrux::generate_random(kKeySize);
|
||||
}
|
||||
/** @brief Create cipher in decrypt mode using provided key
|
||||
* @param key 256 bit key
|
||||
*/
|
||||
explicit AES256_CBC(const std::vector<unsigned char>& key)
|
||||
: Cipher(Mode::kDecrypt, key) {
|
||||
if (key.size() != kKeySize)
|
||||
throw std::invalid_argument("Invalid key size");
|
||||
}
|
||||
explicit AES256_CBC(std::vector<unsigned char>&& key)
|
||||
: Cipher(Mode::kDecrypt, key) {
|
||||
if (key.size() != kKeySize)
|
||||
throw std::invalid_argument("Invalid key size");
|
||||
}
|
||||
|
||||
/** @brief default virtual destructor */
|
||||
virtual ~AES256_CBC() = default;
|
||||
|
||||
/** @brief process inputdata according to Cipher mode
|
||||
* @param inputdata buffer containing data to process
|
||||
* @return processed data
|
||||
*/
|
||||
std::vector<unsigned char> process(
|
||||
const std::vector<unsigned char>& inputdata) override;
|
||||
|
||||
/** @brief encrypt the content of a buffer using Cipher key
|
||||
* @param plaintext the input buffer
|
||||
* @return encrypted data
|
||||
*/
|
||||
std::vector<unsigned char> encrypt(
|
||||
const std::vector<unsigned char>& plaintext) override;
|
||||
|
||||
/** @brief decrypt the content of a buffer using Cipher key
|
||||
* @param decrypt the input buffer
|
||||
* @return decrypted data
|
||||
*/
|
||||
std::vector<unsigned char> decrypt(
|
||||
const std::vector<unsigned char>& ciphertext) override;
|
||||
|
||||
/** @brief Read the whole input and return a buffer with the encrypted data
|
||||
* @param key the encryption key
|
||||
* @param iv the initialization vector that will be copied to the beginning
|
||||
* of the output
|
||||
* @param input the input buffer
|
||||
* @return the encrypted data buffer
|
||||
*/
|
||||
std::vector<unsigned char> encrypt(const std::vector<unsigned char>& key,
|
||||
const std::vector<unsigned char>& iv,
|
||||
const std::vector<unsigned char>& input);
|
||||
|
||||
int encrypt(const std::vector<unsigned char>& key,
|
||||
const std::vector<unsigned char>& iv,
|
||||
const std::vector<unsigned char>& input,
|
||||
std::vector<unsigned char>& output);
|
||||
|
||||
/*
|
||||
int encrypt(const std::vector<unsigned char>& key,
|
||||
const std::vector<unsigned char>& iv,
|
||||
std::istream input, const size_t input_len,
|
||||
std::ostream output, size_t& output_len);
|
||||
|
||||
int decrypt(const std::vector<unsigned char>& key,
|
||||
const std::vector<unsigned char>& iv,
|
||||
const std::vector<unsigned char>& input,
|
||||
std::vector<unsigned char>& output);
|
||||
|
||||
*/
|
||||
/** @brief Read the whole input and return a buffer with the decrypted data.
|
||||
* Read the iv from the beginning of ciphertext
|
||||
* @param key the encryption key
|
||||
* @param ciphertext the input buffer
|
||||
* @return the encrypted data buffer
|
||||
*/
|
||||
std::vector<unsigned char> decrypt(
|
||||
const std::vector<unsigned char>& key,
|
||||
const std::vector<unsigned char>& ciphertext);
|
||||
|
||||
/** @brief Read the whole input and return a buffer with the decrypted data.
|
||||
* ciphertext does not contain the iv.
|
||||
* @param key the encryption key
|
||||
* @param iv the initialization vector
|
||||
* @param ciphertext the input buffer
|
||||
* @return the encrypted data buffer
|
||||
*/
|
||||
std::vector<unsigned char> decrypt(
|
||||
const std::vector<unsigned char>& key,
|
||||
const std::vector<unsigned char>& iv,
|
||||
const std::vector<unsigned char>& ciphertext);
|
||||
|
||||
/** @brief Read some input from begin to end and return a buffer with the
|
||||
* decrypted data. Output data is finalized.
|
||||
* @param key the encryption key
|
||||
* @param iv the initialization vector
|
||||
* @param begin beginning of the input buffer
|
||||
* @param end end of the input buffer
|
||||
* @return the encrypted data buffer
|
||||
*/
|
||||
std::vector<unsigned char> decrypt(
|
||||
const std::vector<unsigned char>& key,
|
||||
const std::vector<unsigned char>& iv,
|
||||
@ -100,9 +182,27 @@ public:
|
||||
std::vector<unsigned char>::const_iterator end);
|
||||
|
||||
private:
|
||||
/** @brief Create a Cipher context object needed for enc/dec operations
|
||||
* @param mode encrypt or decrypt
|
||||
* @param key the enc/dec key
|
||||
* @param the initialization vector
|
||||
* @return the Cipher context object
|
||||
*/
|
||||
EvpCipherCtx init(Mode mode, const std::vector<unsigned char>& key,
|
||||
const std::vector<unsigned char>& iv);
|
||||
|
||||
/** @brief process a chunk of input
|
||||
* @param mode encrypt or decrypt
|
||||
* @param ctx the Cipher context object
|
||||
* @param begin beginning of the input chunk
|
||||
* @param end end of the input chunk
|
||||
* @param output output buffer
|
||||
* @param output_offset where to start to append the processed data within
|
||||
* the output buffer
|
||||
* @param resize_in resize the output buffer before appending data to it in
|
||||
* order to make sure there is enough room.
|
||||
* @param resize_out shrink the output buffer at the end
|
||||
*/
|
||||
size_t process_chunk(Mode mode, EvpCipherCtx& ctx,
|
||||
std::vector<unsigned char>::const_iterator begin,
|
||||
std::vector<unsigned char>::const_iterator end,
|
||||
@ -110,11 +210,34 @@ private:
|
||||
size_t output_offset,
|
||||
bool resize_in = true, bool resize_out = true);
|
||||
|
||||
/** @brief Finalize a encryption/decryption process. Write remaining bytes
|
||||
* to the output
|
||||
* @param mode encrypt or decrypt
|
||||
* @param ctx the Cipher context object
|
||||
* @param output output buffer
|
||||
* @param output_offset where to start to append the last data within
|
||||
* the output buffer
|
||||
* @param resize_in resize the output buffer before appending data to it in
|
||||
* order to make sure there is enough room.
|
||||
* @param resize_out shrink the output buffer at the end
|
||||
*/
|
||||
size_t process_final(Mode mode, EvpCipherCtx& ctx,
|
||||
std::vector<unsigned char>& output,
|
||||
size_t output_offset,
|
||||
bool resize_in = true, bool resize_out = true);
|
||||
|
||||
/** @brief process a input and finalize it.
|
||||
* @param mode encrypt or decrypt
|
||||
* @param ctx the Cipher context object
|
||||
* @param begin beginning of the input chunk
|
||||
* @param end end of the input chunk
|
||||
* @param output output buffer
|
||||
* @param output_offset where to start to append the processed data within
|
||||
* the output buffer
|
||||
* @param resize_in resize the output buffer before appending data to it in
|
||||
* order to make sure there is enough room.
|
||||
* @param resize_out shrink the output buffer at the end
|
||||
*/
|
||||
size_t process_all(Mode mode, EvpCipherCtx& ctx,
|
||||
std::vector<unsigned char>::const_iterator begin,
|
||||
std::vector<unsigned char>::const_iterator end,
|
||||
|
@ -7,13 +7,13 @@
|
||||
using namespace horcrux;
|
||||
TEST(CryptoTest, encrypt1){
|
||||
const std::vector<unsigned char> plaintext(test1_str.begin(), test1_str.end());
|
||||
size_t output_len = plaintext.size() + 16;
|
||||
std::vector<unsigned char> output(output_len);
|
||||
const std::vector<unsigned char> key(test1_key.begin(), test1_key.end());
|
||||
const std::vector<unsigned char> iv(test1_iv.begin(), test1_iv.end());
|
||||
|
||||
AES256_CBC a;
|
||||
a.encrypt(key, iv, plaintext, output);
|
||||
auto output = a.encrypt(key, iv, plaintext);
|
||||
//remove iv from output
|
||||
output.erase(output.begin(), output.begin() + iv.size());
|
||||
|
||||
EXPECT_EQ(test1_enc, output);
|
||||
}
|
||||
@ -51,13 +51,11 @@ TEST(CryptoTest, encrypt3){
|
||||
|
||||
TEST(CryptoTest, decrypt1){
|
||||
const std::vector<unsigned char> plaintext(test1_str.begin(), test1_str.end());
|
||||
size_t output_len = test1_enc.size();
|
||||
std::vector<unsigned char> output(output_len);
|
||||
const std::vector<unsigned char> key(test1_key.begin(), test1_key.end());
|
||||
const std::vector<unsigned char> iv(test1_iv.begin(), test1_iv.end());
|
||||
|
||||
AES256_CBC a;
|
||||
a.decrypt(key, iv, test1_enc, output);
|
||||
auto output = a.decrypt(key, iv, test1_enc);
|
||||
|
||||
EXPECT_EQ(plaintext, output);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user