feat: add openssl aes-ecb wrapper.

This commit is contained in:
2025-08-20 14:44:38 +08:00
parent 15df2fab99
commit ddecaeee6b
4 changed files with 118 additions and 0 deletions

View File

@@ -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
View 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
View 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

View File

@@ -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}
)