diff --git a/ExampleApp/main.cpp b/ExampleApp/main.cpp index f6c41bf..70273fd 100644 --- a/ExampleApp/main.cpp +++ b/ExampleApp/main.cpp @@ -1,6 +1,7 @@ #pragma once #include #include +#include using namespace GhettoCipher; diff --git a/GhettoCrypt/Block.h b/GhettoCrypt/Block.h index 100f338..8b39cd1 100644 --- a/GhettoCrypt/Block.h +++ b/GhettoCrypt/Block.h @@ -1,8 +1,8 @@ #pragma once -#include +#include "SecureBitset.h" #include "Config.h" namespace GhettoCipher { - typedef std::bitset Block; + typedef SecureBitset Block; } diff --git a/GhettoCrypt/Feistel.cpp b/GhettoCrypt/Feistel.cpp index b9138a2..5bacd1e 100644 --- a/GhettoCrypt/Feistel.cpp +++ b/GhettoCrypt/Feistel.cpp @@ -125,7 +125,7 @@ GhettoCipher::Halfblock GhettoCipher::Feistel::CompressionFunction(const Block& std::stringstream ss; const std::string bits = block.to_string(); - // We have to double the bits! + // We have to half the bits! for (std::size_t i = 0; i < bits.size(); i += 4) { const std::string sub = bits.substr(i, 4); @@ -191,13 +191,6 @@ void GhettoCipher::Feistel::GenerateRoundKeys(const Block& seedKey) return; } -// These pragmas only work for MSVC and g++, as far as i know. Beware!!! -#if defined _WIN32 || defined _WIN64 -#pragma optimize("", off ) -#elif defined __GNUG__ -#pragma GCC push_options -#pragma GCC optimize ("O0") -#endif void GhettoCipher::Feistel::ZeroKeyMemory() { for (Block& key : roundKeys) @@ -205,8 +198,3 @@ void GhettoCipher::Feistel::ZeroKeyMemory() return; } -#if defined _WIN32 || defined _WIN64 -#pragma optimize("", on ) -#elif defined __GNUG__ -#pragma GCC pop_options -#endif diff --git a/GhettoCrypt/GhettoCrypt.vcxproj b/GhettoCrypt/GhettoCrypt.vcxproj index b9ae2ed..6985c42 100644 --- a/GhettoCrypt/GhettoCrypt.vcxproj +++ b/GhettoCrypt/GhettoCrypt.vcxproj @@ -141,8 +141,8 @@ - + @@ -153,6 +153,7 @@ + diff --git a/GhettoCrypt/GhettoCrypt.vcxproj.filters b/GhettoCrypt/GhettoCrypt.vcxproj.filters index 55434c2..f47e6c3 100644 --- a/GhettoCrypt/GhettoCrypt.vcxproj.filters +++ b/GhettoCrypt/GhettoCrypt.vcxproj.filters @@ -56,5 +56,8 @@ Headerdateien + + Headerdateien + \ No newline at end of file diff --git a/GhettoCrypt/Halfblock.h b/GhettoCrypt/Halfblock.h index ed13692..e619035 100644 --- a/GhettoCrypt/Halfblock.h +++ b/GhettoCrypt/Halfblock.h @@ -1,10 +1,10 @@ #pragma once -#include +#include "SecureBitset.h" #include #include "Config.h" namespace GhettoCipher { constexpr std::size_t HALFBLOCK_SIZE = (BLOCK_SIZE / 2); - typedef std::bitset Halfblock; + typedef SecureBitset Halfblock; } diff --git a/GhettoCrypt/SecureBitset.h b/GhettoCrypt/SecureBitset.h new file mode 100644 index 0000000..fa0f2d1 --- /dev/null +++ b/GhettoCrypt/SecureBitset.h @@ -0,0 +1,324 @@ +#pragma once +#include +#include +#include + +namespace GhettoCipher +{ +/** Wrapper for std::bitset that zeroes memory upon deletion. +* This does not include ALL methods, but the ones needed. +* +* Just creating a specialization of std::bitset does not work. +*/ +template +class SecureBitset +{ +public: + explicit SecureBitset(); + explicit SecureBitset(const std::string& str); + explicit SecureBitset(const long long int i); + + ~SecureBitset(); + + bool operator==(const SecureBitset& other) const; + bool operator!=(const SecureBitset& other) const; + bool operator[](const std::size_t) const; + bool test(const std::size_t index) const; + bool all() const; + bool any() const; + bool none() const; + std::size_t count() const; + std::size_t size() const; + SecureBitset& operator&=(const SecureBitset& other); + SecureBitset& operator|=(const SecureBitset& other); + SecureBitset& operator^=(const SecureBitset& other); + SecureBitset operator&(const SecureBitset& other); + SecureBitset operator|(const SecureBitset& other); + SecureBitset operator^(const SecureBitset& other); + SecureBitset operator~() const; + SecureBitset& operator<<=(const std::size_t offset); + SecureBitset& operator>>=(const std::size_t offset); + SecureBitset operator<<(const std::size_t offset) const; + SecureBitset operator>>(const std::size_t offset) const; + SecureBitset& set(); + SecureBitset& set(const std::size_t index, bool value = true); + SecureBitset& reset(); + SecureBitset& reset(const std::size_t index); + SecureBitset& flip(); + SecureBitset& flip(const std::size_t index); + std::string to_string() const; + unsigned long to_ulong() const; + unsigned long long to_ullong() const; + + std::bitset& Get(); + const std::bitset& Get() const; + +private: + std::bitset bitset; +}; + +template +inline SecureBitset::SecureBitset() + : + bitset() +{ + return; +} + +template +inline SecureBitset::SecureBitset(const std::string& str) + : + bitset(str) +{ + return; +} + +template +inline SecureBitset::SecureBitset(const long long int i) + : + bitset(i) +{ + return; +} + + +// Don't optimize the destructor out!!! +// These pragmas only work for MSVC and g++, as far as i know. Beware!!! +#if defined _WIN32 || defined _WIN64 +#pragma optimize("", off ) +#elif defined __GNUG__ +#pragma GCC push_options +#pragma GCC optimize ("O0") +#endif +template +inline SecureBitset::~SecureBitset() +{ + bitset.reset(); + return; +} +#if defined _WIN32 || defined _WIN64 +#pragma optimize("", on ) +#elif defined __GNUG__ +#pragma GCC pop_options +#endif + +template +inline bool SecureBitset::operator==(const SecureBitset& other) const +{ + return bitset == other.bitset; +} + +template +inline bool SecureBitset::operator!=(const SecureBitset& other) const +{ + return bitset != other.bitset; +} + +template +inline bool SecureBitset::operator[](const std::size_t index) const +{ + return bitset[index]; +} + +template +inline bool SecureBitset::test(const std::size_t index) const +{ + return bitset.test(index); +} + +template +inline bool SecureBitset::all() const +{ + return bitset.all(); +} + +template +inline bool SecureBitset::any() const +{ + return bitset.any(); +} + +template +inline bool SecureBitset::none() const +{ + return bitset.none(); +} + +template +inline std::size_t SecureBitset::count() const +{ + return bitset.count(); +} + +template +inline std::size_t SecureBitset::size() const +{ + return bitset.count(); +} + +template +inline SecureBitset& SecureBitset::operator&=(const SecureBitset& other) +{ + bitset &= other.bitset; + return *this; +} + +template +inline SecureBitset& SecureBitset::operator|=(const SecureBitset& other) +{ + bitset |= other.bitset; + return *this; +} + +template +inline SecureBitset& SecureBitset::operator^=(const SecureBitset& other) +{ + bitset ^= other.bitset; + return *this; +} + +template +inline SecureBitset SecureBitset::operator&(const SecureBitset& other) +{ + SecureBitset bs; + bs.bitset = bitset & other.bitset; + return bs; +} + +template +inline SecureBitset SecureBitset::operator|(const SecureBitset& other) +{ + SecureBitset bs; + bs.bitset = bitset | other.bitset; + return bs; +} + +template +inline SecureBitset SecureBitset::operator^(const SecureBitset& other) +{ + SecureBitset bs; + bs.bitset = bitset ^ other.bitset; + return bs; +} + +template +inline SecureBitset SecureBitset::operator~() const +{ + SecureBitset bs; + bs.bitset = ~bitset; + return bs; +} + +template +inline SecureBitset& SecureBitset::operator<<=(const std::size_t offset) +{ + bitset <<= offset; + return *this; +} + +template +inline SecureBitset& SecureBitset::operator>>=(const std::size_t offset) +{ + bitset >>= offset; + return *this; +} + +template +inline SecureBitset SecureBitset::operator<<(const std::size_t offset) const +{ + SecureBitset bs; + bs.bitset = bitset << offset; + return bs; +} + +template +inline SecureBitset SecureBitset::operator>>(const std::size_t offset) const +{ + SecureBitset bs; + bs.bitset = bitset >> offset; + return bs; +} + +template +inline SecureBitset& SecureBitset::set() +{ + bitset.set(); + return *this; +} + +template +inline SecureBitset& SecureBitset::set(const std::size_t index, bool value) +{ + bitset.set(index, value); + return *this; +} + +template +inline SecureBitset& SecureBitset::reset() +{ + bitset.reset(); + return *this; +} + +template +inline SecureBitset& SecureBitset::reset(const std::size_t index) +{ + bitset.reset(index); + return *this; +} + +template +inline SecureBitset& SecureBitset::flip() +{ + bitset.flip(); + return *this; +} + +template +inline SecureBitset& SecureBitset::flip(const std::size_t index) +{ + bitset.flip(index); + return *this; +} + +template +inline std::string SecureBitset::to_string() const +{ + return bitset.to_string(); +} + +template +inline unsigned long SecureBitset::to_ulong() const +{ + return bitset.to_ulong(); +} +template +inline unsigned long long SecureBitset::to_ullong() const +{ + return bitset.to_ullong(); +} + +template +inline std::bitset& SecureBitset::Get() +{ + return bitset; +} + +template +inline const std::bitset& SecureBitset::Get() const +{ + return bitset; +} + +template +inline std::ostream& operator<<(std::ostream& ofs, const SecureBitset& bs) +{ + return ofs << bs.Get(); +} + +template +inline std::istream& operator>>(std::istream& ifs, const SecureBitset& bs) +{ + return ifs >> bs.Get(); +} +} diff --git a/GhettoCrypt/Util.h b/GhettoCrypt/Util.h index 8a528ea..39cc47a 100644 --- a/GhettoCrypt/Util.h +++ b/GhettoCrypt/Util.h @@ -2,6 +2,7 @@ #include #include #include +#include "SecureBitset.h" #include "Block.h" #include "Flexblock.h" @@ -15,7 +16,7 @@ namespace GhettoCipher //! Will perform a wrapping left-bitshift on a bitset template - inline std::bitset Shiftl(const std::bitset& bits, const std::size_t amount) + inline SecureBitset Shiftl(const SecureBitset& bits, const std::size_t amount) { std::stringstream ss; const std::string bitss = bits.to_string(); @@ -23,12 +24,12 @@ namespace GhettoCipher for (std::size_t i = 0; i < bitss.size(); i++) ss << bitss[Mod((int)(i + amount), (int)bitss.size())]; - return std::bitset(ss.str()); + return SecureBitset(ss.str()); } //! Will perform a wrapping right-bitshift on a bitset template - inline std::bitset Shiftr(const std::bitset& bits, const std::size_t amount) + inline SecureBitset Shiftr(const SecureBitset& bits, const std::size_t amount) { std::stringstream ss; const std::string bitss = bits.to_string(); @@ -36,7 +37,7 @@ namespace GhettoCipher for (std::size_t i = 0; i < bitss.size(); i++) ss << bitss[Mod((i - amount), bitss.size())]; - return std::bitset(ss.str()); + return SecureBitset(ss.str()); } //! Will pad a string to a set length with a certain character diff --git a/GhettoCrypt/Version.h b/GhettoCrypt/Version.h index e606a79..49aee36 100644 --- a/GhettoCrypt/Version.h +++ b/GhettoCrypt/Version.h @@ -1,2 +1,2 @@ #pragma once -#define GHETTOCRYPT_VERSION 0.1 +#define GHETTOCRYPT_VERSION 0.12 diff --git a/INCLUDE/GhettoCrypt.cpp b/INCLUDE/GhettoCrypt.cpp index 5b614b3..75c4940 100644 --- a/INCLUDE/GhettoCrypt.cpp +++ b/INCLUDE/GhettoCrypt.cpp @@ -289,7 +289,7 @@ GhettoCipher::Halfblock GhettoCipher::Feistel::CompressionFunction(const Block& std::stringstream ss; const std::string bits = block.to_string(); - // We have to double the bits! + // We have to half the bits! for (std::size_t i = 0; i < bits.size(); i += 4) { const std::string sub = bits.substr(i, 4); @@ -355,13 +355,6 @@ void GhettoCipher::Feistel::GenerateRoundKeys(const Block& seedKey) return; } -// These pragmas only work for MSVC and g++, as far as i know. Beware!!! -#if defined _WIN32 || defined _WIN64 -#pragma optimize("", off ) -#elif defined __GNUG__ -#pragma GCC push_options -#pragma GCC optimize ("O0") -#endif void GhettoCipher::Feistel::ZeroKeyMemory() { for (Block& key : roundKeys) @@ -369,11 +362,6 @@ void GhettoCipher::Feistel::ZeroKeyMemory() return; } -#if defined _WIN32 || defined _WIN64 -#pragma optimize("", on ) -#elif defined __GNUG__ -#pragma GCC pop_options -#endif /*** ./../GhettoCrypt/GhettoCryptWrapper.cpp ***/ diff --git a/INCLUDE/GhettoCrypt.h b/INCLUDE/GhettoCrypt.h index 10f759c..4f4ff0f 100644 --- a/INCLUDE/GhettoCrypt.h +++ b/INCLUDE/GhettoCrypt.h @@ -28,11 +28,6 @@ #pragma once -/*** ./../GhettoCrypt/Version.h ***/ - -#pragma once -#define GHETTOCRYPT_VERSION 0.1 - /*** ./../GhettoCrypt/GhettoCryptWrapper.h ***/ #pragma once @@ -91,14 +86,340 @@ namespace GhettoCipher constexpr std::size_t N_ROUNDS = 64; } -/*** ./../GhettoCrypt/Block.h ***/ +/*** ./../GhettoCrypt/SecureBitset.h ***/ #pragma once #include +#include +#include namespace GhettoCipher { - typedef std::bitset Block; +/** Wrapper for std::bitset that zeroes memory upon deletion. +* This does not include ALL methods, but the ones needed. +* +* Just creating a specialization of std::bitset does not work. +*/ +template +class SecureBitset +{ +public: + explicit SecureBitset(); + explicit SecureBitset(const std::string& str); + explicit SecureBitset(const long long int i); + + ~SecureBitset(); + + bool operator==(const SecureBitset& other) const; + bool operator!=(const SecureBitset& other) const; + bool operator[](const std::size_t) const; + bool test(const std::size_t index) const; + bool all() const; + bool any() const; + bool none() const; + std::size_t count() const; + std::size_t size() const; + SecureBitset& operator&=(const SecureBitset& other); + SecureBitset& operator|=(const SecureBitset& other); + SecureBitset& operator^=(const SecureBitset& other); + SecureBitset operator&(const SecureBitset& other); + SecureBitset operator|(const SecureBitset& other); + SecureBitset operator^(const SecureBitset& other); + SecureBitset operator~() const; + SecureBitset& operator<<=(const std::size_t offset); + SecureBitset& operator>>=(const std::size_t offset); + SecureBitset operator<<(const std::size_t offset) const; + SecureBitset operator>>(const std::size_t offset) const; + SecureBitset& set(); + SecureBitset& set(const std::size_t index, bool value = true); + SecureBitset& reset(); + SecureBitset& reset(const std::size_t index); + SecureBitset& flip(); + SecureBitset& flip(const std::size_t index); + std::string to_string() const; + unsigned long to_ulong() const; + unsigned long long to_ullong() const; + + std::bitset& Get(); + const std::bitset& Get() const; + +private: + std::bitset bitset; +}; + +template +inline SecureBitset::SecureBitset() + : + bitset() +{ + return; +} + +template +inline SecureBitset::SecureBitset(const std::string& str) + : + bitset(str) +{ + return; +} + +template +inline SecureBitset::SecureBitset(const long long int i) + : + bitset(i) +{ + return; +} + + +// Don't optimize the destructor out!!! +// These pragmas only work for MSVC and g++, as far as i know. Beware!!! +#if defined _WIN32 || defined _WIN64 +#pragma optimize("", off ) +#elif defined __GNUG__ +#pragma GCC push_options +#pragma GCC optimize ("O0") +#endif +template +inline SecureBitset::~SecureBitset() +{ + bitset.reset(); + return; +} +#if defined _WIN32 || defined _WIN64 +#pragma optimize("", on ) +#elif defined __GNUG__ +#pragma GCC pop_options +#endif + +template +inline bool SecureBitset::operator==(const SecureBitset& other) const +{ + return bitset == other.bitset; +} + +template +inline bool SecureBitset::operator!=(const SecureBitset& other) const +{ + return bitset != other.bitset; +} + +template +inline bool SecureBitset::operator[](const std::size_t index) const +{ + return bitset[index]; +} + +template +inline bool SecureBitset::test(const std::size_t index) const +{ + return bitset.test(index); +} + +template +inline bool SecureBitset::all() const +{ + return bitset.all(); +} + +template +inline bool SecureBitset::any() const +{ + return bitset.any(); +} + +template +inline bool SecureBitset::none() const +{ + return bitset.none(); +} + +template +inline std::size_t SecureBitset::count() const +{ + return bitset.count(); +} + +template +inline std::size_t SecureBitset::size() const +{ + return bitset.count(); +} + +template +inline SecureBitset& SecureBitset::operator&=(const SecureBitset& other) +{ + bitset &= other.bitset; + return *this; +} + +template +inline SecureBitset& SecureBitset::operator|=(const SecureBitset& other) +{ + bitset |= other.bitset; + return *this; +} + +template +inline SecureBitset& SecureBitset::operator^=(const SecureBitset& other) +{ + bitset ^= other.bitset; + return *this; +} + +template +inline SecureBitset SecureBitset::operator&(const SecureBitset& other) +{ + SecureBitset bs; + bs.bitset = bitset & other.bitset; + return bs; +} + +template +inline SecureBitset SecureBitset::operator|(const SecureBitset& other) +{ + SecureBitset bs; + bs.bitset = bitset | other.bitset; + return bs; +} + +template +inline SecureBitset SecureBitset::operator^(const SecureBitset& other) +{ + SecureBitset bs; + bs.bitset = bitset ^ other.bitset; + return bs; +} + +template +inline SecureBitset SecureBitset::operator~() const +{ + SecureBitset bs; + bs.bitset = ~bitset; + return bs; +} + +template +inline SecureBitset& SecureBitset::operator<<=(const std::size_t offset) +{ + bitset <<= offset; + return *this; +} + +template +inline SecureBitset& SecureBitset::operator>>=(const std::size_t offset) +{ + bitset >>= offset; + return *this; +} + +template +inline SecureBitset SecureBitset::operator<<(const std::size_t offset) const +{ + SecureBitset bs; + bs.bitset = bitset << offset; + return bs; +} + +template +inline SecureBitset SecureBitset::operator>>(const std::size_t offset) const +{ + SecureBitset bs; + bs.bitset = bitset >> offset; + return bs; +} + +template +inline SecureBitset& SecureBitset::set() +{ + bitset.set(); + return *this; +} + +template +inline SecureBitset& SecureBitset::set(const std::size_t index, bool value) +{ + bitset.set(index, value); + return *this; +} + +template +inline SecureBitset& SecureBitset::reset() +{ + bitset.reset(); + return *this; +} + +template +inline SecureBitset& SecureBitset::reset(const std::size_t index) +{ + bitset.reset(index); + return *this; +} + +template +inline SecureBitset& SecureBitset::flip() +{ + bitset.flip(); + return *this; +} + +template +inline SecureBitset& SecureBitset::flip(const std::size_t index) +{ + bitset.flip(index); + return *this; +} + +template +inline std::string SecureBitset::to_string() const +{ + return bitset.to_string(); +} + +template +inline unsigned long SecureBitset::to_ulong() const +{ + return bitset.to_ulong(); +} +template +inline unsigned long long SecureBitset::to_ullong() const +{ + return bitset.to_ullong(); +} + +template +inline std::bitset& SecureBitset::Get() +{ + return bitset; +} + +template +inline const std::bitset& SecureBitset::Get() const +{ + return bitset; +} + +template +inline std::ostream& operator<<(std::ostream& ofs, const SecureBitset& bs) +{ + return ofs << bs.Get(); +} + +template +inline std::istream& operator>>(std::istream& ifs, const SecureBitset& bs) +{ + return ifs >> bs.Get(); +} +} + +/*** ./../GhettoCrypt/Block.h ***/ + +#pragma once + +namespace GhettoCipher +{ + typedef SecureBitset Block; } /*** ./../GhettoCrypt/Util.h ***/ @@ -118,7 +439,7 @@ namespace GhettoCipher //! Will perform a wrapping left-bitshift on a bitset template - inline std::bitset Shiftl(const std::bitset& bits, const std::size_t amount) + inline SecureBitset Shiftl(const SecureBitset& bits, const std::size_t amount) { std::stringstream ss; const std::string bitss = bits.to_string(); @@ -126,12 +447,12 @@ namespace GhettoCipher for (std::size_t i = 0; i < bitss.size(); i++) ss << bitss[Mod((int)(i + amount), (int)bitss.size())]; - return std::bitset(ss.str()); + return SecureBitset(ss.str()); } //! Will perform a wrapping right-bitshift on a bitset template - inline std::bitset Shiftr(const std::bitset& bits, const std::size_t amount) + inline SecureBitset Shiftr(const SecureBitset& bits, const std::size_t amount) { std::stringstream ss; const std::string bitss = bits.to_string(); @@ -139,7 +460,7 @@ namespace GhettoCipher for (std::size_t i = 0; i < bitss.size(); i++) ss << bitss[Mod((i - amount), bitss.size())]; - return std::bitset(ss.str()); + return SecureBitset(ss.str()); } //! Will pad a string to a set length with a certain character @@ -362,6 +683,11 @@ namespace GhettoCipher } } +/*** ./../GhettoCrypt/Version.h ***/ + +#pragma once +#define GHETTOCRYPT_VERSION 0.12 + /*** ./../GhettoCrypt/Keyset.h ***/ #pragma once @@ -375,13 +701,12 @@ namespace GhettoCipher /*** ./../GhettoCrypt/Halfblock.h ***/ #pragma once -#include #include namespace GhettoCipher { constexpr std::size_t HALFBLOCK_SIZE = (BLOCK_SIZE / 2); - typedef std::bitset Halfblock; + typedef SecureBitset Halfblock; } /*** ./../GhettoCrypt/Feistel.h ***/