1
0
mirror of synced 2025-01-18 00:56:49 +01:00

Added AES decryption node

This commit is contained in:
WerWolv 2021-02-04 00:21:53 +01:00
parent ac019a7d7e
commit 91d05c5de6
3 changed files with 206 additions and 10 deletions

View File

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

View File

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

View File

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