From d96e828be83f7adf0fe88001da865169cfd573c7 Mon Sep 17 00:00:00 2001 From: Malfurious Date: Tue, 22 Oct 2024 02:45:53 -0400 Subject: Refactor AES functions to use mbedtls Signed-off-by: Malfurious --- Cryptor.cpp | 137 +++++++++++++++++++++++++++++++++++++++++++++--------------- Cryptor.h | 15 +++---- 2 files changed, 112 insertions(+), 40 deletions(-) diff --git a/Cryptor.cpp b/Cryptor.cpp index 57ded9a..fc27caf 100644 --- a/Cryptor.cpp +++ b/Cryptor.cpp @@ -1,54 +1,98 @@ #include "Cryptor.h" bool Cryptor::haveKey = false; -unsigned char Cryptor::key[CryptoPP::AES::DEFAULT_KEYLENGTH]; +unsigned char Cryptor::key[AES_BLOCK_LENGTH]; + +static void toHex(char *output, const void *input, size_t size) { + const unsigned char *_input = (const unsigned char *)input; + for (size_t i = 0; i < size; i++) { + sprintf(output+(i*2), "%02hhX", _input[i]); + } +} + +static void fromHex(void *output, const char *input) { + unsigned char *_output = (unsigned char *)output; + size_t size = strlen(input); + if (size & 1) { + throw 1; + } else { + size /= 2; + } + for (size_t i = 0; i < size; i++) { + if (sscanf(input+(i*2), "%02hhx", &_output[i]) != 1) { + throw 1; + } + } +} void Cryptor::encryptAndSave(std::string remoteHost, std::string port, std::string directory, std::string payload) { // Key - if (!haveKey) + if (!haveKey) { assembleKey(true); + } // IV - unsigned char iv[CryptoPP::AES::BLOCKSIZE]; - CryptoPP::AutoSeededRandomPool randl; - randl.GenerateBlock(iv, sizeof(iv)); + unsigned char iv[AES_BLOCK_LENGTH]; + generateRandom(iv, sizeof(iv)); // Encrypt - std::string cipher; - CryptoPP::CBC_Mode::Encryption enc(key, sizeof(key), iv); - CryptoPP::StringSource(payload, true, new CryptoPP::StreamTransformationFilter(enc, new CryptoPP::StringSink(cipher))); + size_t ciphertextLen = 0; + unsigned char *ciphertext = new unsigned char[payload.size() + 64]; + const mbedtls_cipher_info_t *cipherInfo = mbedtls_cipher_info_from_type(MBEDTLS_CIPHER_AES_128_CBC); + mbedtls_cipher_context_t cipher; + + mbedtls_cipher_init(&cipher); + mbedtls_cipher_setup(&cipher, cipherInfo); + mbedtls_cipher_setkey(&cipher, key, sizeof(key)*8, MBEDTLS_ENCRYPT); + mbedtls_cipher_set_padding_mode(&cipher, MBEDTLS_PADDING_PKCS7); + mbedtls_cipher_crypt(&cipher, iv, sizeof(iv), + (const unsigned char *)payload.c_str(), payload.size(), + ciphertext, &ciphertextLen); + mbedtls_cipher_free(&cipher); // Save Data - std::string encIV, encCipher; - CryptoPP::StringSource(iv, sizeof(iv), true, new CryptoPP::HexEncoder(new CryptoPP::StringSink(encIV))); - CryptoPP::StringSource(cipher, true, new CryptoPP::HexEncoder(new CryptoPP::StringSink(encCipher))); + char encIV[(AES_BLOCK_LENGTH * 2) + 1]; + char *encCipher = new char[(ciphertextLen * 2) + 1]; + toHex(encIV, iv, sizeof(iv)); + toHex(encCipher, ciphertext, ciphertextLen); + std::string _encIV(encIV); + std::string _encCipher(encCipher); + + delete[] encCipher; + delete[] ciphertext; + if (remoteHost == "") { - if (directory[directory.size() - 1] != '/') directory += "/"; + if (directory[directory.size() - 1] != '/') { + directory += "/"; + } directory += KEYCHAIN_FILE; std::ofstream f(directory.c_str()); - f << encIV << std::endl; - f << encCipher << std::endl; + f << _encIV << std::endl; + f << _encCipher << std::endl; f.close(); - } - else { + } else { Socket s; std::string err = ""; s.conn(remoteHost, port); s.sendline("store"); s.sendline(directory); - s.sendline(encIV); - s.sendline(encCipher); + s.sendline(_encIV); + s.sendline(_encCipher); err = s.readline(); s.clo(); - if (err != "OK") throw 1; + if (err != "OK") { + throw 1; + } } } std::string Cryptor::loadAndDecrypt(std::string remoteHost, std::string port, std::string directory) { // Load Data - std::string encIV, encCipher, ivstr, cipher; + std::string encIV, encCipher; if (remoteHost == "") { - if (directory[directory.size() - 1] != '/') directory += "/"; + if (directory[directory.size() - 1] != '/') { + directory += "/"; + } directory += KEYCHAIN_FILE; std::ifstream f(directory.c_str()); if (!f.good()) { @@ -58,8 +102,7 @@ std::string Cryptor::loadAndDecrypt(std::string remoteHost, std::string port, st f >> encIV; f >> encCipher; f.close(); - } - else { + } else { Socket s; std::string err = ""; s.conn(remoteHost, port); @@ -74,21 +117,37 @@ std::string Cryptor::loadAndDecrypt(std::string remoteHost, std::string port, st encCipher = s.readline(); s.clo(); } - CryptoPP::StringSource(encIV, true, new CryptoPP::HexDecoder(new CryptoPP::StringSink(ivstr))); - CryptoPP::StringSource(encCipher, true, new CryptoPP::HexDecoder(new CryptoPP::StringSink(cipher))); + + // Decode data + unsigned char *ciphertext = new unsigned char[encCipher.size() / 2]; + unsigned char iv[AES_BLOCK_LENGTH]; + fromHex(ciphertext, encCipher.c_str()); + fromHex(iv, encIV.c_str()); // Key - if (!haveKey) + if (!haveKey) { assembleKey(); - - // IV - unsigned char iv[CryptoPP::AES::BLOCKSIZE]; - memcpy(iv, ivstr.c_str(), ivstr.size()); + } // Decrypt - std::string payload; - CryptoPP::CBC_Mode::Decryption dec(key, sizeof(key), iv); - CryptoPP::StringSource(cipher, true, new CryptoPP::StreamTransformationFilter(dec, new CryptoPP::StringSink(payload))); + size_t plaintextLen = 0; + char *plaintext = new char[(encCipher.size() / 2) + 64]; + const mbedtls_cipher_info_t *cipherInfo = mbedtls_cipher_info_from_type(MBEDTLS_CIPHER_AES_128_CBC); + mbedtls_cipher_context_t cipher; + + mbedtls_cipher_init(&cipher); + mbedtls_cipher_setup(&cipher, cipherInfo); + mbedtls_cipher_setkey(&cipher, key, sizeof(key)*8, MBEDTLS_DECRYPT); + mbedtls_cipher_set_padding_mode(&cipher, MBEDTLS_PADDING_PKCS7); + mbedtls_cipher_crypt(&cipher, iv, sizeof(iv), + ciphertext, (encCipher.size() / 2), + (unsigned char *)plaintext, &plaintextLen); + mbedtls_cipher_free(&cipher); + + std::string payload(plaintext, plaintextLen); + + delete[] plaintext; + delete[] ciphertext; return payload; } @@ -174,6 +233,18 @@ void Cryptor::sha256(std::string str) { haveKey = true; } +void Cryptor::generateRandom(void *output, size_t size) { + mbedtls_entropy_context entropy; + mbedtls_ctr_drbg_context random; + + mbedtls_entropy_init(&entropy); + mbedtls_ctr_drbg_init(&random); + mbedtls_ctr_drbg_seed(&random, mbedtls_entropy_func, &entropy, NULL, 0); + mbedtls_ctr_drbg_random(&random, (unsigned char *)output, size); + mbedtls_ctr_drbg_free(&random); + mbedtls_entropy_free(&entropy); +} + std::string Cryptor::readPassword(bool confirm) { std::string password; diff --git a/Cryptor.h b/Cryptor.h index 8ba1c16..1fcac36 100644 --- a/Cryptor.h +++ b/Cryptor.h @@ -4,6 +4,7 @@ #include #include #include +#include #ifdef WIN32 #include @@ -12,17 +13,16 @@ #include #endif // WIN32 -#include "cryptopp562/osrng.h" -#include "cryptopp562/cryptlib.h" -#include "cryptopp562/hex.h" -#include "cryptopp562/filters.h" -#include "cryptopp562/aes.h" -#include "cryptopp562/ccm.h" +#include "mbedtls/cipher.h" +#include "mbedtls/ctr_drbg.h" +#include "mbedtls/entropy.h" #include "Socket.h" #define DEF_PASSWD_LENGTH 50 +#define AES_BLOCK_LENGTH 16 + #define KEYCHAIN_FILE ".compasskeychain" #define PASSWORD_PROMPT "ComPASS Password: " #define PASSWORD_CONF "Confirm Password: " @@ -49,9 +49,10 @@ public: private: static bool haveKey; - static unsigned char key[CryptoPP::AES::DEFAULT_KEYLENGTH]; + static unsigned char key[AES_BLOCK_LENGTH]; static void sha256(std::string str); + static void generateRandom(void *output, size_t size); static std::string readPassword(bool confirm); static std::string readPassword(); static void assembleKey(bool confirm); -- cgit v1.2.3