Added AES decryption node
This commit is contained in:
parent
ac019a7d7e
commit
91d05c5de6
@ -1,14 +1,51 @@
|
|||||||
#include <hex/plugin.hpp>
|
#include <hex/plugin.hpp>
|
||||||
|
|
||||||
#include "math_evaluator.hpp"
|
|
||||||
|
|
||||||
#include <hex/helpers/crypto.hpp>
|
#include <hex/helpers/crypto.hpp>
|
||||||
|
|
||||||
|
#include <cctype>
|
||||||
|
|
||||||
namespace hex::plugin::builtin {
|
namespace hex::plugin::builtin {
|
||||||
|
|
||||||
|
class NodeNullptr : public dp::Node {
|
||||||
|
public:
|
||||||
|
NodeNullptr() : Node("Nullptr", { dp::Attribute(dp::Attribute::IOType::Out, dp::Attribute::Type::Buffer, "") }) {}
|
||||||
|
|
||||||
|
void process() override {
|
||||||
|
this->setBufferOnOutput(0, { });
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
u64 m_value = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
class NodeString : public dp::Node {
|
||||||
|
public:
|
||||||
|
NodeString() : Node("String", { dp::Attribute(dp::Attribute::IOType::Out, dp::Attribute::Type::Buffer, "") }) {
|
||||||
|
this->m_value.resize(0xFFF, 0x00);
|
||||||
|
}
|
||||||
|
|
||||||
|
void drawNode() override {
|
||||||
|
ImGui::PushItemWidth(100);
|
||||||
|
ImGui::InputText("##string", reinterpret_cast<char*>(this->m_value.data()), this->m_value.size() - 1);
|
||||||
|
ImGui::PopItemWidth();
|
||||||
|
}
|
||||||
|
|
||||||
|
void process() override {
|
||||||
|
std::vector<u8> output(std::strlen(this->m_value.c_str()) + 1, 0x00);
|
||||||
|
std::strcpy(reinterpret_cast<char*>(output.data()), this->m_value.c_str());
|
||||||
|
|
||||||
|
output.pop_back();
|
||||||
|
|
||||||
|
this->setBufferOnOutput(0, output);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::string m_value;
|
||||||
|
};
|
||||||
|
|
||||||
class NodeInteger : public dp::Node {
|
class NodeInteger : public dp::Node {
|
||||||
public:
|
public:
|
||||||
NodeInteger() : Node("Integer", { dp::Attribute(dp::Attribute::IOType::Out, dp::Attribute::Type::Integer, "Value") }) {}
|
NodeInteger() : Node("Integer", { dp::Attribute(dp::Attribute::IOType::Out, dp::Attribute::Type::Integer, "") }) {}
|
||||||
|
|
||||||
void drawNode() override {
|
void drawNode() override {
|
||||||
ImGui::TextUnformatted("0x"); ImGui::SameLine(0, 0);
|
ImGui::TextUnformatted("0x"); ImGui::SameLine(0, 0);
|
||||||
@ -30,7 +67,7 @@ namespace hex::plugin::builtin {
|
|||||||
|
|
||||||
class NodeFloat : public dp::Node {
|
class NodeFloat : public dp::Node {
|
||||||
public:
|
public:
|
||||||
NodeFloat() : Node("Float", { dp::Attribute(dp::Attribute::IOType::Out, dp::Attribute::Type::Float, "Value") }) {}
|
NodeFloat() : Node("Float", { dp::Attribute(dp::Attribute::IOType::Out, dp::Attribute::Type::Float, "") }) {}
|
||||||
|
|
||||||
void drawNode() override {
|
void drawNode() override {
|
||||||
ImGui::PushItemWidth(100);
|
ImGui::PushItemWidth(100);
|
||||||
@ -406,9 +443,112 @@ namespace hex::plugin::builtin {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class NodeCryptoAESDecrypt : public dp::Node {
|
||||||
|
public:
|
||||||
|
NodeCryptoAESDecrypt() : Node("Decrypt AES", { dp::Attribute(dp::Attribute::IOType::In, dp::Attribute::Type::Buffer, "Key"),
|
||||||
|
dp::Attribute(dp::Attribute::IOType::In, dp::Attribute::Type::Buffer, "IV"),
|
||||||
|
dp::Attribute(dp::Attribute::IOType::In, dp::Attribute::Type::Buffer, "Nonce"),
|
||||||
|
dp::Attribute(dp::Attribute::IOType::In, dp::Attribute::Type::Buffer, "Input"),
|
||||||
|
dp::Attribute(dp::Attribute::IOType::Out, dp::Attribute::Type::Buffer, "Output") }) {}
|
||||||
|
|
||||||
|
void drawNode() override {
|
||||||
|
ImGui::PushItemWidth(100);
|
||||||
|
ImGui::Combo("Mode", &this->m_mode, "ECB\0CBC\0CFB128\0CTR\0GCM\0CCM\0OFB\0");
|
||||||
|
ImGui::Combo("Key Length", &this->m_keyLength, "128 Bits\000192 Bits\000256 Bits\000");
|
||||||
|
ImGui::PopItemWidth();
|
||||||
|
}
|
||||||
|
|
||||||
|
void process() override {
|
||||||
|
auto key = this->getBufferOnInput(0);
|
||||||
|
auto iv = this->getBufferOnInput(1);
|
||||||
|
auto nonce = this->getBufferOnInput(2);
|
||||||
|
auto input = this->getBufferOnInput(3);
|
||||||
|
|
||||||
|
if (!key.has_value() || !iv.has_value() || !nonce.has_value() || !input.has_value())
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (key->empty() || input->empty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
std::array<u8, 8> ivData = { 0 }, nonceData = { 0 };
|
||||||
|
|
||||||
|
std::copy(iv->begin(), iv->end(), ivData.begin());
|
||||||
|
std::copy(nonce->begin(), nonce->end(), nonceData.begin());
|
||||||
|
|
||||||
|
auto output = crypt::aesDecrypt(static_cast<crypt::AESMode>(this->m_mode), static_cast<crypt::KeyLength>(this->m_keyLength), key.value(), nonceData, ivData, input.value());
|
||||||
|
|
||||||
|
this->setBufferOnOutput(4, output);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
int m_mode = 0;
|
||||||
|
int m_keyLength = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
class NodeDecodingBase64 : public dp::Node {
|
||||||
|
public:
|
||||||
|
NodeDecodingBase64() : Node("Base64 Decoder", {
|
||||||
|
dp::Attribute(dp::Attribute::IOType::In, dp::Attribute::Type::Buffer, "In"),
|
||||||
|
dp::Attribute(dp::Attribute::IOType::Out, dp::Attribute::Type::Buffer, "Out") }) {}
|
||||||
|
|
||||||
|
void process() override {
|
||||||
|
auto input = this->getBufferOnInput(0);
|
||||||
|
|
||||||
|
if (!input.has_value())
|
||||||
|
return;
|
||||||
|
|
||||||
|
auto output = crypt::decode64(input.value());
|
||||||
|
|
||||||
|
this->setBufferOnOutput(1, output);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class NodeDecodingHex : public dp::Node {
|
||||||
|
public:
|
||||||
|
NodeDecodingHex() : Node("Hexadecimal Decoder", {
|
||||||
|
dp::Attribute(dp::Attribute::IOType::In, dp::Attribute::Type::Buffer, "In"),
|
||||||
|
dp::Attribute(dp::Attribute::IOType::Out, dp::Attribute::Type::Buffer, "Out") }) {}
|
||||||
|
|
||||||
|
void process() override {
|
||||||
|
auto input = this->getBufferOnInput(0);
|
||||||
|
|
||||||
|
if (!input.has_value())
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (input->size() % 2 != 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
std::vector<u8> output;
|
||||||
|
for (u32 i = 0; i < input->size(); i += 2) {
|
||||||
|
char c1 = tolower(input->at(i));
|
||||||
|
char c2 = tolower(input->at(i + 1));
|
||||||
|
|
||||||
|
if (!std::isxdigit(c1) || !isxdigit(c2))
|
||||||
|
return;
|
||||||
|
|
||||||
|
u8 value;
|
||||||
|
if (std::isdigit(c1))
|
||||||
|
value = (c1 - '0') << 4;
|
||||||
|
else
|
||||||
|
value = ((c1 - 'a') + 0x0A) << 4;
|
||||||
|
|
||||||
|
if (std::isdigit(c2))
|
||||||
|
value |= c2 - '0';
|
||||||
|
else
|
||||||
|
value |= (c2 - 'a') + 0x0A;
|
||||||
|
|
||||||
|
output.push_back(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
this->setBufferOnOutput(1, output);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
void registerDataProcessorNodes() {
|
void registerDataProcessorNodes() {
|
||||||
ContentRegistry::DataProcessorNode::add<NodeInteger>("Constants", "Integer");
|
ContentRegistry::DataProcessorNode::add<NodeInteger>("Constants", "Integer");
|
||||||
ContentRegistry::DataProcessorNode::add<NodeFloat>("Constants", "Float");
|
ContentRegistry::DataProcessorNode::add<NodeFloat>("Constants", "Float");
|
||||||
|
ContentRegistry::DataProcessorNode::add<NodeNullptr>("Constants", "Nullptr");
|
||||||
|
ContentRegistry::DataProcessorNode::add<NodeString>("Constants", "String");
|
||||||
ContentRegistry::DataProcessorNode::add<NodeRGBA8>("Constants", "RGBA8 Color");
|
ContentRegistry::DataProcessorNode::add<NodeRGBA8>("Constants", "RGBA8 Color");
|
||||||
|
|
||||||
ContentRegistry::DataProcessorNode::add<NodeDisplayInteger>("Display", "Integer");
|
ContentRegistry::DataProcessorNode::add<NodeDisplayInteger>("Display", "Integer");
|
||||||
@ -432,6 +572,11 @@ namespace hex::plugin::builtin {
|
|||||||
ContentRegistry::DataProcessorNode::add<NodeBitwiseOR>("Bitwise Operations", "OR");
|
ContentRegistry::DataProcessorNode::add<NodeBitwiseOR>("Bitwise Operations", "OR");
|
||||||
ContentRegistry::DataProcessorNode::add<NodeBitwiseXOR>("Bitwise Operations", "XOR");
|
ContentRegistry::DataProcessorNode::add<NodeBitwiseXOR>("Bitwise Operations", "XOR");
|
||||||
ContentRegistry::DataProcessorNode::add<NodeBitwiseNOT>("Bitwise Operations", "NOT");
|
ContentRegistry::DataProcessorNode::add<NodeBitwiseNOT>("Bitwise Operations", "NOT");
|
||||||
|
|
||||||
|
ContentRegistry::DataProcessorNode::add<NodeDecodingBase64>("Decoding", "Base64");
|
||||||
|
ContentRegistry::DataProcessorNode::add<NodeDecodingHex>("Decoding", "Hexadecimal");
|
||||||
|
|
||||||
|
ContentRegistry::DataProcessorNode::add<NodeCryptoAESDecrypt>("Crypto", "AES");
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -27,5 +27,22 @@ namespace hex::crypt {
|
|||||||
std::vector<u8> decode64(const std::vector<u8> &input);
|
std::vector<u8> decode64(const std::vector<u8> &input);
|
||||||
std::vector<u8> encode64(const std::vector<u8> &input);
|
std::vector<u8> encode64(const std::vector<u8> &input);
|
||||||
|
|
||||||
std::vector<u8> aesCtrDecrypt(const std::vector<u8> &key, std::array<u8, 8> nonce, std::array<u8, 8> iv, const std::vector<u8> &input);
|
enum class AESMode : u8 {
|
||||||
|
ECB = 0,
|
||||||
|
CBC = 1,
|
||||||
|
CFB128 = 2,
|
||||||
|
CTR = 3,
|
||||||
|
GCM = 4,
|
||||||
|
CCM = 5,
|
||||||
|
OFB = 6,
|
||||||
|
XTS = 7
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class KeyLength : u8 {
|
||||||
|
Key128Bits = 0,
|
||||||
|
Key192Bits = 1,
|
||||||
|
Key256Bits = 2
|
||||||
|
};
|
||||||
|
|
||||||
|
std::vector<u8> aesDecrypt(AESMode mode, KeyLength keyLength, const std::vector<u8> &key, std::array<u8, 8> nonce, std::array<u8, 8> iv, const std::vector<u8> &input);
|
||||||
}
|
}
|
@ -241,24 +241,58 @@ namespace hex::crypt {
|
|||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<u8> aesCtrDecrypt(const std::vector<u8> &key, std::array<u8, 8> nonce, std::array<u8, 8> iv, const std::vector<u8> &input) {
|
static std::vector<u8> aes(mbedtls_cipher_type_t type, mbedtls_operation_t operation, const std::vector<u8> &key, std::array<u8, 8> nonce, std::array<u8, 8> iv, const std::vector<u8> &input) {
|
||||||
std::vector<u8> output(input.size());
|
std::vector<u8> output;
|
||||||
|
|
||||||
|
if (input.empty())
|
||||||
|
return { };
|
||||||
|
|
||||||
mbedtls_cipher_context_t ctx;
|
mbedtls_cipher_context_t ctx;
|
||||||
|
auto cipherInfo = mbedtls_cipher_info_from_type(type);
|
||||||
|
|
||||||
mbedtls_cipher_setup(&ctx, mbedtls_cipher_info_from_type(MBEDTLS_CIPHER_AES_128_CTR));
|
|
||||||
|
|
||||||
mbedtls_cipher_setkey(&ctx, key.data(), key.size() * 8, MBEDTLS_DECRYPT);
|
mbedtls_cipher_setup(&ctx, cipherInfo);
|
||||||
|
mbedtls_cipher_setkey(&ctx, key.data(), key.size() * 8, operation);
|
||||||
|
|
||||||
std::array<u8, 16> nonceCounter = { 0 };
|
std::array<u8, 16> nonceCounter = { 0 };
|
||||||
std::copy(nonce.begin(), nonce.end(), nonceCounter.begin());
|
std::copy(nonce.begin(), nonce.end(), nonceCounter.begin());
|
||||||
std::copy(iv.begin(), iv.end(), nonceCounter.begin() + 8);
|
std::copy(iv.begin(), iv.end(), nonceCounter.begin() + 8);
|
||||||
|
|
||||||
size_t outputSize = output.size();
|
size_t outputSize = input.size() + cipherInfo->block_size;
|
||||||
|
output.resize(outputSize, 0x00);
|
||||||
mbedtls_cipher_crypt(&ctx, nonceCounter.data(), nonceCounter.size(), input.data(), input.size(), output.data(), &outputSize);
|
mbedtls_cipher_crypt(&ctx, nonceCounter.data(), nonceCounter.size(), input.data(), input.size(), output.data(), &outputSize);
|
||||||
|
|
||||||
mbedtls_cipher_free(&ctx);
|
mbedtls_cipher_free(&ctx);
|
||||||
|
|
||||||
|
output.resize(input.size());
|
||||||
|
|
||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<u8> aesDecrypt(AESMode mode, KeyLength keyLength, const std::vector<u8> &key, std::array<u8, 8> nonce, std::array<u8, 8> iv, const std::vector<u8> &input) {
|
||||||
|
switch (keyLength) {
|
||||||
|
case KeyLength::Key128Bits: if (key.size() != 128 / 8) return { }; break;
|
||||||
|
case KeyLength::Key192Bits: if (key.size() != 192 / 8) return { }; break;
|
||||||
|
case KeyLength::Key256Bits: if (key.size() != 256 / 8) return { }; break;
|
||||||
|
default: return { };
|
||||||
|
}
|
||||||
|
|
||||||
|
mbedtls_cipher_type_t type;
|
||||||
|
switch (mode) {
|
||||||
|
case AESMode::ECB: type = MBEDTLS_CIPHER_AES_128_ECB; break;
|
||||||
|
case AESMode::CBC: type = MBEDTLS_CIPHER_AES_128_CBC; break;
|
||||||
|
case AESMode::CFB128: type = MBEDTLS_CIPHER_AES_128_CFB128; break;
|
||||||
|
case AESMode::CTR: type = MBEDTLS_CIPHER_AES_128_CTR; break;
|
||||||
|
case AESMode::GCM: type = MBEDTLS_CIPHER_AES_128_GCM; break;
|
||||||
|
case AESMode::CCM: type = MBEDTLS_CIPHER_AES_128_CCM; break;
|
||||||
|
case AESMode::OFB: type = MBEDTLS_CIPHER_AES_128_OFB; break;
|
||||||
|
case AESMode::XTS: type = MBEDTLS_CIPHER_AES_128_XTS; break;
|
||||||
|
default: return { };
|
||||||
|
}
|
||||||
|
|
||||||
|
type = mbedtls_cipher_type_t(type + u8(keyLength));
|
||||||
|
|
||||||
|
return aes(type, MBEDTLS_DECRYPT, key, nonce, iv, input);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
Loading…
x
Reference in New Issue
Block a user