CppSecurity 1.1.2.0
C++ Security Library
Loading...
Searching...
No Matches
cipher.cpp
Go to the documentation of this file.
1
9#include "security/cipher.h"
10
11#include "errors/exceptions.h"
12#include "string/format.h"
13#include "utility/countof.h"
14
15namespace CppSecurity {
16
17Cipher::Cipher(CipherAlgorithm algorithm, size_t iterations)
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)
22{
23 switch (algorithm)
24 {
26 _name = "AES-128";
27 _cipher = EVP_aes_128_cbc();
28 break;
30 _name = "AES-192";
31 _cipher = EVP_aes_192_cbc();
32 break;
34 _name = "AES-256";
35 _cipher = EVP_aes_256_cbc();
36 break;
38 _name = "ARIA-128";
39 _cipher = EVP_aria_128_cbc();
40 break;
42 _name = "ARIA-192";
43 _cipher = EVP_aria_192_cbc();
44 break;
46 _name = "ARIA-256";
47 _cipher = EVP_aria_256_cbc();
48 break;
50 _name = "Camellia-128";
51 _cipher = EVP_camellia_128_cbc();
52 break;
54 _name = "Camellia-192";
55 _cipher = EVP_camellia_192_cbc();
56 break;
58 _name = "Camellia-256";
59 _cipher = EVP_camellia_256_cbc();
60 break;
61 }
62
63 // Validate cipher algorithm
64 assert((_cipher != nullptr) && "Unknown cipher algorithm!");
65 if (_cipher == nullptr)
66 throwex CppCommon::SecurityException("Unknown cipher algorithm!");
67
68 // Validate cipher encrypt context
69 assert((_encrypt != nullptr) && "Invalid cipher encrypt context!");
70 if (_encrypt == nullptr)
71 throwex CppCommon::SecurityException("Invalid cipher encrypt context!");
72
73 // Validate cipher decrypt context
74 assert((_decrypt != nullptr) && "Invalid cipher decrypt context!");
75 if (_decrypt == nullptr)
76 throwex CppCommon::SecurityException("Invalid cipher decrypt context!");
77}
78
80{
81 std::string result(8, 0);
82 CppCommon::Memory::CryptoFill(result.data(), result.size());
83 return result;
84}
85
86void Cipher::Initialize(std::string_view secret)
87{
88 int result = EVP_BytesToKey(_cipher, EVP_sha1(), nullptr, (const uint8_t*)secret.data(), (int)secret.size(), (int)_iterations, _key, _iv);
89 if (result == 0)
90 throwex CppCommon::SecurityException(CppCommon::format("Cannot initialize key and IV for {} cipher!", _name));
91 InitializeContext();
92}
93
94void Cipher::Initialize(std::string_view secret, std::string_view salt)
95{
96 uint8_t salta[8];
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);
99 if (result == 0)
100 throwex CppCommon::SecurityException(CppCommon::format("Cannot initialize key and IV for {} cipher!", _name));
101 InitializeContext();
102}
103
104void Cipher::InitializeContext()
105{
106 // Initialize encrypt context
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));
110
111 // Initialize decrypt context
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));
115}
116
117std::string Cipher::Encrypt(std::string_view str)
118{
119 std::string result(str.size() + EVP_MAX_BLOCK_LENGTH, 0);
120
121 // Initialize encrypt context
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));
124
125 // Update encrypt context with plane data
126 int cur_length = 0;
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));
129
130 // Finalize the encrypted context
131 int fin_length = 0;
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));
134
135 // Return the encrypted data
136 result.resize(cur_length + fin_length);
137 return result;
138}
139
140std::string Cipher::Decrypt(std::string_view str)
141{
142 std::string result(str.size(), 0);
143
144 // Initialize decrypt context
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));
147
148 // Update decrypt context with encrypted data
149 int cur_length = 0;
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));
152
153 // Finalize the decrypted data
154 int fin_length = 0;
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));
157
158 // Return the decrypted data
159 result.resize(cur_length + fin_length);
160 return result;
161}
162
163} // namespace CppSecurity
Cipher definition.
void Initialize(std::string_view secret)
Initialize the cipher with the given secret key.
Definition cipher.cpp:86
CipherAlgorithm algorithm() const noexcept
Get the cipher algorithm.
Definition cipher.h:75
static std::string GenerateSalt()
Generate the unique secret salt.
Definition cipher.cpp:79
std::string Decrypt(std::string_view str)
Decrypt the given string.
Definition cipher.cpp:140
std::string Encrypt(std::string_view str)
Encrypt the given string.
Definition cipher.cpp:117
Cipher(CipherAlgorithm algorithm=CipherAlgorithm::AES256, size_t iterations=1000)
Initialize cipher with required algorithm.
Definition cipher.cpp:17
CipherAlgorithm
Cipher algorithm.
Definition cipher.h:22