11 #include "errors/exceptions.h"
12 #include "string/format.h"
13 #include "utility/countof.h"
18 : _algorithm(algorithm),
19 _iterations(iterations),
20 _encrypt(EVP_CIPHER_CTX_new(), EVP_CIPHER_CTX_free),
21 _decrypt(EVP_CIPHER_CTX_new(), EVP_CIPHER_CTX_free)
27 _cipher = EVP_aes_128_cbc();
31 _cipher = EVP_aes_192_cbc();
35 _cipher = EVP_aes_256_cbc();
39 _cipher = EVP_aria_128_cbc();
43 _cipher = EVP_aria_192_cbc();
47 _cipher = EVP_aria_256_cbc();
50 _name =
"Camellia-128";
51 _cipher = EVP_camellia_128_cbc();
54 _name =
"Camellia-192";
55 _cipher = EVP_camellia_192_cbc();
58 _name =
"Camellia-256";
59 _cipher = EVP_camellia_256_cbc();
64 assert((_cipher !=
nullptr) &&
"Unknown cipher algorithm!");
65 if (_cipher ==
nullptr)
66 throwex CppCommon::SecurityException(
"Unknown cipher algorithm!");
69 assert((_encrypt !=
nullptr) &&
"Invalid cipher encrypt context!");
70 if (_encrypt ==
nullptr)
71 throwex CppCommon::SecurityException(
"Invalid cipher encrypt context!");
74 assert((_decrypt !=
nullptr) &&
"Invalid cipher decrypt context!");
75 if (_decrypt ==
nullptr)
76 throwex CppCommon::SecurityException(
"Invalid cipher decrypt context!");
81 std::string result(8, 0);
82 CppCommon::Memory::CryptoFill(result.data(), result.size());
88 int result = EVP_BytesToKey(_cipher, EVP_sha1(),
nullptr, (
const uint8_t*)secret.data(), (
int)secret.size(), (
int)_iterations, _key, _iv);
90 throwex CppCommon::SecurityException(CppCommon::format(
"Cannot initialize key and IV for {} cipher!", _name));
97 std::memcpy(salta, salt.data(), std::min(salt.size(), CppCommon::countof(salta)));
98 int result = EVP_BytesToKey(_cipher, EVP_sha1(), salta, (
const uint8_t*)secret.data(), (
int)secret.size(), (
int)_iterations, _key, _iv);
100 throwex CppCommon::SecurityException(CppCommon::format(
"Cannot initialize key and IV for {} cipher!", _name));
104 void Cipher::InitializeContext()
107 EVP_CIPHER_CTX_init(_encrypt.get());
108 if (EVP_EncryptInit_ex(_encrypt.get(), _cipher,
nullptr, _key, _iv) == 0)
109 throwex CppCommon::SecurityException(CppCommon::format(
"Cannot initialize encrypt context for {} cipher!", _name));
112 EVP_CIPHER_CTX_init(_decrypt.get());
113 if (EVP_DecryptInit_ex(_decrypt.get(), _cipher,
nullptr, _key, _iv) == 0)
114 throwex CppCommon::SecurityException(CppCommon::format(
"Cannot initialize decrypt context for {} cipher!", _name));
119 std::string result(str.size() + EVP_MAX_BLOCK_LENGTH, 0);
122 if (EVP_EncryptInit_ex(_encrypt.get(),
nullptr,
nullptr,
nullptr,
nullptr) == 0)
123 throwex CppCommon::SecurityException(CppCommon::format(
"Cannot initialize encrypt context for {} cipher!", _name));
127 if (EVP_EncryptUpdate(_encrypt.get(), (uint8_t*)result.data(), &cur_length, (
const uint8_t*)str.data(), (
int)str.size()) == 0)
128 throwex CppCommon::SecurityException(CppCommon::format(
"Cannot encrypt data with {} cipher!", _name));
132 if (EVP_EncryptFinal_ex(_encrypt.get(), (uint8_t*)result.data() + cur_length, &fin_length) == 0)
133 throwex CppCommon::SecurityException(CppCommon::format(
"Cannot finalize encrypted data with {} cipher!", _name));
136 result.resize(cur_length + fin_length);
142 std::string result(str.size(), 0);
145 if (EVP_DecryptInit_ex(_decrypt.get(),
nullptr,
nullptr,
nullptr,
nullptr) == 0)
146 throwex CppCommon::SecurityException(CppCommon::format(
"Cannot initialize decrypt context for {} cipher!", _name));
150 if (EVP_DecryptUpdate(_decrypt.get(), (uint8_t*)result.data(), &cur_length, (
const uint8_t*)str.data(), (
int)str.size()) == 0)
151 throwex CppCommon::SecurityException(CppCommon::format(
"Cannot decrypt data with {} cipher!", _name));
155 if (EVP_DecryptFinal_ex(_decrypt.get(), (uint8_t*)result.data() + cur_length, &fin_length) == 0)
156 throwex CppCommon::SecurityException(CppCommon::format(
"Cannot finalize decrypted data with {} cipher!", _name));
159 result.resize(cur_length + fin_length);
void Initialize(std::string_view secret)
Initialize the cipher with the given secret key.
CipherAlgorithm algorithm() const noexcept
Get the cipher algorithm.
static std::string GenerateSalt()
Generate the unique secret salt.
std::string Decrypt(std::string_view str)
Decrypt the given string.
std::string Encrypt(std::string_view str)
Encrypt the given string.
Cipher(CipherAlgorithm algorithm=CipherAlgorithm::AES256, size_t iterations=1000)
Initialize cipher with required algorithm.
CipherAlgorithm
Cipher algorithm.