2022-05-22 13:07:40 +02:00
|
|
|
#include "GCrypt/GWrapper.h"
|
2022-05-22 12:51:58 +02:00
|
|
|
#include "GCrypt/GCipher.h"
|
2022-05-16 22:35:28 +02:00
|
|
|
#include "GCrypt/Util.h"
|
2022-05-26 00:55:24 +02:00
|
|
|
#include <vector>
|
2022-05-16 22:15:34 +02:00
|
|
|
|
|
|
|
namespace Leonetienne::GCrypt {
|
|
|
|
|
2022-05-22 13:43:23 +02:00
|
|
|
std::string GWrapper::EncryptString(
|
|
|
|
const std::string& cleartext,
|
|
|
|
const Key& key)
|
|
|
|
{
|
2022-05-16 22:15:34 +02:00
|
|
|
// Recode the ascii-string to bits
|
2022-05-26 15:04:39 +02:00
|
|
|
const std::vector<Block> cleartext_blocks = StringToBitblocks(cleartext);
|
2022-05-16 22:15:34 +02:00
|
|
|
|
2022-05-26 15:04:39 +02:00
|
|
|
// Create cipher instance
|
|
|
|
GCipher cipher(key, GCipher::DIRECTION::ENCIPHER);
|
2022-05-16 22:15:34 +02:00
|
|
|
|
2022-05-26 15:04:39 +02:00
|
|
|
// Encrypt all blocks
|
|
|
|
std::vector<Block> ciphertext_blocks;
|
|
|
|
|
|
|
|
for (const Block& clearBlock : cleartext_blocks) {
|
|
|
|
ciphertext_blocks.emplace_back(cipher.Digest(clearBlock));
|
|
|
|
}
|
|
|
|
|
|
|
|
// Recode the ciphertext blocks to a hex-string
|
|
|
|
std::stringstream ss;
|
|
|
|
for (const Block& block : ciphertext_blocks) {
|
|
|
|
ss << block.ToHexString();
|
|
|
|
}
|
2022-05-16 22:15:34 +02:00
|
|
|
|
|
|
|
// Return it
|
2022-05-26 15:04:39 +02:00
|
|
|
return ss.str();
|
2022-05-16 22:15:34 +02:00
|
|
|
}
|
|
|
|
|
2022-05-22 13:43:23 +02:00
|
|
|
std::string GWrapper::DecryptString(
|
|
|
|
const std::string& ciphertext,
|
|
|
|
const Key& key)
|
|
|
|
{
|
2022-05-26 15:04:39 +02:00
|
|
|
// Make sure our ciphertext is a multiple of block size
|
|
|
|
if (ciphertext.length() % Block::BLOCK_SIZE*2 != 0) { // Two chars per byte
|
|
|
|
throw std::runtime_error("Leonetienne::GCrypt::GWrapper::DecryptString() received ciphertext of length not a multiple of block size.");
|
|
|
|
}
|
|
|
|
|
|
|
|
// Recode the hex-string to blocks
|
|
|
|
std::vector<Block> ciphertext_blocks;
|
|
|
|
ciphertext_blocks.reserve(ciphertext.length() / (Block::BLOCK_SIZE*2));
|
|
|
|
for (std::size_t i = 0; i < ciphertext.length(); i += Block::BLOCK_SIZE*2) {
|
|
|
|
Block block;
|
|
|
|
block.FromHexString(ciphertext.substr(i, Block::BLOCK_SIZE*2));
|
|
|
|
|
|
|
|
ciphertext_blocks.emplace_back(block);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Create cipher instance
|
|
|
|
GCipher cipher(key, GCipher::DIRECTION::DECIPHER);
|
2022-05-16 22:15:34 +02:00
|
|
|
|
2022-05-26 15:04:39 +02:00
|
|
|
// Decrypt all blocks
|
|
|
|
std::vector<Block> cleartext_blocks;
|
|
|
|
for (const Block& cipherBlock : ciphertext_blocks) {
|
|
|
|
cleartext_blocks.emplace_back(cipher.Digest(cipherBlock));
|
|
|
|
}
|
2022-05-16 22:15:34 +02:00
|
|
|
|
2022-05-26 15:04:39 +02:00
|
|
|
// Recode the cleartext blocks to bytes
|
|
|
|
std::stringstream ss;
|
|
|
|
for (const Block& block : cleartext_blocks) {
|
|
|
|
ss << block.ToTextString();
|
|
|
|
}
|
2022-05-16 22:15:34 +02:00
|
|
|
|
|
|
|
// Return it
|
2022-05-26 15:04:39 +02:00
|
|
|
return ss.str();
|
2022-05-16 22:15:34 +02:00
|
|
|
}
|
|
|
|
|
2022-05-22 13:43:23 +02:00
|
|
|
bool GWrapper::EncryptFile(
|
|
|
|
const std::string& filename_in,
|
|
|
|
const std::string& filename_out,
|
|
|
|
const Key& key,
|
|
|
|
bool printProgressReport)
|
|
|
|
{
|
2022-05-16 22:15:34 +02:00
|
|
|
try {
|
2022-05-26 04:22:42 +02:00
|
|
|
// Read the file to blocks
|
|
|
|
const std::vector<Block> cleartext_blocks = ReadFileToBlocks(filename_in);
|
2022-05-16 22:15:34 +02:00
|
|
|
|
2022-05-26 04:22:42 +02:00
|
|
|
// Encrypt our cleartext blocks
|
|
|
|
std::vector<Block> ciphertext_blocks;
|
|
|
|
ciphertext_blocks.reserve(cleartext_blocks.size());
|
2022-05-16 22:15:34 +02:00
|
|
|
|
2022-05-26 04:22:42 +02:00
|
|
|
// Create cipher instance
|
|
|
|
GCipher cipher(key, GCipher::DIRECTION::ENCIPHER);
|
|
|
|
|
|
|
|
// Encrypt all blocks
|
|
|
|
for (const Block& clearBlock : cleartext_blocks) {
|
|
|
|
ciphertext_blocks.emplace_back(cipher.Digest(clearBlock));
|
|
|
|
}
|
|
|
|
|
|
|
|
// Write our ciphertext blocks to file
|
|
|
|
WriteBlocksToFile(filename_out, ciphertext_blocks);
|
2022-05-16 22:15:34 +02:00
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
catch (std::runtime_error&) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-05-22 13:43:23 +02:00
|
|
|
bool GWrapper::DecryptFile(
|
|
|
|
const std::string& filename_in,
|
|
|
|
const std::string& filename_out,
|
|
|
|
const Key& key,
|
|
|
|
bool printProgressReport)
|
|
|
|
{
|
2022-05-16 22:15:34 +02:00
|
|
|
try {
|
2022-05-26 04:22:42 +02:00
|
|
|
// Read the file to blocks
|
|
|
|
const std::vector<Block> ciphertext_blocks = ReadFileToBlocks(filename_in);
|
|
|
|
|
|
|
|
// Decrypt our cleartext blocks
|
|
|
|
std::vector<Block> cleartext_blocks;
|
|
|
|
cleartext_blocks.reserve(ciphertext_blocks.size());
|
|
|
|
|
|
|
|
// Create cipher instance
|
|
|
|
GCipher cipher(key, GCipher::DIRECTION::DECIPHER);
|
2022-05-16 22:15:34 +02:00
|
|
|
|
2022-05-26 04:22:42 +02:00
|
|
|
// Decrypt all blocks
|
|
|
|
for (const Block& cipherBlock : ciphertext_blocks) {
|
|
|
|
cleartext_blocks.emplace_back(cipher.Digest(cipherBlock));
|
|
|
|
}
|
2022-05-16 22:15:34 +02:00
|
|
|
|
2022-05-26 04:22:42 +02:00
|
|
|
// Write our cleartext blocks to file
|
|
|
|
WriteBlocksToFile(filename_out, cleartext_blocks);
|
2022-05-16 22:15:34 +02:00
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
catch (std::runtime_error&) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-05-22 13:07:40 +02:00
|
|
|
Flexblock GWrapper::CipherFlexblock(
|
2022-05-22 13:04:20 +02:00
|
|
|
const Flexblock& data,
|
2022-05-22 13:43:23 +02:00
|
|
|
const Key& key,
|
2022-05-22 13:04:20 +02:00
|
|
|
const GCipher::DIRECTION direction)
|
|
|
|
{
|
2022-05-21 20:41:09 +02:00
|
|
|
// Split input into blocks
|
|
|
|
std::vector<Block> blocks;
|
|
|
|
|
2022-05-26 00:55:24 +02:00
|
|
|
for (std::size_t i = 0; i < data.size(); i += Block::BLOCK_SIZE_BITS) {
|
2022-05-21 20:41:09 +02:00
|
|
|
blocks.push_back(Block(
|
2022-05-26 00:55:24 +02:00
|
|
|
PadStringToLength(data.substr(i, Block::BLOCK_SIZE_BITS), Block::BLOCK_SIZE_BITS, '0', false))
|
2022-05-21 20:41:09 +02:00
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Create cipher instance
|
2022-05-22 12:51:58 +02:00
|
|
|
GCipher cipher(key, direction);
|
2022-05-21 20:41:09 +02:00
|
|
|
|
|
|
|
for (Block& block : blocks) {
|
|
|
|
block = cipher.Digest(block);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Concatenate ciphertext blocks back into a flexblock
|
|
|
|
std::stringstream ss;
|
|
|
|
for (Block& b : blocks) {
|
|
|
|
ss << b;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Return it
|
|
|
|
return ss.str();
|
|
|
|
}
|
2022-05-16 22:15:34 +02:00
|
|
|
}
|
|
|
|
|