Defcon 23 file version. Updated LICENSE.md to reflect MIT. Update README.md with additional prerequisite info, etc.

This commit is contained in:
atarivampire 2015-08-12 04:50:13 -07:00
parent 19558b915b
commit eeeea2037f
19 changed files with 1957 additions and 11 deletions

View File

@ -1 +1,21 @@
Copyright 2014 - 2015 Eijah. All Rights Reserved.
The MIT License (MIT)
Copyright (c) 2015 Demonsaw LLC
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@ -1,16 +1,57 @@
# demonsaw
Welcome to the Future of File Sharing...
_ _
| | | |
__| | ___ _ __ ___ ___ _ __ ___ _ __ _ _ _ __ | |_
/ _` |/ _ \ '_ ` _ \ / _ \| '_ \ / __| '__| | | | '_ \| __|
| (_| | __/ | | | | | (_) | | | | (__| | | |_| | |_) | |_
\__,_|\___|_| |_| |_|\___/|_| |_|\___|_| \__, | .__/ \__|
__/ | |
|___/|_|
Demonsaw is a new type of file sharing application that allows you to share your files securely. It's the next leap in the evolution of file sharing. Demonsaw is designed to protect your anonymity and hide what you're sharing. Your IP address is never revealed to the world. Share whatever you want, with whomever you want, without fear or consequence.
demoncrypt 2.0
Copyright 2014-2015 Demonsaw LLC All Rights Reserved
Believe in the Right to Share
https://www.demonsaw.com
Every file sharing application over the past 45+ years has had 3 common elements: the ability to upload/download files, the ability to control program flow, and the ability to transfer data. Demonsaw is different from other file sharing applications because it breaks up these different types of abilities into separate network components that act autonomously. By doing this demonsaw creates an extra layer of abstraction that completely secures your file sharing.
[overview]
-------------------------------------------------------------------------------
Believe in the Right to Share.
Demonsaw is a type of decentralized Cloud network. It takes the best features from centralized applications, like the Dropbox, and decentralized applications, like BitTorrent, and merges them into a seamless new type of hybrid file sharing application. By levering your home Internet access, you become your own private file sharing network.
Demoncrypt is a lightweight C++ wrapper around some of the more common crypto routines in Crypto++. Demoncrypt is the open-source crypto layer used in demonsaw. It's free and open-source. Use it however you want.
[prerequisites]
-------------------------------------------------------------------------------
* C++ 11 compliant compiler (gcc 4.7, MSVC 2013, or greater)
* Cryptop++ 5.6.2 (www.cryptopp.com)
[contents]
-------------------------------------------------------------------------------
/security/
aes.h
base.h
block_cipher.cpp
block_cipher.h
checksum.h
diffie_hellman.cpp
diffie_hellman.h
filter.h
hash.h
hex.h
hmac.h
md.h
pbkdf.h
security.cpp
security.h
sha.h
/system/
type.h
[setup]
-------------------------------------------------------------------------------
Just copy the security and system folders into your project workspace. Update your project/solution/makefiles accordingly. Include the appropriate files in your *.h/*.cpp source. Build. Enjoy!
[questions]
https://twitter.com/demon_saw
eijah@demonsaw.com
Secure, Anonymous, Free, Everywhere. Believe in the Right to Share.
-Eijah
Want to help? Let me know...
https://twitter.com/demon_saw
eijah@demonsaw.com

30
security/aes.h Normal file
View File

@ -0,0 +1,30 @@
//
// The MIT License(MIT)
//
// Copyright(c) 2014 Eijah
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files(the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions :
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
//
#ifndef _EJA_AES_
#define _EJA_AES_
#include "security/block_cipher.h"
#endif

30
security/base.h Normal file
View File

@ -0,0 +1,30 @@
//
// The MIT License(MIT)
//
// Copyright(c) 2014 Eijah
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files(the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions :
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
//
#ifndef _EJA_BASE_
#define _EJA_BASE_
#include "security/filter.h"
#endif

12
security/block_cipher.cpp Normal file
View File

@ -0,0 +1,12 @@
#include "block_cipher.h"
namespace eja
{
void block_cipher::set_key(const byte* key, const size_t key_size)
{
assert(key && (key_size == 16) || (key_size == 24) || (key_size == 32));
m_key.Assign(key, key_size);
}
}

257
security/block_cipher.h Normal file
View File

@ -0,0 +1,257 @@
//
// The MIT License(MIT)
//
// Copyright(c) 2014 Eijah
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files(the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions :
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
//
#ifndef _EJA_CIPHER_
#define _EJA_CIPHER_
#include <memory>
#include <string>
#include <cryptopp/filters.h>
#include <cryptopp/hex.h>
#include <cryptopp/modes.h>
#include <cryptopp/osrng.h>
#include <cryptopp/secblock.h>
// AES
#include <cryptopp/aes.h>
#include <cryptopp/cast.h>
#include <cryptopp/mars.h>
#include <cryptopp/rc6.h>
#include <cryptopp/rijndael.h>
#include <cryptopp/serpent.h>
#include <cryptopp/twofish.h>
// Other
#include <cryptopp/blowfish.h>
#include <cryptopp/camellia.h>
#include <cryptopp/des.h>
#include <cryptopp/idea.h>
#include <cryptopp/rc5.h>
#include <cryptopp/seed.h>
#include <cryptopp/shacal2.h>
#include <cryptopp/skipjack.h>
#include <cryptopp/tea.h>
// Legacy
#include <cryptopp/3way.h>
#include <cryptopp/gost.h>
#include <cryptopp/rc2.h>
#include <cryptopp/safer.h>
#include <cryptopp/shark.h>
#include <cryptopp/cast.h>
#include <cryptopp/square.h>
#include "security.h"
#include "system/type.h"
namespace eja
{
// Using
template <typename T, typename U = CryptoPP::CBC_Mode<T>>
class block_cipher_impl;
// AES
using mars = block_cipher_impl<CryptoPP::MARS>;
using rc6 = block_cipher_impl<CryptoPP::RC6>;
using rijndael = block_cipher_impl<CryptoPP::Rijndael>;
using serpent = block_cipher_impl<CryptoPP::Serpent>;
using twofish = block_cipher_impl<CryptoPP::Twofish>;
using aes = rijndael;
// Other
using blowfish = block_cipher_impl<CryptoPP::Blowfish>;
using camellia = block_cipher_impl<CryptoPP::Camellia>;
using cast256 = block_cipher_impl<CryptoPP::CAST256>;
using des_ede2 = block_cipher_impl<CryptoPP::DES_EDE2>;
using des_ede3 = block_cipher_impl<CryptoPP::DES_EDE3>;
using idea = block_cipher_impl<CryptoPP::IDEA>;
using rc5 = block_cipher_impl<CryptoPP::RC5>;
using seed = block_cipher_impl<CryptoPP::SEED>;
using shacal2 = block_cipher_impl<CryptoPP::SHACAL2>;
using skipjack = block_cipher_impl<CryptoPP::SKIPJACK>;
using tea = block_cipher_impl<CryptoPP::TEA>;
using xtea = block_cipher_impl<CryptoPP::XTEA>;
// Legacy
using cast128 = block_cipher_impl<CryptoPP::CAST128>;
using des = block_cipher_impl<CryptoPP::DES>;
using des_xex3 = block_cipher_impl<CryptoPP::DES_XEX3>;
using gost = block_cipher_impl<CryptoPP::GOST>;
using rc2 = block_cipher_impl<CryptoPP::RC2>;
using safer_k = block_cipher_impl<CryptoPP::SAFER_K>;
using safer_sk = block_cipher_impl<CryptoPP::SAFER_SK>;
using shark = block_cipher_impl<CryptoPP::SHARK>;
using square = block_cipher_impl<CryptoPP::Square>;
using threeway = block_cipher_impl<CryptoPP::ThreeWay>;
// Type
enum class cipher_type { aes, mars, rc6, serpent, twofish };
// Cipher
class block_cipher
{
protected:
CryptoPP::SecByteBlock m_key;
public:
using ptr = std::shared_ptr<block_cipher>;
public:
block_cipher() { }
block_cipher(const byte* key, const size_t key_size) { set_key(key, key_size); }
block_cipher(const CryptoPP::SecByteBlock& key) { set_key(key); }
block_cipher(const std::string& key, const size_t key_size) { set_key(key, key_size); }
block_cipher(const std::string& key) { set_key(key); }
block_cipher(const char* key, const size_t key_size) { set_key(key, key_size); }
block_cipher(const char* key) { set_key(key); }
virtual ~block_cipher() { }
// Interface
void clear() { m_key.resize(0); }
// Utility
bool empty() const { return !m_key.size(); }
// Random
virtual std::string random(const size_t output_size) const = 0;
// Encrypt
virtual std::string encrypt(const byte* input, const size_t input_size) const = 0;
std::string encrypt(const CryptoPP::SecByteBlock& input) const { return encrypt(input.data(), input.size()); }
std::string encrypt(const std::string& input) const { return encrypt(reinterpret_cast<const byte*>(input.c_str()), input.size()); }
std::string encrypt(const char* input) const { return encrypt(reinterpret_cast<const byte*>(input), strlen(input)); }
// Decrypt
virtual std::string decrypt(const byte* input, const size_t input_size) const = 0;
std::string decrypt(const CryptoPP::SecByteBlock& input) const { return decrypt(input.data(), input.size()); }
std::string decrypt(const std::string& input) const { return decrypt(reinterpret_cast<const byte*>(input.c_str()), input.size()); }
std::string decrypt(const char* input) const { return decrypt(reinterpret_cast<const byte*>(input), strlen(input)); }
// Mutator
void set_key(const byte* key, const size_t key_size);
void set_key(const CryptoPP::SecByteBlock& key) { set_key(key.data(), key.size()); }
void set_key(const std::string& key, const size_t key_size) { set_key(reinterpret_cast<const byte*>(key.c_str()), key_size); }
void set_key(const std::string& key) { set_key(reinterpret_cast<const byte*>(key.c_str()), key.size()); }
void set_key(const char* key, const size_t key_size) { set_key(reinterpret_cast<const byte*>(key), key_size); }
void set_key(const char* key) { set_key(reinterpret_cast<const byte*>(key), strlen(key)); }
// Accessor
std::string get_key() const{ return security::str(m_key); }
size_t size() { return m_key.size(); }
};
template <typename T, typename U>
class block_cipher_impl final : public block_cipher
{
private:
T m_routine;
CryptoPP::SecByteBlock m_iv;
public:
block_cipher_impl() : m_iv(T::BLOCKSIZE) { set_iv(); }
block_cipher_impl(const byte* key, const size_t key_size) : block_cipher(key, key_size) { set_iv(); }
block_cipher_impl(const CryptoPP::SecByteBlock& key) : block_cipher(key), m_iv(T::BLOCKSIZE) { set_iv(); }
block_cipher_impl(const std::string& key, const size_t key_size) : block_cipher(key, key_size), m_iv(T::BLOCKSIZE) { set_iv(); }
block_cipher_impl(const std::string& key) : block_cipher(key), m_iv(T::BLOCKSIZE) { set_iv(); }
block_cipher_impl(const char* key, const size_t key_size) : block_cipher(key, key_size), m_iv(T::BLOCKSIZE) { set_iv(); }
block_cipher_impl(const char* key) : block_cipher(key), m_iv(T::BLOCKSIZE) { set_iv(); }
virtual ~block_cipher_impl() override { }
// Operator
std::string operator()(const size_t output_size = T::DEFAULT_KEYLENGTH) const { return block_cipher_impl().random(output_size); }
// Random
virtual std::string random(const size_t output_size = T::DEFAULT_KEYLENGTH) const override { return security::random<T>(output_size); }
// Encrypt
using block_cipher::encrypt;
virtual std::string encrypt(const byte* input, const size_t input_size) const override;
// Decrypt
using block_cipher::decrypt;
virtual std::string decrypt(const byte* input, const size_t input_size) const override;
// Mutator
void set_iv() { memset(m_iv, 0, T::BLOCKSIZE); }
void set_iv(const byte* iv, const size_t iv_size);
void set_iv(const CryptoPP::SecByteBlock& iv) { set_iv(iv.data(), iv.size()); }
void set_iv(const std::string& iv) { set_iv(reinterpret_cast<const byte*>(iv.c_str()), iv.size()); }
void set_iv(const char* iv) { set_iv(reinterpret_cast<const byte*>(iv), strlen(iv)); }
// Accessor
std::string get_iv() const { return security::str(m_iv); }
// Static
static size_t get_min_size() { return T::MIN_KEYLENGTH; }
static size_t get_max_size() { return T::MAX_KEYLENGTH; }
static size_t get_default_size() { return T::DEFAULT_KEYLENGTH; }
static ptr create() { return std::make_shared<block_cipher_impl<T, U>>(); }
static ptr create(const byte* key, const size_t key_size) { return std::make_shared<block_cipher_impl<T, U>>(key, key_size); }
static ptr create(const CryptoPP::SecByteBlock& key) { return std::make_shared<block_cipher_impl<T, U>>(key); }
static ptr create(const std::string& key, const size_t key_size) { return std::make_shared<block_cipher_impl<T, U>>(key, key_size); }
static ptr create(const std::string& key) { return std::make_shared<block_cipher_impl<T, U>>(key); }
static ptr create(const char* key, const size_t key_size) { return std::make_shared<block_cipher_impl<T, U>>(key, key_size); }
static ptr create(const char* key) { return std::make_shared<block_cipher_impl<T, U>>(key); }
};
// Encrypt
template <typename T, typename U>
std::string block_cipher_impl<T, U>::encrypt(const byte* input, const size_t input_size) const
{
assert(input && input_size);
std::string output;
typename U::Encryption encryptor(m_key, m_key.size(), m_iv);
CryptoPP::StreamTransformationFilter filter(encryptor, new CryptoPP::StringSink(output));
filter.Put(input, input_size);
filter.MessageEnd();
return output;
}
// Decrypt
template <typename T, typename U>
std::string block_cipher_impl<T, U>::decrypt(const byte* input, const size_t input_size) const
{
assert(input && input_size);
std::string output;
typename U::Decryption decryptor(m_key, m_key.size(), m_iv);
CryptoPP::StreamTransformationFilter filter(decryptor, new CryptoPP::StringSink(output));
filter.Put(input, input_size);
filter.MessageEnd();
return output;
}
// Mutator
template <typename T, typename U>
void block_cipher_impl<T, U>::set_iv(const byte* iv, const size_t iv_size)
{
assert(iv && (iv_size >= T::BLOCKSIZE));
m_iv.Assign(iv, iv_size);
}
}
#endif

140
security/checksum.h Normal file
View File

@ -0,0 +1,140 @@
//
// The MIT License(MIT)
//
// Copyright(c) 2014 Eijah
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files(the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions :
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
//
#ifndef _EJA_CHECKSUM_
#define _EJA_CHECKSUM_
#include <memory>
#include <string>
#include <cryptopp/adler32.h>
#include <cryptopp/crc.h>
#include <cryptopp/osrng.h>
#include <cryptopp/secblock.h>
namespace eja
{
template <typename T>
class checksum_impl;
// Adler
using adler32 = checksum_impl<CryptoPP::Adler32>;
using adler = adler32;
// CRC
using crc32 = checksum_impl<CryptoPP::CRC32>;
using crc = crc32;
class checksum
{
public:
using ptr = std::shared_ptr<checksum>;
public:
checksum() { }
virtual ~checksum() { }
// Random
virtual CryptoPP::word random() = 0;
// Compute
virtual CryptoPP::word compute() = 0;
virtual CryptoPP::word compute(const byte* input, const size_t input_size) = 0;
CryptoPP::word compute(const CryptoPP::SecByteBlock& input) { return compute(input.data(), input.size()); }
CryptoPP::word compute(const std::string& input) { return compute(reinterpret_cast<const byte*>(input.c_str()), input.size()); }
CryptoPP::word compute(const char* input) { return compute(reinterpret_cast<const byte*>(input), strlen(input)); }
// Update
virtual void update(const byte* input, const size_t input_size) = 0;
void update(const CryptoPP::SecByteBlock& input) { update(input.data(), input.size()); }
void update(const std::string& input) { update(reinterpret_cast<const byte*>(input.c_str()), input.size()); }
void update(const char* input) { update(reinterpret_cast<const byte*>(input), strlen(input)); }
// Accessor
virtual size_t size() const = 0;
};
template <typename T>
class checksum_impl final : public checksum
{
private:
T m_routine;
public:
checksum_impl() { }
virtual ~checksum_impl() override { }
// Operator
CryptoPP::word operator()() const { return checksum_impl().random(); }
std::string operator()(const CryptoPP::SecByteBlock& input) const { return checksum_impl().compute(input); }
std::string operator()(const std::string& input) const { return checksum_impl().compute(input); }
std::string operator()(const char* input) const { return checksum_impl().compute(input); }
// Random
virtual CryptoPP::word random() override;
// Compute
using checksum::compute;
virtual CryptoPP::word compute() override;
virtual CryptoPP::word compute(const byte* input, const size_t input_size) override;
// Update
using checksum::update;
virtual void update(const byte* input, const size_t input_size) override { m_routine.Update(input, input_size); }
// Accessor
virtual size_t size() const override { return T::DIGESTSIZE; }
// Static
static ptr create() { return std::make_shared<checksum_impl<T>>(); }
};
// Random
template <typename T>
CryptoPP::word checksum_impl<T>::random()
{
CryptoPP::word output;
CryptoPP::AutoSeededX917RNG<CryptoPP::AES> rng;
rng.GenerateBlock(reinterpret_cast<byte*>(&output), T::DIGESTSIZE);
return output;
}
// Compute
template <typename T>
CryptoPP::word checksum_impl<T>::compute()
{
CryptoPP::word output;
m_routine.Final(reinterpret_cast<byte*>(&output));
return output;
}
template <typename T>
CryptoPP::word checksum_impl<T>::compute(const byte* input, const size_t input_size)
{
CryptoPP::word output;
m_routine.CalculateDigest(reinterpret_cast<byte*>(&output), input, input_size);
return output;
}
}
#endif

125
security/diffie_hellman.cpp Normal file
View File

@ -0,0 +1,125 @@
//
// The MIT License(MIT)
//
// Copyright(c) 2014 Eijah
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files(the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions :
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
//
#include <cassert>
#include <cryptopp/nbtheory.h>
#include <cryptopp/osrng.h>
#include "diffie_hellman.h"
#include "security.h"
// NOTE: Ideally, we always want to validate the base/prime
// Unfortunately, I ran into some compatibility problems when using C# & C++ versions.
// Most likely this was caused by a shitty crypto implementation. To maintain bakwards
// compatibility cross-language I had to disable this check in demonsaw v2.0. Boo.
#define VALIDATE (0)
namespace eja
{
// Interface
void diffie_hellman::clear()
{
m_private.resize(0);
m_public.resize(0);
m_shared.resize(0);
}
// Init
void diffie_hellman::init(const size_t bits /*= default_bits*/)
{
// Initialize with random prime and base
CryptoPP::AutoSeededX917RNG<CryptoPP::AES> rng;
auto& group = m_dh.AccessGroupParameters();
group.Initialize(rng, bits);
#if VALIDATE
if (!m_dh.GetGroupParameters().ValidateGroup(rng, 3))
throw std::runtime_error("Failed to validate base and prime");
// Extract the prime and base
const auto& parameters = m_dh.GetGroupParameters();
const auto& g = parameters.GetGenerator();
const auto& p = parameters.GetModulus();
const auto& q = parameters.GetSubgroupOrder();
// http://groups.google.com/group/sci.crypt/browse_thread/thread/7dc7eeb04a09f0ce
const auto v = CryptoPP::ModularExponentiation(g, q, p);
if (v != CryptoPP::Integer::One())
throw std::runtime_error("Failed to verify order of the subgroup");
#endif
m_private.resize(m_dh.PrivateKeyLength());
m_public.resize(m_dh.PublicKeyLength());
m_shared.resize(m_dh.AgreedValueLength());
// Generate a pair of integers for Alice. The public integer is forwarded to Bob.
m_dh.GenerateKeyPair(rng, m_private, m_public);
}
void diffie_hellman::init(const CryptoPP::Integer& p, const CryptoPP::Integer& g)
{
CryptoPP::AutoSeededX917RNG<CryptoPP::AES> rng;
auto& group = m_dh.AccessGroupParameters();
group.Initialize(p, g);
#if VALIDATE
if (!m_dh.GetGroupParameters().ValidateGroup(rng, 3))
throw std::runtime_error("Failed to validate base and prime");
#endif
m_private.resize(m_dh.PrivateKeyLength());
m_public.resize(m_dh.PublicKeyLength());
m_shared.resize(m_dh.AgreedValueLength());
// Generate a pair of integers
m_dh.GenerateKeyPair(rng, m_private, m_public);
}
// Compute
bool diffie_hellman::compute(const CryptoPP::SecByteBlock& input, const bool validate /*= true*/)
{
assert(!input.empty());
return m_dh.Agree(m_shared, m_private, reinterpret_cast<const byte*>(input.data()), validate);
}
bool diffie_hellman::compute(const char* input, const bool validate /*= true*/)
{
assert(input);
return m_dh.Agree(m_shared, m_private, reinterpret_cast<const byte*>(input), validate);
}
bool diffie_hellman::compute(const std::string& input, const bool validate /*= true*/)
{
assert(!input.empty());
return m_dh.Agree(m_shared, m_private, reinterpret_cast<const byte*>(input.c_str()), validate);
}
bool diffie_hellman::compute(const byte* input, const size_t input_size, const bool validate /*= true*/)
{
assert(input && input_size);
return m_dh.Agree(m_shared, m_private, input, validate);
}
}

101
security/diffie_hellman.h Normal file
View File

@ -0,0 +1,101 @@
//
// The MIT License(MIT)
//
// Copyright(c) 2014 Eijah
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files(the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions :
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
//
#ifndef _EJA_DIFFIE_HELLMAN_
#define _EJA_DIFFIE_HELLMAN_
#include <memory>
#include <string>
#include <cryptopp/dh.h>
#include <cryptopp/integer.h>
#include <cryptopp/secblock.h>
#include "system/type.h"
namespace eja
{
class diffie_hellman final
{
private:
static const size_t default_bits = 128;
private:
CryptoPP::DH m_dh;
CryptoPP::SecByteBlock m_private;
CryptoPP::SecByteBlock m_public;
CryptoPP::SecByteBlock m_shared;
public:
using ptr = std::shared_ptr<diffie_hellman>;
public:
diffie_hellman(const size_t bits = default_bits) { init(bits); }
diffie_hellman(const byte* prime, const size_t prime_size, const size_t base) { init(prime, prime_size, base); }
diffie_hellman(const CryptoPP::Integer& prime, const CryptoPP::Integer& base) { init(prime, base); }
diffie_hellman(const CryptoPP::Integer& prime, const size_t base) { init(prime, base); }
diffie_hellman(const std::string& prime, const size_t base) { init(prime, base); }
diffie_hellman(const char* prime, const size_t base) { init(prime, base); }
~diffie_hellman() { }
// Interface
void clear();
// Utility
bool empty() const { return !m_shared.size(); }
// Init
void init(const size_t bits = default_bits);
void init(const byte* prime, const size_t prime_size, const size_t base) { init(CryptoPP::Integer(prime, prime_size), base); }
void init(const CryptoPP::Integer& prime, const CryptoPP::Integer& base);
void init(const CryptoPP::Integer& prime, const size_t base) { init(prime, CryptoPP::Integer(base)); }
void init(const std::string& prime, const size_t base) { init(reinterpret_cast<const byte*>(prime.c_str()), prime.size(), base); }
void init(const char* prime, const size_t base) { init(reinterpret_cast<const byte*>(prime), strlen(prime), base); }
// Compute
bool compute(const byte* input, const size_t input_size, const bool validate = true);
bool compute(const CryptoPP::SecByteBlock& input, const bool validate = true);
bool compute(const std::string& input, const bool validate = true);
bool compute(const char* input, const bool validate = true);
// Accessor
size_t size() const { return m_shared.size(); }
const CryptoPP::Integer& get_base() const { return m_dh.GetGroupParameters().GetGenerator(); }
const CryptoPP::Integer& get_prime() const { return m_dh.GetGroupParameters().GetModulus(); }
const CryptoPP::SecByteBlock& get_private_key() const { return m_private; }
const CryptoPP::SecByteBlock& get_public_key() const { return m_public; }
const CryptoPP::SecByteBlock& get_shared_key() const { return m_shared; }
// Static
static ptr create() { return std::make_shared<diffie_hellman>(); }
static ptr create(const size_t bits) { return std::make_shared<diffie_hellman>(bits); }
static ptr create(const byte* prime, const size_t prime_size, const size_t base) { return std::make_shared<diffie_hellman>(prime, prime_size, base); }
static ptr create(const CryptoPP::Integer& prime, const CryptoPP::Integer& base) { return std::make_shared<diffie_hellman>(prime, base); }
static ptr create(const CryptoPP::Integer& prime, const size_t base) { return std::make_shared<diffie_hellman>(prime, base); }
static ptr create(const std::string& prime, const size_t base) { return std::make_shared<diffie_hellman>(prime, base); }
static ptr create(const char* prime, const size_t base) { return std::make_shared<diffie_hellman>(prime, base); }
};
}
#endif

111
security/filter.h Normal file
View File

@ -0,0 +1,111 @@
//
// The MIT License(MIT)
//
// Copyright(c) 2014 Eijah
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files(the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions :
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
//
#ifndef _EJA_FILTER_
#define _EJA_FILTER_
#include <string>
#include <cryptopp/base64.h>
#include <cryptopp/integer.h>
#include <cryptopp/hex.h>
#include <cryptopp/secblock.h>
#include "security.h"
namespace eja
{
// Using
template <typename E, typename D> class filter;
using base64 = filter<CryptoPP::Base64Encoder, CryptoPP::Base64Decoder>;
using hex = filter<CryptoPP::HexEncoder, CryptoPP::HexDecoder>;
template <typename E, typename D>
class filter final
{
public:
static const size_t default_size = 16;
private:
filter() = delete;
filter(const filter&) = delete;
~filter() = delete;
// Operator
filter& operator=(const filter&) = delete;
public:
// Random
static std::string random(const size_t output_size = default_size) { return encode(security::random(output_size)); }
// Encode
static std::string encode(const byte* input, const size_t input_size);
static std::string encode(const CryptoPP::SecByteBlock& input) { return encode(input.data(), input.size()); }
static std::string encode(const CryptoPP::SecByteBlock& input, const size_t input_size) { return encode(input.data(), std::min(input.size(), input_size)); }
static std::string encode(const std::string& input, const size_t input_size) { return encode(reinterpret_cast<const byte*>(input.c_str()), std::min(input.size(), input_size)); }
static std::string encode(const std::string& input) { return encode(reinterpret_cast<const byte*>(input.c_str()), input.size()); }
static std::string encode(const char* input, const size_t input_size) { return encode(reinterpret_cast<const byte*>(input), std::min(strlen(input), input_size)); }
static std::string encode(const char* input) { return encode(reinterpret_cast<const byte*>(input), strlen(input)); }
static std::string encode(const CryptoPP::Integer& input) { return encode(security::str(input)); }
// Decode
static std::string decode(const byte* input, const size_t input_size);
static std::string decode(const CryptoPP::SecByteBlock& input) { return decode(input.data(), input.size()); }
static std::string decode(const CryptoPP::SecByteBlock& input, const size_t input_size) { return decode(input.data(), std::min(input.size(), input_size)); }
static std::string decode(const std::string& input, const size_t input_size) { return decode(reinterpret_cast<const byte*>(input.c_str()), std::min(input.size(), input_size)); }
static std::string decode(const std::string& input) { return decode(reinterpret_cast<const byte*>(input.c_str()), input.size()); }
static std::string decode(const char* input, const size_t input_size) { return decode(reinterpret_cast<const byte*>(input), std::min(strlen(input), input_size)); }
static std::string decode(const char* input) { return decode(reinterpret_cast<const byte*>(input), strlen(input)); }
static std::string decode(const CryptoPP::Integer& input) { return decode(security::str(input)); }
};
// Encoder
template <typename E, typename D>
std::string filter<E, D>::encode(const byte* input, const size_t input_size)
{
//assert(input && input_size);
E encoder(NULL, false);
std::string output;
encoder.Attach(new CryptoPP::StringSink(output));
encoder.Put(input, input_size);
encoder.MessageEnd();
return output;
}
// Decode
template <typename E, typename D>
std::string filter<E, D>::decode(const byte* input, const size_t input_size)
{
//assert(input && input_size);
D decoder;
std::string output;
decoder.Attach(new CryptoPP::StringSink(output));
decoder.Put(input, input_size);
decoder.MessageEnd();
return output;
}
}
#endif

178
security/hash.h Normal file
View File

@ -0,0 +1,178 @@
//
// The MIT License(MIT)
//
// Copyright(c) 2014 Eijah
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files(the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions :
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
//
#ifndef _EJA_HASH_
#define _EJA_HASH_
#define CRYPTOPP_ENABLE_NAMESPACE_WEAK 1
#include <memory>
#include <string>
#include <cryptopp/md2.h>
#include <cryptopp/md4.h>
#include <cryptopp/md5.h>
#include <cryptopp/osrng.h>
#include <cryptopp/secblock.h>
#include <cryptopp/sha.h>
#include <cryptopp/sha3.h>
#include "security.h"
namespace eja
{
template <typename T>
class hash_impl;
// MD
using md2 = hash_impl<CryptoPP::Weak::MD2>;
using md4 = hash_impl<CryptoPP::Weak::MD4>;
using md5 = hash_impl<CryptoPP::Weak::MD5>;
using md = md5;
// SHA1
using sha1 = hash_impl<CryptoPP::SHA1>;
using sha = sha1;
// SHA2
using sha224 = hash_impl<CryptoPP::SHA224>;
using sha256 = hash_impl<CryptoPP::SHA256>;
using sha384 = hash_impl<CryptoPP::SHA384>;
using sha512 = hash_impl<CryptoPP::SHA512>;
// SHA3
using sha3_224 = hash_impl<CryptoPP::SHA3_224>;
using sha3_256 = hash_impl<CryptoPP::SHA3_256>;
using sha3_384 = hash_impl<CryptoPP::SHA3_384>;
using sha3_512 = hash_impl<CryptoPP::SHA3_512>;
// Type
enum class hash_type { md5, sha1, sha224, sha256, sha384, sha512, sha3_224, sha3_256, sha3_384, sha3_512 };
// Hash
class hash
{
protected:
CryptoPP::SecByteBlock m_salt;
public:
using ptr = std::shared_ptr<hash>;
public:
hash() { }
virtual ~hash() { }
// Interface
void clear() { m_salt.resize(0); }
// Utility
bool empty() const { return !m_salt.size(); }
// Random
virtual std::string random() const = 0;
// Compute
virtual std::string compute() = 0;
virtual std::string compute(const byte* input, const size_t input_size) = 0;
std::string compute(const CryptoPP::SecByteBlock& input) { return compute(input.data(), input.size()); }
std::string compute(const std::string& input) { return compute(reinterpret_cast<const byte*>(input.c_str()), input.size()); }
std::string compute(const char* input) { return compute(reinterpret_cast<const byte*>(input), strlen(input)); }
// Update
virtual void update(const byte* input, const size_t input_size) = 0;
void update(const CryptoPP::SecByteBlock& input) { return update(input.data(), input.size()); }
void update(const std::string& input) { update(reinterpret_cast<const byte*>(input.c_str()), input.size()); }
void update(const char* input) { update(reinterpret_cast<const byte*>(input), strlen(input)); }
// Mutator
void set_salt(const char* salt) { m_salt.Assign(reinterpret_cast<const byte*>(salt), strlen(salt)); }
void set_salt(const CryptoPP::SecByteBlock& salt) { m_salt.Assign(salt.data(), salt.size()); }
void set_salt(const std::string& salt) { m_salt.Assign(reinterpret_cast<const byte*>(salt.c_str()), salt.size()); }
void set_salt(const byte* salt, const size_t salt_size) { m_salt.Assign(salt, salt_size); }
// Accessor
const CryptoPP::SecByteBlock& get_salt() const { return m_salt; }
virtual size_t size() const = 0;
};
template <typename T>
class hash_impl final : public hash
{
private:
T m_routine;
public:
hash_impl() { }
virtual ~hash_impl() override { }
// Operator
std::string operator()() const { return hash_impl().random(); }
std::string operator()(const CryptoPP::SecByteBlock& input) const { return hash_impl().compute(input); }
std::string operator()(const std::string& input) const { return hash_impl().compute(input); }
std::string operator()(const char* input) const { return hash_impl().compute(input); }
// Random
virtual std::string random() const override { return security::random(T::DIGESTSIZE); }
// Compute
using hash::compute;
virtual std::string compute() override;
virtual std::string compute(const byte* input, const size_t input_size) override;
// Update
using hash::update;
virtual void update(const byte* input, const size_t input_size) override { m_routine.Update(input, input_size); }
// Accessor
virtual size_t size() const override { return T::DIGESTSIZE; }
// Static
static ptr create() { return std::make_shared<hash_impl<T>>(); }
};
// Compute
template <typename T>
std::string hash_impl<T>::compute()
{
byte digest[T::DIGESTSIZE];
m_routine.Update(m_salt.data(), m_salt.size());
m_routine.Final(digest);
return security::str(digest, T::DIGESTSIZE);
}
template <typename T>
std::string hash_impl<T>::compute(const byte* input, const size_t input_size)
{
assert(input && input_size);
byte digest[T::DIGESTSIZE];
m_routine.Update(input, input_size);
m_routine.Update(m_salt.data(), m_salt.size());
m_routine.Final(digest);
return security::str(digest, T::DIGESTSIZE);
}
}
#endif

30
security/hex.h Normal file
View File

@ -0,0 +1,30 @@
//
// The MIT License(MIT)
//
// Copyright(c) 2014 Eijah
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files(the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions :
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
//
#ifndef _EJA_HEX_
#define _EJA_HEX_
#include "filter.h"
#endif

169
security/hmac.h Normal file
View File

@ -0,0 +1,169 @@
//
// The MIT License(MIT)
//
// Copyright(c) 2014 Eijah
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files(the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions :
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
//
#ifndef _EJA_HMAC_
#define _EJA_HMAC_
#define CRYPTOPP_ENABLE_NAMESPACE_WEAK 1
#include <memory>
#include <string>
#include <cryptopp/hmac.h>
#include <cryptopp/md5.h>
#include <cryptopp/osrng.h>
#include <cryptopp/secblock.h>
#include <cryptopp/sha.h>
#include "hash.h"
#include "security.h"
namespace eja
{
// Using
template <typename T>
class hmac_impl;
// MD
using hmac_md5 = hmac_impl<CryptoPP::HMAC<CryptoPP::Weak::MD5>>;
using hmac_md = hmac_md5;
// SHA1
using hmac_sha1 = hmac_impl<CryptoPP::HMAC<CryptoPP::SHA1>>;
using hmac_sha = hmac_sha1;
// SHA2
using hmac_sha224 = hmac_impl<CryptoPP::HMAC<CryptoPP::SHA224>>;
using hmac_sha256 = hmac_impl<CryptoPP::HMAC<CryptoPP::SHA256>>;
using hmac_sha384 = hmac_impl<CryptoPP::HMAC<CryptoPP::SHA384>>;
using hmac_sha512 = hmac_impl<CryptoPP::HMAC<CryptoPP::SHA512>>;
// Type
enum class hmac_type { md5, sha1, sha224, sha256, sha384, sha512 };
// HMAC
class hmac : public hash
{
public:
using ptr = std::shared_ptr<hmac>;
public:
hmac() { }
virtual ~hmac() override { }
// Utility
virtual void clear() { hash::clear(); }
// Mutator
virtual void set_key(const byte* key, const size_t key_size) = 0;
virtual void set_key(const CryptoPP::SecByteBlock& key) = 0;
virtual void set_key(const std::string& key) = 0;
virtual void set_key(const char* key) = 0;
};
template <typename T>
class hmac_impl final : public hmac
{
private:
T m_routine;
public:
hmac_impl() { clear(); }
hmac_impl(const byte* key, const size_t key_size) { set_key(key, key_size); }
hmac_impl(const CryptoPP::SecByteBlock& key) { set_key(key); }
hmac_impl(const std::string& key) { set_key(key); }
hmac_impl(const char* key) { set_key(key); }
virtual ~hmac_impl() override { };
// Operator
std::string operator()() const { return hmac_impl().random(); }
// Utility
virtual void clear() override;
// Random
virtual std::string random() const override { return security::random(T::DIGESTSIZE); }
// Compute
using hmac::compute;
virtual std::string compute() override;
virtual std::string compute(const byte* input, const size_t input_size) override;
// Update
using hmac::update;
virtual void update(const byte* input, const size_t input_size) override { m_routine.Update(input, input_size); }
// Accessor
virtual size_t size() const override { return T::DIGESTSIZE; }
// Mutator
virtual void set_key(const byte* key, const size_t key_size) override { m_routine.SetKey(key, key_size); }
virtual void set_key(const CryptoPP::SecByteBlock& key) override { m_routine.SetKey(key.data(), key.size()); }
virtual void set_key(const std::string& key) override { m_routine.SetKey(reinterpret_cast<const byte*>(key.c_str()), key.size()); }
virtual void set_key(const char* key) override { m_routine.SetKey(reinterpret_cast<const byte*>(key), strlen(key)); }
// Static
static ptr create() { return std::make_shared<hmac_impl<T>>(); }
static ptr create(const byte* key, const size_t key_size) { return std::make_shared<hmac_impl<T>>(key, key_size); }
static ptr create(const CryptoPP::SecByteBlock& key) { return std::make_shared<hmac_impl<T>>(key); }
static ptr create(const std::string& key) { return std::make_shared<hmac_impl<T>>(key); }
static ptr create(const char* key) { return std::make_shared<hmac_impl<T>>(key); }
};
// Utility
template <typename T>
void hmac_impl<T>::clear()
{
hmac::clear();
byte key[T::DIGESTSIZE];
memset(key, 0, T::DIGESTSIZE);
set_key(key, T::DIGESTSIZE);
}
// Compute
template <typename T>
std::string hmac_impl<T>::compute()
{
byte digest[T::DIGESTSIZE];
m_routine.Update(m_salt.data(), m_salt.size());
m_routine.Final(digest);
return security::str(digest, T::DIGESTSIZE);
}
template <typename T>
std::string hmac_impl<T>::compute(const byte* input, const size_t input_size)
{
assert(input && input_size);
byte digest[T::DIGESTSIZE];
m_routine.Update(input, input_size);
m_routine.Update(m_salt.data(), m_salt.size());
m_routine.Final(digest);
return security::str(digest, T::DIGESTSIZE);
}
}
#endif

32
security/md.h Normal file
View File

@ -0,0 +1,32 @@
//
// The MIT License(MIT)
//
// Copyright(c) 2014 Eijah
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files(the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions :
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
//
#ifndef _EJA_MD_
#define _EJA_MD_
#include "hash.h"
#include "hmac.h"
#include "pbkdf.h"
#endif

192
security/pbkdf.h Normal file
View File

@ -0,0 +1,192 @@
//
// The MIT License(MIT)
//
// Copyright(c) 2014 Eijah
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files(the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions :
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
//
#ifndef _EJA_PASSWORD_
#define _EJA_PASSWORD_
#define CRYPTOPP_ENABLE_NAMESPACE_WEAK 1
#include <memory>
#include <string>
#include <cryptopp/md5.h>
#include <cryptopp/osrng.h>
#include <cryptopp/pwdbased.h>
#include <cryptopp/sha.h>
#include <cryptopp/sha3.h>
#include <cryptopp/secblock.h>
#include "security.h"
#include "system/type.h"
namespace eja
{
template <typename T, typename U>
class pbkdf_impl;
// PBKDF1 - MD
using pbkdf1_md5 = pbkdf_impl<CryptoPP::PKCS5_PBKDF1<CryptoPP::Weak::MD5>, CryptoPP::Weak::MD5>;
using pbkdf1_md = pbkdf1_md5;
// PBKDF1 - SHA1
using pbkdf1_sha1 = pbkdf_impl<CryptoPP::PKCS5_PBKDF1<CryptoPP::SHA1>, CryptoPP::SHA1>;
// PBKDF1 - SHA2
using pbkdf1_sha224 = pbkdf_impl<CryptoPP::PKCS5_PBKDF1<CryptoPP::SHA224>, CryptoPP::SHA224>;
using pbkdf1_sha256 = pbkdf_impl<CryptoPP::PKCS5_PBKDF1<CryptoPP::SHA256>, CryptoPP::SHA256>;
using pbkdf1_sha384 = pbkdf_impl<CryptoPP::PKCS5_PBKDF1<CryptoPP::SHA384>, CryptoPP::SHA384>;
using pbkdf1_sha512 = pbkdf_impl<CryptoPP::PKCS5_PBKDF1<CryptoPP::SHA512>, CryptoPP::SHA512>;
// PBKDF2 - MD
using pbkdf2_hmac_md5 = pbkdf_impl<CryptoPP::PKCS5_PBKDF2_HMAC<CryptoPP::Weak::MD5>, CryptoPP::Weak::MD5>;
using pbkdf2_hmac_md = pbkdf2_hmac_md5;
// PBKDF2 - SHA1
using pbkdf2_hmac_sha1 = pbkdf_impl<CryptoPP::PKCS5_PBKDF2_HMAC<CryptoPP::SHA1>, CryptoPP::SHA1>;
// PBKDF2 - SHA2
using pbkdf2_hmac_sha224 = pbkdf_impl<CryptoPP::PKCS5_PBKDF2_HMAC<CryptoPP::SHA224>, CryptoPP::SHA224>;
using pbkdf2_hmac_sha256 = pbkdf_impl<CryptoPP::PKCS5_PBKDF2_HMAC<CryptoPP::SHA256>, CryptoPP::SHA256>;
using pbkdf2_hmac_sha384 = pbkdf_impl<CryptoPP::PKCS5_PBKDF2_HMAC<CryptoPP::SHA384>, CryptoPP::SHA384>;
using pbkdf2_hmac_sha512 = pbkdf_impl<CryptoPP::PKCS5_PBKDF2_HMAC<CryptoPP::SHA512>, CryptoPP::SHA512>;
// Type
enum class pbkdf_type { md5, sha1, sha224, sha256, sha384, sha512 };
// PBKDF
class pbkdf
{
protected:
CryptoPP::SecByteBlock m_salt;
size_t m_iterations;
static const size_t default_iterations = (1 << 14);
public:
using ptr = std::shared_ptr<pbkdf>;
public:
pbkdf() : m_iterations(default_iterations) { }
pbkdf(const char* salt, const size_t iterations) : m_iterations(iterations) { set_salt(salt); }
pbkdf(const CryptoPP::SecByteBlock& salt, const size_t iterations) : m_iterations(iterations) { set_salt(salt); }
pbkdf(const std::string& salt, const size_t iterations) : m_iterations(iterations) { set_salt(salt); }
pbkdf(const byte* salt, const size_t salt_size, const size_t iterations) : m_iterations(iterations) { set_salt(salt, salt_size); }
virtual ~pbkdf() { };
// Interface
void clear() { m_salt.resize(0); }
// Utility
bool empty() const { return !m_salt.size(); }
// Random
virtual std::string random(const size_t output_size) const = 0;
// Compute
virtual std::string compute(const byte* input, const size_t input_size, const size_t output_size) const = 0;
virtual std::string compute(const CryptoPP::SecByteBlock& input, const size_t output_size) const = 0;
virtual std::string compute(const std::string& input, const size_t output_size) const = 0;
virtual std::string compute(const char* input, const size_t output_size) const = 0;
virtual void compute(const byte* input, const size_t input_size, CryptoPP::SecByteBlock& output) const = 0;
virtual void compute(const CryptoPP::SecByteBlock& input, CryptoPP::SecByteBlock& output) const = 0;
virtual void compute(const std::string& input, CryptoPP::SecByteBlock& output) const = 0;
virtual void compute(const char* input, CryptoPP::SecByteBlock& output) const = 0;
// Mutator
void set_salt(const char* salt) { m_salt.Assign(reinterpret_cast<const byte*>(salt), strlen(salt)); }
void set_salt(const CryptoPP::SecByteBlock& salt) { m_salt.Assign(salt.data(), salt.size()); }
void set_salt(const std::string& salt) { m_salt.Assign(reinterpret_cast<const byte*>(salt.c_str()), salt.size()); }
void set_salt(const byte* salt, const size_t salt_size) { m_salt.Assign(salt, salt_size); }
void set_iterations(size_t iterations) { m_iterations = iterations; }
// Accessor
const CryptoPP::SecByteBlock& get_salt() const { return m_salt; }
size_t get_iterations() const { return m_iterations; }
virtual size_t size() const = 0;
};
template <typename T, typename U>
class pbkdf_impl final : public pbkdf
{
private:
T m_routine;
public:
pbkdf_impl() { }
pbkdf_impl(const byte* salt, const size_t salt_size, const size_t iterations = default_iterations) : pbkdf(salt, salt_size, iterations) { }
pbkdf_impl(const CryptoPP::SecByteBlock& salt, const size_t iterations = default_iterations) : pbkdf(salt, iterations) { }
pbkdf_impl(const std::string& salt, const size_t iterations = default_iterations) : pbkdf(salt, iterations) { }
pbkdf_impl(const char* salt, const size_t iterations = default_iterations) : pbkdf(salt, iterations) { }
virtual ~pbkdf_impl() override { };
// Operator
std::string operator()(const size_t output_size = U::DIGESTSIZE) const { return pbkdf_impl().random(output_size); }
// Random
virtual std::string random(const size_t output_size = U::DIGESTSIZE) const override { return security::random(output_size); }
// Compute
virtual std::string compute(const byte* input, const size_t input_size, const size_t output_size = U::DIGESTSIZE) const override;
virtual std::string compute(const CryptoPP::SecByteBlock& input, const size_t output_size = U::DIGESTSIZE) const override { return compute(input.data(), input.size(), output_size); }
virtual std::string compute(const std::string& input, const size_t output_size = U::DIGESTSIZE) const override { return compute(reinterpret_cast<const byte*>(input.c_str()), input.size(), output_size); }
virtual std::string compute(const char* input, const size_t output_size = U::DIGESTSIZE) const override { return compute(reinterpret_cast<const byte*>(input), strlen(input), output_size); }
virtual void compute(const byte* input, const size_t input_size, CryptoPP::SecByteBlock& output) const override;
virtual void compute(const CryptoPP::SecByteBlock& input, CryptoPP::SecByteBlock& output) const override { return compute(input.data(), input.size(), output); }
virtual void compute(const std::string& input, CryptoPP::SecByteBlock& output) const override { return compute(reinterpret_cast<const byte*>(input.c_str()), input.size(), output); }
virtual void compute(const char* input, CryptoPP::SecByteBlock& output) const override { return compute(reinterpret_cast<const byte*>(input), strlen(input), output); }
// Static
virtual size_t size() const override { return U::DIGESTSIZE; }
// Static
static ptr create() { return std::make_shared<pbkdf_impl<T, U>>(); }
static ptr create(const byte* salt, const size_t salt_size, const size_t iterations = default_iterations) { return std::make_shared<pbkdf_impl<T, U>>(salt, salt_size, iterations); }
static ptr create(const CryptoPP::SecByteBlock& salt, const size_t iterations = default_iterations) { return std::make_shared<pbkdf_impl<T, U>>(salt, iterations); }
static ptr create(const std::string& salt, const size_t iterations = default_iterations) { return std::make_shared<pbkdf_impl<T, U>>(salt, iterations); }
static ptr create(const char* salt, const size_t iterations = default_iterations) { return std::make_shared<pbkdf_impl<T, U>>(salt, iterations); }
};
// Compute
template <typename T, typename U>
std::string pbkdf_impl<T, U>::compute(const byte* input, const size_t input_size, size_t output_size /*= U::DIGESTSIZE*/) const
{
assert(output_size);
CryptoPP::SecByteBlock block(output_size);
m_routine.DeriveKey(block, block.size(), 0x00, input, input_size, m_salt, m_salt.size(), m_iterations, 0);
return security::str(block);
}
template <typename T, typename U>
void pbkdf_impl<T, U>::compute(const byte* input, const size_t input_size, CryptoPP::SecByteBlock& output) const
{
assert(output.size());
m_routine.DeriveKey(output, output.size(), 0x00, input, input_size, m_salt, m_salt.size(), m_iterations, 0);
}
}
#endif

278
security/security.cpp Normal file
View File

@ -0,0 +1,278 @@
//
// The MIT License(MIT)
//
// Copyright(c) 2014 Eijah
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files(the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions :
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
//
#ifdef _MSC_VER
#pragma warning(disable: 4996)
#endif
#include <sstream>
#include <boost/algorithm/string.hpp>
#include <cryptopp/filters.h>
#include <cryptopp/osrng.h>
#include <cryptopp/secblock.h>
#include "hash.h"
#include "block_cipher.h"
#include "hmac.h"
#include "pbkdf.h"
#include "security.h"
namespace eja
{
// Cipher
block_cipher::ptr security::get_cipher(const cipher_type type)
{
switch (type)
{
case cipher_type::aes: return aes::create();
case cipher_type::mars: return mars::create();
case cipher_type::rc6: return rc6::create();
case cipher_type::serpent: return serpent::create();
case cipher_type::twofish: return twofish::create();
}
return nullptr;
}
block_cipher::ptr security::get_cipher(const char* name)
{
if (boost::iequals(name, "aes md5"))
return aes::create();
else if (boost::iequals(name, "mars"))
return mars::create();
else if (boost::iequals(name, "rc6"))
return rc6::create();
else if (boost::iequals(name, "serpent"))
return serpent::create();
else if (boost::iequals(name, "twofish"))
return twofish::create();
return nullptr;
}
const char* security::get_cipher_name(const cipher_type type)
{
switch (type)
{
case cipher_type::aes: return "AES";
case cipher_type::mars: return "MARS";
case cipher_type::rc6: return "RC6";
case cipher_type::serpent: return "Serpent";
case cipher_type::twofish: return "Twofish";
default: return "";
}
}
// Hash
hash::ptr security::get_hash(const hash_type type)
{
switch (type)
{
case hash_type::md5: return md5::create();
case hash_type::sha1: return sha1::create();
case hash_type::sha224: return sha224::create();
case hash_type::sha256: return sha256::create();
case hash_type::sha384: return sha384::create();
case hash_type::sha512: return sha512::create();
case hash_type::sha3_224: return sha3_224::create();
case hash_type::sha3_256: return sha3_256::create();
case hash_type::sha3_384: return sha3_384::create();
case hash_type::sha3_512: return sha3_512::create();
}
return nullptr;
}
hash::ptr security::get_hash(const char* name)
{
if (boost::iequals(name, "md5"))
return md5::create();
else if (boost::iequals(name, "sha1"))
return sha1::create();
else if (boost::iequals(name, "sha224"))
return sha224::create();
else if (boost::iequals(name, "sha256"))
return sha256::create();
else if (boost::iequals(name, "sha384"))
return sha384::create();
else if (boost::iequals(name, "sha512"))
return sha512::create();
else if (boost::iequals(name, "sha3 224"))
return sha3_224::create();
else if (boost::iequals(name, "sha3 256"))
return sha3_256::create();
else if (boost::iequals(name, "sha3 384"))
return sha3_384::create();
else if (boost::iequals(name, "sha3 512"))
return sha3_512::create();
return nullptr;
}
const char* security::get_hash_name(const hash_type type)
{
switch (type)
{
case hash_type::md5: return "MD5";
case hash_type::sha1: return "SHA1";
case hash_type::sha224: return "SHA224";
case hash_type::sha256: return "SHA256";
case hash_type::sha384: return "SHA384";
case hash_type::sha512: return "SHA512";
case hash_type::sha3_224: return "SHA3 224";
case hash_type::sha3_256: return "SHA3 256";
case hash_type::sha3_384: return "SHA3 384";
case hash_type::sha3_512: return "SHA3 512";
default: return "";
}
}
// HMAC
hmac::ptr security::get_hmac(const hmac_type type)
{
switch (type)
{
case hmac_type::md5: return hmac_md5::create();
case hmac_type::sha1: return hmac_sha1::create();
case hmac_type::sha224: return hmac_sha224::create();
case hmac_type::sha256: return hmac_sha256::create();
case hmac_type::sha384: return hmac_sha384::create();
case hmac_type::sha512: return hmac_sha512::create();
}
return nullptr;
}
hmac::ptr security::get_hmac(const char* name)
{
if (boost::iequals(name, "hmac md5"))
return hmac_md5::create();
else if (boost::iequals(name, "hmac sha1"))
return hmac_sha1::create();
else if (boost::iequals(name, "hmac sha224"))
return hmac_sha224::create();
else if (boost::iequals(name, "hmac sha256"))
return hmac_sha256::create();
else if (boost::iequals(name, "hmac sha384"))
return hmac_sha384::create();
else if (boost::iequals(name, "hmac sha512"))
return hmac_sha512::create();
return nullptr;
}
const char* security::get_hmac_name(const hmac_type type)
{
switch (type)
{
case hmac_type::md5: return "HMAC MD5";
case hmac_type::sha1: return "HMAC SHA1";
case hmac_type::sha224: return "HMAC SHA224";
case hmac_type::sha256: return "HMAC SHA256";
case hmac_type::sha384: return "HMAC SHA384";
case hmac_type::sha512: return "HMAC SHA512";
default: return "";
}
}
// PBKDF
pbkdf::ptr security::get_pbkdf(const pbkdf_type type)
{
switch (type)
{
case pbkdf_type::md5: return pbkdf2_hmac_md5::create();
case pbkdf_type::sha1: return pbkdf2_hmac_sha1::create();
case pbkdf_type::sha224: return pbkdf2_hmac_sha224::create();
case pbkdf_type::sha256: return pbkdf2_hmac_sha256::create();
case pbkdf_type::sha384: return pbkdf2_hmac_sha384::create();
case pbkdf_type::sha512: return pbkdf2_hmac_sha512::create();
}
return nullptr;
}
pbkdf::ptr security::get_pbkdf(const char* name)
{
if (boost::iequals(name, "pbkdf2_hmac_md5"))
return pbkdf2_hmac_md5::create();
else if (boost::iequals(name, "pbkdf2_hmac_sha1"))
return pbkdf2_hmac_sha1::create();
else if (boost::iequals(name, "pbkdf2_hmac_sha224"))
return pbkdf2_hmac_sha224::create();
else if (boost::iequals(name, "pbkdf2_hmac_sha256"))
return pbkdf2_hmac_sha256::create();
else if (boost::iequals(name, "pbkdf2_hmac_sha384"))
return pbkdf2_hmac_sha384::create();
else if (boost::iequals(name, "pbkdf2_hmac_sha512"))
return pbkdf2_hmac_sha512::create();
return nullptr;
}
const char* security::get_pbkdf_name(const pbkdf_type type)
{
switch (type)
{
case pbkdf_type::md5: return "PBKDF HMAC MD5";
case pbkdf_type::sha1: return "PBKDF HMAC SHA1";
case pbkdf_type::sha224: return "PBKDF HMAC SHA224";
case pbkdf_type::sha256: return "PBKDF HMAC SHA256";
case pbkdf_type::sha384: return "PBKDF HMAC SHA384";
case pbkdf_type::sha512: return "PBKDF HMAC SHA512";
default: return "";
}
}
// Utility
std::string security::str(const byte* input, const size_t input_size)
{
std::string output;
CryptoPP::StringSink sink(output);
sink.Put(input, input_size);
return output;
}
std::string security::str(const CryptoPP::SecByteBlock& input)
{
std::string output;
CryptoPP::StringSink sink(output);
sink.Put(input, input.size());
return output;
}
std::string security::str(const CryptoPP::Integer& input)
{
const auto input_size = input.MinEncodedSize();
CryptoPP::SecByteBlock block(input_size);
input.Encode(block.BytePtr(), input_size);
return str(block);
// NOTE: CryptoPP::Integer has a weird ostream format (uses prefixes to specify numeric base)
//
/*std::ostringstream oss;
oss << std::hex << input;
return oss.str();*/
}
}

121
security/security.h Normal file
View File

@ -0,0 +1,121 @@
//
// The MIT License(MIT)
//
// Copyright(c) 2014 Eijah
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files(the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions :
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
//
#ifndef _EJA_SECURITY_
#define _EJA_SECURITY_
#include <cassert>
#include <string>
#include <cryptopp/aes.h>
#include <cryptopp/integer.h>
#include <cryptopp/osrng.h>
#include <cryptopp/secblock.h>
namespace eja
{
// Type
enum class cipher_type;
enum class hash_type;
enum class hmac_type;
enum class pbkdf_type;
// Algorithm
class block_cipher;
class hash;
class hmac;
class pbkdf;
class security final
{
public:
static const char* empty;
static const char* signature;
private:
security() = delete;
security(const security&) = delete;
~security() = delete;
// Operator
security& operator=(const security&) = delete;
public:
// Random
static std::string random(const size_t output_size) { return random<CryptoPP::AES>(output_size); }
template <typename T> static std::string random(const size_t output_size);
// Utility
static std::string str(const byte* input, const size_t input_size);
static std::string str(const CryptoPP::SecByteBlock& input);
static std::string str(const CryptoPP::Integer& input);
// Cipher
static std::shared_ptr<block_cipher> get_cipher(const cipher_type type);
static std::shared_ptr<block_cipher> get_cipher(const std::string& name) { return get_cipher(name.c_str()); }
static std::shared_ptr<block_cipher> get_cipher(const char* name);
static const char* get_cipher_name(const cipher_type type);
static const char* get_cipher_name(const size_t type) { return get_cipher_name(static_cast<cipher_type>(type)); }
// Hash
static std::shared_ptr<hash> get_hash(const hash_type type);
static std::shared_ptr<hash> get_hash(const std::string& name) { return get_hash(name.c_str()); }
static std::shared_ptr<hash> get_hash(const char* name);
static const char* get_hash_name(const hash_type type);
static const char* get_hash_name(const size_t type) { return get_hash_name(static_cast<hash_type>(type)); }
// HMAC
static std::shared_ptr<hmac> get_hmac(const hmac_type type);
static std::shared_ptr<hmac> get_hmac(const std::string& name) { return get_hmac(name.c_str()); }
static std::shared_ptr<hmac> get_hmac(const char* name);
static const char* get_hmac_name(const hmac_type type);
static const char* get_hmac_name(const size_t type) { return get_hmac_name(static_cast<hmac_type>(type)); }
// PBKDF
static std::shared_ptr<pbkdf> get_pbkdf(const pbkdf_type type);
static std::shared_ptr<pbkdf> get_pbkdf(const std::string& name) { return get_pbkdf(name.c_str()); }
static std::shared_ptr<pbkdf> get_pbkdf(const char* name);
static const char* get_pbkdf_name(const pbkdf_type type);
static const char* get_pbkdf_name(const size_t type) { return get_pbkdf_name(static_cast<pbkdf_type>(type)); }
};
// Random
template <typename T>
std::string security::random(const size_t output_size)
{
assert(output_size);
CryptoPP::AutoSeededX917RNG<T> rng;
CryptoPP::SecByteBlock block(output_size);
rng.GenerateBlock(block, block.size());
return str(block);
}
}
#endif

32
security/sha.h Normal file
View File

@ -0,0 +1,32 @@
//
// The MIT License(MIT)
//
// Copyright(c) 2014 Eijah
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files(the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions :
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
//
#ifndef _EJA_SHA_
#define _EJA_SHA_
#include "hash.h"
#include "hmac.h"
#include "pbkdf.h"
#endif

47
system/type.h Normal file
View File

@ -0,0 +1,47 @@
#ifndef _EJA_TYPE_
#define _EJA_TYPE_
#include <limits>
#include <boost/cstdint.hpp>
// Int (signed)
using s8 = boost::int_fast8_t;
#define s8_max std::numeric_limits<s8>::max()
using s16 = boost::int_fast16_t;
#define s16_max std::numeric_limits<s16>::max()
using s32 = boost::int_fast32_t;
#define s32_max std::numeric_limits<s32>::max()
using s64 = boost::int_fast64_t;
#define s64_max std::numeric_limits<s64>::max()
// Int (unsigned)
using u8 = boost::uint_fast8_t;
using byte = boost::uint_fast8_t;
#define u8_max std::numeric_limits<u8>::max()
using u16 = boost::uint_fast16_t;
#define u16_max std::numeric_limits<u16>::max()
using u32 = boost::uint_fast32_t;
#define u32_max std::numeric_limits<u32>::max()
using u64 = boost::uint_fast64_t;
#define u64_max std::numeric_limits<u64>::max()
// Long (unsigned)
using ulong = unsigned long;
// Real
#if SIZE_MAX == 0xffffffff
using real = float;
#define real_max std::numeric_limits<real>::max()
#else
using real = double;
#define real_max std::numeric_limits<real>::max()
#endif
#endif