5#ifdef MAL_PACKET_WEAVER_HAS_OPENSSL
6namespace mal_packet_weaver::crypto::AES
12 class AES256 final :
public non_copyable_non_movable,
public EncryptionInterface
19 static constexpr uint32_t KEY_SIZE = 32;
23 static constexpr uint32_t SALT_SIZE = 8;
31 AES256(
const KeyView input_key,
const ByteView salt,
const int n_rounds = 5)
33 AlwaysAssert(input_key.size() == 32,
"Key size must be 32 bytes");
34 AlwaysAssert(salt.size() == 8,
"Salt size must be 8 bytes");
36 unsigned char key[32], iv[32];
44 EVP_BytesToKey(EVP_aes_256_cbc(), EVP_sha1(), salt.as<
unsigned char>(), input_key.as<
unsigned char>(),
45 static_cast<int>(input_key.size()), n_rounds, key, iv);
47 AlwaysAssert(i == 32,
"Key size is " + std::to_string(i) +
" bytes - should be 256 bits");
49 encrypt_context_.reset(EVP_CIPHER_CTX_new());
50 decrypt_context_.reset(EVP_CIPHER_CTX_new());
51 EVP_CIPHER_CTX_init(encrypt_context_.get());
52 EVP_EncryptInit_ex(encrypt_context_.get(), EVP_aes_256_cbc(),
nullptr, key, iv);
53 EVP_CIPHER_CTX_init(decrypt_context_.get());
54 EVP_DecryptInit_ex(decrypt_context_.get(), EVP_aes_256_cbc(),
nullptr, key, iv);
61 [[nodiscard]] ByteArray encrypt(
const ByteView plaintext)
const override
64 AlwaysAssert(plaintext.size() < INT_MAX - AES_BLOCK_SIZE,
"Plaintext size is too large");
65 int c_len =
static_cast<int>(plaintext.size() + AES_BLOCK_SIZE);
68 ciphertext.resize(c_len);
70 EVP_EncryptInit_ex(encrypt_context_.get(),
nullptr,
nullptr,
nullptr,
nullptr);
71 EVP_EncryptUpdate(encrypt_context_.get(), ciphertext.as<
unsigned char>(), &c_len,
72 plaintext.as<
unsigned char>(),
static_cast<int>(plaintext.size()));
73 EVP_EncryptFinal_ex(encrypt_context_.get(), ciphertext.as<
unsigned char>() + c_len, &f_len);
75 ciphertext.resize(c_len + f_len);
84 [[nodiscard]] ByteArray decrypt(
const ByteView ciphertext)
const override
87 int p_len =
static_cast<int>(ciphertext.size());
90 plaintext.resize(p_len);
91 EVP_DecryptInit_ex(decrypt_context_.get(),
nullptr,
nullptr,
nullptr,
nullptr);
92 EVP_DecryptUpdate(decrypt_context_.get(), plaintext.as<
unsigned char>(), &p_len,
93 ciphertext.as<
unsigned char>(),
static_cast<int>(ciphertext.size()));
94 EVP_DecryptFinal_ex(decrypt_context_.get(), plaintext.as<
unsigned char>() + p_len, &f_len);
95 plaintext.resize(p_len + f_len);
98 void encrypt_in_place(ByteArray &plaintext)
const override
100 auto tmp = encrypt(plaintext);
103 void decrypt_in_place(ByteArray &ciphertext)
const override
105 auto tmp = decrypt(ciphertext);
110 EVP_CIPHER_CTX_WRAPPER encrypt_context_;
111 EVP_CIPHER_CTX_WRAPPER decrypt_context_;