feat: add openssl aes-ecb wrapper.
This commit is contained in:
@@ -19,6 +19,7 @@ using namespace llvm;
|
||||
#include <bit>
|
||||
|
||||
#include <cstring>
|
||||
#include <span>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
|
||||
|
||||
84
src/util/aes.cpp
Normal file
84
src/util/aes.cpp
Normal file
@@ -0,0 +1,84 @@
|
||||
#include "aes.h"
|
||||
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/evp.h>
|
||||
|
||||
namespace di {
|
||||
|
||||
void handle_openssl_errors() {
|
||||
std::string str;
|
||||
unsigned long code;
|
||||
while ((code = ERR_get_error()) != 0) {
|
||||
char buffer[256];
|
||||
ERR_error_string_n(code, buffer, sizeof(buffer));
|
||||
str += std::string(buffer) + "\n";
|
||||
}
|
||||
if (str.empty()) str = "Unknown error.";
|
||||
throw OpenSSLException("{}", str);
|
||||
}
|
||||
|
||||
AES::AES(const std::span<uint8_t>& key) : m_ctx(nullptr) {
|
||||
m_ctx = EVP_CIPHER_CTX_new();
|
||||
if (!m_ctx) {
|
||||
handle_openssl_errors();
|
||||
}
|
||||
|
||||
const EVP_CIPHER* cipher_type = nullptr;
|
||||
switch (key.size()) {
|
||||
case 16: // AES-128
|
||||
cipher_type = EVP_aes_128_ecb();
|
||||
break;
|
||||
case 24: // AES-192
|
||||
cipher_type = EVP_aes_192_ecb();
|
||||
break;
|
||||
case 32: // AES-256
|
||||
cipher_type = EVP_aes_256_ecb();
|
||||
break;
|
||||
default:
|
||||
EVP_CIPHER_CTX_free(m_ctx);
|
||||
throw OpenSSLException("Invalid key size. Must be 16/24/32 bytes.");
|
||||
}
|
||||
|
||||
if (EVP_DecryptInit_ex(m_ctx, cipher_type, nullptr, key.data(), nullptr)
|
||||
!= 1) {
|
||||
EVP_CIPHER_CTX_free(m_ctx);
|
||||
handle_openssl_errors();
|
||||
}
|
||||
}
|
||||
|
||||
AES::~AES() {
|
||||
if (m_ctx) {
|
||||
EVP_CIPHER_CTX_free(m_ctx);
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<uint8_t> AES::decrypt(const std::span<uint8_t>& ciphertext) {
|
||||
if (ciphertext.empty()) {
|
||||
return {};
|
||||
}
|
||||
|
||||
std::vector<uint8_t> plaintext(ciphertext.size());
|
||||
int len = 0;
|
||||
|
||||
if (EVP_DecryptUpdate(
|
||||
m_ctx,
|
||||
plaintext.data(),
|
||||
&len,
|
||||
ciphertext.data(),
|
||||
ciphertext.size()
|
||||
)
|
||||
!= 1) {
|
||||
handle_openssl_errors();
|
||||
}
|
||||
int plaintext_len = len;
|
||||
|
||||
if (EVP_DecryptFinal_ex(m_ctx, plaintext.data() + len, &len) != 1) {
|
||||
handle_openssl_errors();
|
||||
}
|
||||
plaintext_len += len;
|
||||
|
||||
plaintext.resize(plaintext_len);
|
||||
return plaintext;
|
||||
}
|
||||
|
||||
} // namespace di
|
||||
31
src/util/aes.h
Normal file
31
src/util/aes.h
Normal file
@@ -0,0 +1,31 @@
|
||||
#pragma once
|
||||
|
||||
#include <openssl/types.h>
|
||||
|
||||
namespace di {
|
||||
|
||||
class AES {
|
||||
public:
|
||||
explicit AES(const std::span<uint8_t>& key);
|
||||
|
||||
~AES();
|
||||
|
||||
AES(const AES&) = delete;
|
||||
AES(AES&&) = delete;
|
||||
AES& operator=(const AES&) = delete;
|
||||
AES& operator=(AES&&) = delete;
|
||||
|
||||
std::vector<uint8_t> decrypt(const std::span<uint8_t>& ciphertext);
|
||||
|
||||
private:
|
||||
EVP_CIPHER_CTX* m_ctx;
|
||||
};
|
||||
|
||||
class OpenSSLException : public RuntimeException<OpenSSLException> {
|
||||
public:
|
||||
using RuntimeException::RuntimeException;
|
||||
|
||||
constexpr std::string category() const { return "exception.ossl"; }
|
||||
};
|
||||
|
||||
} // namespace di
|
||||
@@ -5,6 +5,7 @@ add_requires('nlohmann_json 3.12.0')
|
||||
add_requires('xxhash 0.8.3')
|
||||
add_requires('libllvm 19.1.7')
|
||||
add_requires('magic_enum 0.9.7')
|
||||
add_requires('openssl3 3.5.1')
|
||||
add_requires('boost 1.88.0', {
|
||||
system = false,
|
||||
configs = {
|
||||
@@ -62,6 +63,7 @@ target('libdi')
|
||||
'libllvm',
|
||||
'boost',
|
||||
'nlohmann_json',
|
||||
'openssl3',
|
||||
{public = true}
|
||||
)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user