remove unused stuff
This commit is contained in:
@@ -1,72 +0,0 @@
|
||||
// mdc.h - written and placed in the public domain by Wei Dai
|
||||
|
||||
#ifndef CRYPTOPP_MDC_H
|
||||
#define CRYPTOPP_MDC_H
|
||||
|
||||
/** \file
|
||||
*/
|
||||
|
||||
#include "seckey.h"
|
||||
#include "misc.h"
|
||||
|
||||
NAMESPACE_BEGIN(CryptoPP)
|
||||
|
||||
template <class T>
|
||||
struct MDC_Info : public FixedBlockSize<T::DIGESTSIZE>, public FixedKeyLength<T::BLOCKSIZE>
|
||||
{
|
||||
static std::string StaticAlgorithmName() {return std::string("MDC/")+T::StaticAlgorithmName();}
|
||||
};
|
||||
|
||||
//! <a href="http://www.weidai.com/scan-mirror/cs.html#MDC">MDC</a>
|
||||
/*! a construction by Peter Gutmann to turn an iterated hash function into a PRF */
|
||||
template <class T>
|
||||
class MDC : public MDC_Info<T>
|
||||
{
|
||||
class Enc : public BlockCipherBaseTemplate<MDC_Info<T> >
|
||||
{
|
||||
typedef typename T::HashWordType HashWordType;
|
||||
|
||||
public:
|
||||
void UncheckedSetKey(CipherDir direction, const byte *userKey, unsigned int length)
|
||||
{
|
||||
assert(direction == ENCRYPTION);
|
||||
this->AssertValidKeyLength(length);
|
||||
memcpy(Key(), userKey, this->KEYLENGTH);
|
||||
T::CorrectEndianess(Key(), Key(), this->KEYLENGTH);
|
||||
}
|
||||
|
||||
void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const
|
||||
{
|
||||
T::CorrectEndianess(Buffer(), (HashWordType *)inBlock, this->BLOCKSIZE);
|
||||
T::Transform(Buffer(), Key());
|
||||
if (xorBlock)
|
||||
{
|
||||
T::CorrectEndianess(Buffer(), Buffer(), this->BLOCKSIZE);
|
||||
xorbuf(outBlock, xorBlock, m_buffer, this->BLOCKSIZE);
|
||||
}
|
||||
else
|
||||
T::CorrectEndianess((HashWordType *)outBlock, Buffer(), this->BLOCKSIZE);
|
||||
}
|
||||
|
||||
bool IsPermutation() const {return false;}
|
||||
|
||||
unsigned int GetAlignment() const {return sizeof(HashWordType);}
|
||||
|
||||
private:
|
||||
HashWordType *Key() {return (HashWordType *)m_key.data();}
|
||||
const HashWordType *Key() const {return (const HashWordType *)m_key.data();}
|
||||
HashWordType *Buffer() const {return (HashWordType *)m_buffer.data();}
|
||||
|
||||
// VC60 workaround: bug triggered if using FixedSizeAllocatorWithCleanup
|
||||
FixedSizeSecBlock<byte, MDC_Info<T>::KEYLENGTH, AllocatorWithCleanup<byte> > m_key;
|
||||
mutable FixedSizeSecBlock<byte, MDC_Info<T>::BLOCKSIZE, AllocatorWithCleanup<byte> > m_buffer;
|
||||
};
|
||||
|
||||
public:
|
||||
//! use BlockCipher interface
|
||||
typedef BlockCipherTemplate<ENCRYPTION, Enc> Encryption;
|
||||
};
|
||||
|
||||
NAMESPACE_END
|
||||
|
||||
#endif
|
||||
@@ -1,105 +0,0 @@
|
||||
// modes.cpp - written and placed in the public domain by Wei Dai
|
||||
|
||||
#include "pch.h"
|
||||
#include "modes.h"
|
||||
|
||||
#include "strciphr.cpp"
|
||||
|
||||
NAMESPACE_BEGIN(CryptoPP)
|
||||
|
||||
// explicit instantiations for Darwin gcc-932.1
|
||||
template class CFB_CipherTemplate<AbstractPolicyHolder<CFB_CipherAbstractPolicy, SymmetricCipher> >;
|
||||
template class CFB_EncryptionTemplate<>;
|
||||
template class CFB_DecryptionTemplate<>;
|
||||
template class AdditiveCipherTemplate<>;
|
||||
template class CFB_CipherTemplate<AbstractPolicyHolder<CFB_CipherAbstractPolicy, CFB_ModePolicy> >;
|
||||
template class CFB_EncryptionTemplate<AbstractPolicyHolder<CFB_CipherAbstractPolicy, CFB_ModePolicy> >;
|
||||
template class CFB_DecryptionTemplate<AbstractPolicyHolder<CFB_CipherAbstractPolicy, CFB_ModePolicy> >;
|
||||
|
||||
void CipherModeBase::SetKey(const byte *key, unsigned int length, const NameValuePairs ¶ms)
|
||||
{
|
||||
UncheckedSetKey(params, key, length); // the underlying cipher will check the key length
|
||||
}
|
||||
|
||||
void CipherModeBase::GetNextIV(byte *IV)
|
||||
{
|
||||
if (!IsForwardTransformation())
|
||||
throw NotImplemented("CipherModeBase: GetNextIV() must be called on an encryption object");
|
||||
|
||||
m_cipher->ProcessBlock(m_register);
|
||||
memcpy(IV, m_register, BlockSize());
|
||||
}
|
||||
|
||||
void CipherModeBase::SetIV(const byte *iv)
|
||||
{
|
||||
if (iv)
|
||||
Resynchronize(iv);
|
||||
else if (IsResynchronizable())
|
||||
{
|
||||
if (!CanUseStructuredIVs())
|
||||
throw InvalidArgument("CipherModeBase: this cipher mode cannot use a null IV");
|
||||
|
||||
// use all zeros as default IV
|
||||
SecByteBlock iv(BlockSize());
|
||||
memset(iv, 0, iv.size());
|
||||
Resynchronize(iv);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void IncrementCounterByOne(byte *inout, unsigned int s)
|
||||
{
|
||||
for (int i=s-1, carry=1; i>=0 && carry; i--)
|
||||
carry = !++inout[i];
|
||||
}
|
||||
|
||||
static inline void IncrementCounterByOne(byte *output, const byte *input, unsigned int s)
|
||||
{
|
||||
for (int i=s-1, carry=1; i>=0; i--)
|
||||
carry = !(output[i] = input[i]+carry) && carry;
|
||||
}
|
||||
|
||||
void BlockOrientedCipherModeBase::UncheckedSetKey(const NameValuePairs ¶ms, const byte *key, unsigned int length)
|
||||
{
|
||||
m_cipher->SetKey(key, length, params);
|
||||
ResizeBuffers();
|
||||
const byte *iv = params.GetValueWithDefault(Name::IV(), (const byte *)NULL);
|
||||
SetIV(iv);
|
||||
}
|
||||
|
||||
void BlockOrientedCipherModeBase::ProcessData(byte *outString, const byte *inString, unsigned int length)
|
||||
{
|
||||
unsigned int s = BlockSize();
|
||||
assert(length % s == 0);
|
||||
unsigned int alignment = m_cipher->BlockAlignment();
|
||||
bool inputAlignmentOk = !RequireAlignedInput() || IsAlignedOn(inString, alignment);
|
||||
|
||||
if (IsAlignedOn(outString, alignment))
|
||||
{
|
||||
if (inputAlignmentOk)
|
||||
ProcessBlocks(outString, inString, length / s);
|
||||
else
|
||||
{
|
||||
memcpy(outString, inString, length);
|
||||
ProcessBlocks(outString, outString, length / s);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
while (length)
|
||||
{
|
||||
if (inputAlignmentOk)
|
||||
ProcessBlocks(m_buffer, inString, 1);
|
||||
else
|
||||
{
|
||||
memcpy(m_buffer, inString, s);
|
||||
ProcessBlocks(m_buffer, m_buffer, 1);
|
||||
}
|
||||
memcpy(outString, m_buffer, s);
|
||||
inString += s;
|
||||
outString += s;
|
||||
length -= s;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
NAMESPACE_END
|
||||
@@ -1,199 +0,0 @@
|
||||
#ifndef CRYPTOPP_MODES_H
|
||||
#define CRYPTOPP_MODES_H
|
||||
|
||||
/*! \file
|
||||
*/
|
||||
|
||||
#include "cryptlib.h"
|
||||
#include "secblock.h"
|
||||
#include "misc.h"
|
||||
#include "strciphr.h"
|
||||
#include "argnames.h"
|
||||
#include "algparam.h"
|
||||
|
||||
NAMESPACE_BEGIN(CryptoPP)
|
||||
|
||||
//! Cipher mode documentation. See NIST SP 800-38A for definitions of these modes.
|
||||
|
||||
/*! Each class derived from this one defines two types, Encryption and Decryption,
|
||||
both of which implement the SymmetricCipher interface.
|
||||
For each mode there are two classes, one of which is a template class,
|
||||
and the other one has a name that ends in "_ExternalCipher".
|
||||
The "external cipher" mode objects hold a reference to the underlying block cipher,
|
||||
instead of holding an instance of it. The reference must be passed in to the constructor.
|
||||
For the "cipher holder" classes, the CIPHER template parameter should be a class
|
||||
derived from BlockCipherDocumentation, for example DES or AES.
|
||||
*/
|
||||
struct CipherModeDocumentation : public SymmetricCipherDocumentation
|
||||
{
|
||||
};
|
||||
|
||||
class CipherModeBase : public SymmetricCipher
|
||||
{
|
||||
public:
|
||||
unsigned int MinKeyLength() const {return m_cipher->MinKeyLength();}
|
||||
unsigned int MaxKeyLength() const {return m_cipher->MaxKeyLength();}
|
||||
unsigned int DefaultKeyLength() const {return m_cipher->DefaultKeyLength();}
|
||||
unsigned int GetValidKeyLength(unsigned int n) const {return m_cipher->GetValidKeyLength(n);}
|
||||
bool IsValidKeyLength(unsigned int n) const {return m_cipher->IsValidKeyLength(n);}
|
||||
|
||||
void SetKey(const byte *key, unsigned int length, const NameValuePairs ¶ms = g_nullNameValuePairs);
|
||||
|
||||
unsigned int OptimalDataAlignment() const {return BlockSize();}
|
||||
|
||||
unsigned int IVSize() const {return BlockSize();}
|
||||
void GetNextIV(byte *IV);
|
||||
virtual IV_Requirement IVRequirement() const =0;
|
||||
|
||||
protected:
|
||||
inline unsigned int BlockSize() const {assert(m_register.size() > 0); return m_register.size();}
|
||||
void SetIV(const byte *iv);
|
||||
virtual void SetFeedbackSize(unsigned int feedbackSize)
|
||||
{
|
||||
if (!(feedbackSize == 0 || feedbackSize == BlockSize()))
|
||||
throw InvalidArgument("CipherModeBase: feedback size cannot be specified for this cipher mode");
|
||||
}
|
||||
virtual void ResizeBuffers()
|
||||
{
|
||||
m_register.New(m_cipher->BlockSize());
|
||||
}
|
||||
virtual void UncheckedSetKey(const NameValuePairs ¶ms, const byte *key, unsigned int length) =0;
|
||||
|
||||
BlockCipher *m_cipher;
|
||||
SecByteBlock m_register;
|
||||
};
|
||||
|
||||
template <class POLICY_INTERFACE>
|
||||
class ModePolicyCommonTemplate : public CipherModeBase, public POLICY_INTERFACE
|
||||
{
|
||||
unsigned int GetAlignment() const {return m_cipher->BlockAlignment();}
|
||||
void CipherSetKey(const NameValuePairs ¶ms, const byte *key, unsigned int length)
|
||||
{
|
||||
m_cipher->SetKey(key, length, params);
|
||||
ResizeBuffers();
|
||||
int feedbackSize = params.GetIntValueWithDefault(Name::FeedbackSize(), 0);
|
||||
SetFeedbackSize(feedbackSize);
|
||||
const byte *iv = params.GetValueWithDefault(Name::IV(), (const byte *)NULL);
|
||||
SetIV(iv);
|
||||
}
|
||||
};
|
||||
|
||||
class CFB_ModePolicy : public ModePolicyCommonTemplate<CFB_CipherAbstractPolicy>
|
||||
{
|
||||
public:
|
||||
IV_Requirement IVRequirement() const {return RANDOM_IV;}
|
||||
|
||||
protected:
|
||||
unsigned int GetBytesPerIteration() const {return m_feedbackSize;}
|
||||
byte * GetRegisterBegin() {return m_register + BlockSize() - m_feedbackSize;}
|
||||
void TransformRegister()
|
||||
{
|
||||
m_cipher->ProcessBlock(m_register, m_temp);
|
||||
memmove(m_register, m_register+m_feedbackSize, BlockSize()-m_feedbackSize);
|
||||
memcpy(m_register+BlockSize()-m_feedbackSize, m_temp, m_feedbackSize);
|
||||
}
|
||||
void CipherResynchronize(const byte *iv)
|
||||
{
|
||||
memcpy(m_register, iv, BlockSize());
|
||||
TransformRegister();
|
||||
}
|
||||
void SetFeedbackSize(unsigned int feedbackSize)
|
||||
{
|
||||
if (feedbackSize > BlockSize())
|
||||
throw InvalidArgument("CFB_Mode: invalid feedback size");
|
||||
m_feedbackSize = feedbackSize ? feedbackSize : BlockSize();
|
||||
}
|
||||
void ResizeBuffers()
|
||||
{
|
||||
CipherModeBase::ResizeBuffers();
|
||||
m_temp.New(BlockSize());
|
||||
}
|
||||
|
||||
SecByteBlock m_temp;
|
||||
unsigned int m_feedbackSize;
|
||||
};
|
||||
|
||||
class BlockOrientedCipherModeBase : public CipherModeBase
|
||||
{
|
||||
public:
|
||||
void UncheckedSetKey(const NameValuePairs ¶ms, const byte *key, unsigned int length);
|
||||
unsigned int MandatoryBlockSize() const {return BlockSize();}
|
||||
bool IsRandomAccess() const {return false;}
|
||||
bool IsSelfInverting() const {return false;}
|
||||
bool IsForwardTransformation() const {return m_cipher->IsForwardTransformation();}
|
||||
void Resynchronize(const byte *iv) {memcpy(m_register, iv, BlockSize());}
|
||||
void ProcessData(byte *outString, const byte *inString, unsigned int length);
|
||||
|
||||
protected:
|
||||
bool RequireAlignedInput() const {return true;}
|
||||
virtual void ProcessBlocks(byte *outString, const byte *inString, unsigned int numberOfBlocks) =0;
|
||||
void ResizeBuffers()
|
||||
{
|
||||
CipherModeBase::ResizeBuffers();
|
||||
m_buffer.New(BlockSize());
|
||||
}
|
||||
|
||||
SecByteBlock m_buffer;
|
||||
};
|
||||
|
||||
class CBC_ModeBase : public BlockOrientedCipherModeBase
|
||||
{
|
||||
public:
|
||||
IV_Requirement IVRequirement() const {return UNPREDICTABLE_RANDOM_IV;}
|
||||
bool RequireAlignedInput() const {return false;}
|
||||
unsigned int MinLastBlockSize() const {return 0;}
|
||||
};
|
||||
|
||||
class CBC_Encryption : public CBC_ModeBase
|
||||
{
|
||||
public:
|
||||
void ProcessBlocks(byte *outString, const byte *inString, unsigned int numberOfBlocks);
|
||||
};
|
||||
|
||||
class CBC_Decryption : public CBC_ModeBase
|
||||
{
|
||||
public:
|
||||
void ProcessBlocks(byte *outString, const byte *inString, unsigned int numberOfBlocks);
|
||||
|
||||
protected:
|
||||
void ResizeBuffers()
|
||||
{
|
||||
BlockOrientedCipherModeBase::ResizeBuffers();
|
||||
m_temp.New(BlockSize());
|
||||
}
|
||||
SecByteBlock m_temp;
|
||||
};
|
||||
|
||||
//! .
|
||||
template <class CIPHER, class BASE>
|
||||
class CipherModeFinalTemplate_CipherHolder : public ObjectHolder<CIPHER>, public BASE
|
||||
{
|
||||
public:
|
||||
CipherModeFinalTemplate_CipherHolder()
|
||||
{
|
||||
this->m_cipher = &this->m_object;
|
||||
this->ResizeBuffers();
|
||||
}
|
||||
CipherModeFinalTemplate_CipherHolder(const byte *key, unsigned int length)
|
||||
{
|
||||
this->m_cipher = &this->m_object;
|
||||
this->SetKey(key, length);
|
||||
}
|
||||
CipherModeFinalTemplate_CipherHolder(const byte *key, unsigned int length, const byte *iv, int feedbackSize = 0)
|
||||
{
|
||||
this->m_cipher = &this->m_object;
|
||||
this->SetKey(key, length, MakeParameters("IV", iv)("FeedbackSize", feedbackSize));
|
||||
}
|
||||
};
|
||||
|
||||
//! CFB mode
|
||||
template <class CIPHER>
|
||||
struct CFB_Mode : public CipherModeDocumentation
|
||||
{
|
||||
typedef CipherModeFinalTemplate_CipherHolder<CPP_TYPENAME CIPHER::Encryption, ConcretePolicyHolder<Empty, CFB_EncryptionTemplate<AbstractPolicyHolder<CFB_CipherAbstractPolicy, CFB_ModePolicy> > > > Encryption;
|
||||
typedef CipherModeFinalTemplate_CipherHolder<CPP_TYPENAME CIPHER::Encryption, ConcretePolicyHolder<Empty, CFB_DecryptionTemplate<AbstractPolicyHolder<CFB_CipherAbstractPolicy, CFB_ModePolicy> > > > Decryption;
|
||||
};
|
||||
|
||||
NAMESPACE_END
|
||||
|
||||
#endif
|
||||
@@ -139,38 +139,6 @@ void BlockingRng::GenerateBlock(byte *output, unsigned int size)
|
||||
|
||||
#endif
|
||||
|
||||
// *************************************************************
|
||||
|
||||
void OS_GenerateRandomBlock(bool blocking, byte *output, unsigned int size)
|
||||
{
|
||||
#ifdef NONBLOCKING_RNG_AVAILABLE
|
||||
if (blocking)
|
||||
#endif
|
||||
{
|
||||
#ifdef BLOCKING_RNG_AVAILABLE
|
||||
BlockingRng rng;
|
||||
rng.GenerateBlock(output, size);
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef BLOCKING_RNG_AVAILABLE
|
||||
if (!blocking)
|
||||
#endif
|
||||
{
|
||||
#ifdef NONBLOCKING_RNG_AVAILABLE
|
||||
NonblockingRng rng;
|
||||
rng.GenerateBlock(output, size);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
void AutoSeededRandomPool::Reseed(bool blocking, unsigned int seedSize)
|
||||
{
|
||||
SecByteBlock seed(seedSize);
|
||||
OS_GenerateRandomBlock(blocking, seed, seedSize);
|
||||
Put(seed, seedSize);
|
||||
}
|
||||
|
||||
NAMESPACE_END
|
||||
|
||||
#endif
|
||||
|
||||
@@ -76,19 +76,6 @@ protected:
|
||||
|
||||
#endif
|
||||
|
||||
void OS_GenerateRandomBlock(bool blocking, byte *output, unsigned int size);
|
||||
|
||||
//! Automaticly Seeded Randomness Pool
|
||||
/*! This class seeds itself using an operating system provided RNG. */
|
||||
class AutoSeededRandomPool : public RandomPool
|
||||
{
|
||||
public:
|
||||
//! blocking will be ignored if the prefered RNG isn't available
|
||||
explicit AutoSeededRandomPool(bool blocking = false, unsigned int seedSize = 32)
|
||||
{Reseed(blocking, seedSize);}
|
||||
void Reseed(bool blocking = false, unsigned int seedSize = 32);
|
||||
};
|
||||
|
||||
NAMESPACE_END
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,99 +0,0 @@
|
||||
// randpool.cpp - written and placed in the public domain by Wei Dai
|
||||
// The algorithm in this module comes from PGP's randpool.c
|
||||
|
||||
#include "pch.h"
|
||||
#include "randpool.h"
|
||||
#include "mdc.h"
|
||||
#include "sha.h"
|
||||
#include "modes.h"
|
||||
|
||||
NAMESPACE_BEGIN(CryptoPP)
|
||||
|
||||
typedef MDC<SHA> RandomPoolCipher;
|
||||
|
||||
RandomPool::RandomPool(unsigned int poolSize)
|
||||
: pool(poolSize), key(RandomPoolCipher::DEFAULT_KEYLENGTH)
|
||||
{
|
||||
assert(poolSize > key.size());
|
||||
|
||||
addPos=0;
|
||||
getPos=poolSize;
|
||||
memset(pool, 0, poolSize);
|
||||
memset(key, 0, key.size());
|
||||
}
|
||||
|
||||
void RandomPool::Stir()
|
||||
{
|
||||
CFB_Mode<RandomPoolCipher>::Encryption cipher;
|
||||
|
||||
for (int i=0; i<2; i++)
|
||||
{
|
||||
cipher.SetKeyWithIV(key, key.size(), pool.end()-cipher.IVSize());
|
||||
cipher.ProcessString(pool, pool.size());
|
||||
memcpy(key, pool, key.size());
|
||||
}
|
||||
|
||||
addPos = 0;
|
||||
getPos = key.size();
|
||||
}
|
||||
|
||||
unsigned int RandomPool::Put2(const byte *inString, unsigned int length, int messageEnd, bool blocking)
|
||||
{
|
||||
unsigned t;
|
||||
|
||||
while (length > (t = pool.size() - addPos))
|
||||
{
|
||||
xorbuf(pool+addPos, inString, t);
|
||||
inString += t;
|
||||
length -= t;
|
||||
Stir();
|
||||
}
|
||||
|
||||
if (length)
|
||||
{
|
||||
xorbuf(pool+addPos, inString, length);
|
||||
addPos += length;
|
||||
getPos = pool.size(); // Force stir on get
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned int RandomPool::TransferTo2(BufferedTransformation &target, unsigned long &transferBytes, const std::string &channel, bool blocking)
|
||||
{
|
||||
ASSERT( blocking );
|
||||
|
||||
unsigned int t;
|
||||
unsigned long size = transferBytes;
|
||||
|
||||
while (size > (t = pool.size() - getPos))
|
||||
{
|
||||
target.ChannelPut(channel, pool+getPos, t);
|
||||
size -= t;
|
||||
Stir();
|
||||
}
|
||||
|
||||
if (size)
|
||||
{
|
||||
target.ChannelPut(channel, pool+getPos, size);
|
||||
getPos += size;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
byte RandomPool::GenerateByte()
|
||||
{
|
||||
if (getPos == pool.size())
|
||||
Stir();
|
||||
|
||||
return pool[getPos++];
|
||||
}
|
||||
|
||||
void RandomPool::GenerateBlock(byte *outString, unsigned int size)
|
||||
{
|
||||
ArraySink sink(outString, size);
|
||||
TransferTo(sink, size);
|
||||
}
|
||||
|
||||
NAMESPACE_END
|
||||
@@ -1,46 +0,0 @@
|
||||
#ifndef CRYPTOPP_RANDPOOL_H
|
||||
#define CRYPTOPP_RANDPOOL_H
|
||||
|
||||
#include "cryptlib.h"
|
||||
#include "filters.h"
|
||||
|
||||
NAMESPACE_BEGIN(CryptoPP)
|
||||
|
||||
//! Randomness Pool
|
||||
/*! This class can be used to generate
|
||||
pseudorandom bytes after seeding the pool with
|
||||
the Put() methods */
|
||||
class RandomPool : public RandomNumberGenerator,
|
||||
public Bufferless<BufferedTransformation>
|
||||
{
|
||||
public:
|
||||
//! poolSize must be greater than 16
|
||||
RandomPool(unsigned int poolSize=384);
|
||||
|
||||
unsigned int Put2(const byte *begin, unsigned int, int messageEnd, bool blocking);
|
||||
|
||||
bool AnyRetrievable() const {return true;}
|
||||
unsigned long MaxRetrievable() const {return ULONG_MAX;}
|
||||
|
||||
unsigned int TransferTo2(BufferedTransformation &target, unsigned long &transferBytes, const std::string &channel=NULL_CHANNEL, bool blocking=true);
|
||||
unsigned int CopyRangeTo2(BufferedTransformation &target, unsigned long &begin, unsigned long end=ULONG_MAX, const std::string &channel=NULL_CHANNEL, bool blocking=true) const
|
||||
{
|
||||
throw NotImplemented("RandomPool: CopyRangeTo2() is not supported by this store");
|
||||
}
|
||||
|
||||
byte GenerateByte();
|
||||
void GenerateBlock(byte *output, unsigned int size);
|
||||
|
||||
void IsolatedInitialize(const NameValuePairs ¶meters) {}
|
||||
|
||||
protected:
|
||||
void Stir();
|
||||
|
||||
private:
|
||||
SecByteBlock pool, key;
|
||||
unsigned int addPos, getPos;
|
||||
};
|
||||
|
||||
NAMESPACE_END
|
||||
|
||||
#endif
|
||||
@@ -1,188 +0,0 @@
|
||||
// strciphr.cpp - written and placed in the public domain by Wei Dai
|
||||
|
||||
#include "pch.h"
|
||||
#include "strciphr.h"
|
||||
|
||||
NAMESPACE_BEGIN(CryptoPP)
|
||||
|
||||
template <class S>
|
||||
byte AdditiveCipherTemplate<S>::GenerateByte()
|
||||
{
|
||||
PolicyInterface &policy = this->AccessPolicy();
|
||||
|
||||
if (m_leftOver == 0)
|
||||
{
|
||||
policy.WriteKeystream(m_buffer, policy.GetIterationsToBuffer());
|
||||
m_leftOver = policy.GetBytesPerIteration();
|
||||
}
|
||||
|
||||
return *(KeystreamBufferEnd()-m_leftOver--);
|
||||
}
|
||||
|
||||
template <class S>
|
||||
inline void AdditiveCipherTemplate<S>::ProcessData(byte *outString, const byte *inString, unsigned int length)
|
||||
{
|
||||
if (m_leftOver > 0)
|
||||
{
|
||||
unsigned int len = STDMIN(m_leftOver, length);
|
||||
xorbuf(outString, inString, KeystreamBufferEnd()-m_leftOver, len);
|
||||
length -= len;
|
||||
m_leftOver -= len;
|
||||
inString += len;
|
||||
outString += len;
|
||||
}
|
||||
|
||||
if (!length)
|
||||
return;
|
||||
|
||||
assert(m_leftOver == 0);
|
||||
|
||||
PolicyInterface &policy = this->AccessPolicy();
|
||||
unsigned int bytesPerIteration = policy.GetBytesPerIteration();
|
||||
unsigned int alignment = policy.GetAlignment();
|
||||
|
||||
if (policy.CanOperateKeystream() && length >= bytesPerIteration && IsAlignedOn(outString, alignment))
|
||||
{
|
||||
if (IsAlignedOn(inString, alignment))
|
||||
policy.OperateKeystream(XOR_KEYSTREAM, outString, inString, length / bytesPerIteration);
|
||||
else
|
||||
{
|
||||
memcpy(outString, inString, length);
|
||||
policy.OperateKeystream(XOR_KEYSTREAM_INPLACE, outString, outString, length / bytesPerIteration);
|
||||
}
|
||||
inString += length - length % bytesPerIteration;
|
||||
outString += length - length % bytesPerIteration;
|
||||
length %= bytesPerIteration;
|
||||
|
||||
if (!length)
|
||||
return;
|
||||
}
|
||||
|
||||
unsigned int bufferByteSize = GetBufferByteSize(policy);
|
||||
unsigned int bufferIterations = policy.GetIterationsToBuffer();
|
||||
|
||||
while (length >= bufferByteSize)
|
||||
{
|
||||
policy.WriteKeystream(m_buffer, bufferIterations);
|
||||
xorbuf(outString, inString, KeystreamBufferBegin(), bufferByteSize);
|
||||
length -= bufferByteSize;
|
||||
inString += bufferByteSize;
|
||||
outString += bufferByteSize;
|
||||
}
|
||||
|
||||
if (length > 0)
|
||||
{
|
||||
policy.WriteKeystream(m_buffer, bufferIterations);
|
||||
xorbuf(outString, inString, KeystreamBufferBegin(), length);
|
||||
m_leftOver = bytesPerIteration - length;
|
||||
}
|
||||
}
|
||||
|
||||
template <class S>
|
||||
void AdditiveCipherTemplate<S>::Resynchronize(const byte *iv)
|
||||
{
|
||||
PolicyInterface &policy = this->AccessPolicy();
|
||||
m_leftOver = 0;
|
||||
m_buffer.New(GetBufferByteSize(policy));
|
||||
policy.CipherResynchronize(m_buffer, iv);
|
||||
}
|
||||
|
||||
template <class BASE>
|
||||
void AdditiveCipherTemplate<BASE>::Seek(dword position)
|
||||
{
|
||||
PolicyInterface &policy = this->AccessPolicy();
|
||||
unsigned int bytesPerIteration = policy.GetBytesPerIteration();
|
||||
|
||||
policy.SeekToIteration(position / bytesPerIteration);
|
||||
position %= bytesPerIteration;
|
||||
|
||||
if (position > 0)
|
||||
{
|
||||
policy.WriteKeystream(m_buffer, 1);
|
||||
m_leftOver = bytesPerIteration - (unsigned int)position;
|
||||
}
|
||||
else
|
||||
m_leftOver = 0;
|
||||
}
|
||||
|
||||
template <class BASE>
|
||||
void CFB_CipherTemplate<BASE>::Resynchronize(const byte *iv)
|
||||
{
|
||||
PolicyInterface &policy = this->AccessPolicy();
|
||||
policy.CipherResynchronize(iv);
|
||||
m_leftOver = policy.GetBytesPerIteration();
|
||||
}
|
||||
|
||||
template <class BASE>
|
||||
void CFB_CipherTemplate<BASE>::ProcessData(byte *outString, const byte *inString, unsigned int length)
|
||||
{
|
||||
PolicyInterface &policy = this->AccessPolicy();
|
||||
unsigned int bytesPerIteration = policy.GetBytesPerIteration();
|
||||
unsigned int alignment = policy.GetAlignment();
|
||||
byte *reg = policy.GetRegisterBegin();
|
||||
|
||||
if (m_leftOver)
|
||||
{
|
||||
unsigned int len = STDMIN(m_leftOver, length);
|
||||
CombineMessageAndShiftRegister(outString, reg + bytesPerIteration - m_leftOver, inString, len);
|
||||
m_leftOver -= len;
|
||||
length -= len;
|
||||
inString += len;
|
||||
outString += len;
|
||||
}
|
||||
|
||||
if (!length)
|
||||
return;
|
||||
|
||||
assert(m_leftOver == 0);
|
||||
|
||||
if (policy.CanIterate() && length >= bytesPerIteration && IsAlignedOn(outString, alignment))
|
||||
{
|
||||
if (IsAlignedOn(inString, alignment))
|
||||
policy.Iterate(outString, inString, GetCipherDir(*this), length / bytesPerIteration);
|
||||
else
|
||||
{
|
||||
memcpy(outString, inString, length);
|
||||
policy.Iterate(outString, outString, GetCipherDir(*this), length / bytesPerIteration);
|
||||
}
|
||||
inString += length - length % bytesPerIteration;
|
||||
outString += length - length % bytesPerIteration;
|
||||
length %= bytesPerIteration;
|
||||
}
|
||||
|
||||
while (length >= bytesPerIteration)
|
||||
{
|
||||
policy.TransformRegister();
|
||||
CombineMessageAndShiftRegister(outString, reg, inString, bytesPerIteration);
|
||||
length -= bytesPerIteration;
|
||||
inString += bytesPerIteration;
|
||||
outString += bytesPerIteration;
|
||||
}
|
||||
|
||||
if (length > 0)
|
||||
{
|
||||
policy.TransformRegister();
|
||||
CombineMessageAndShiftRegister(outString, reg, inString, length);
|
||||
m_leftOver = bytesPerIteration - length;
|
||||
}
|
||||
}
|
||||
|
||||
template <class BASE>
|
||||
void CFB_EncryptionTemplate<BASE>::CombineMessageAndShiftRegister(byte *output, byte *reg, const byte *message, unsigned int length)
|
||||
{
|
||||
xorbuf(reg, message, length);
|
||||
memcpy(output, reg, length);
|
||||
}
|
||||
|
||||
template <class BASE>
|
||||
void CFB_DecryptionTemplate<BASE>::CombineMessageAndShiftRegister(byte *output, byte *reg, const byte *message, unsigned int length)
|
||||
{
|
||||
for (unsigned int i=0; i<length; i++)
|
||||
{
|
||||
byte b = message[i];
|
||||
output[i] = reg[i] ^ b;
|
||||
reg[i] = b;
|
||||
}
|
||||
}
|
||||
|
||||
NAMESPACE_END
|
||||
@@ -1,288 +0,0 @@
|
||||
/*! \file
|
||||
This file contains helper classes for implementing stream ciphers.
|
||||
|
||||
All this infrastructure may look very complex compared to what's in Crypto++ 4.x,
|
||||
but stream ciphers implementations now support a lot of new functionality,
|
||||
including better performance (minimizing copying), resetting of keys and IVs, and methods to
|
||||
query which features are supported by a cipher.
|
||||
|
||||
Here's an explanation of these classes. The word "policy" is used here to mean a class with a
|
||||
set of methods that must be implemented by individual stream cipher implementations.
|
||||
This is usually much simpler than the full stream cipher API, which is implemented by
|
||||
either AdditiveCipherTemplate or CFB_CipherTemplate using the policy. So for example, an
|
||||
implementation of SEAL only needs to implement the AdditiveCipherAbstractPolicy interface
|
||||
(since it's an additive cipher, i.e., it xors a keystream into the plaintext).
|
||||
See this line in seal.h:
|
||||
|
||||
typedef SymmetricCipherFinalTemplate<ConcretePolicyHolder<SEAL_Policy<B>, AdditiveCipherTemplate<> > > Encryption;
|
||||
|
||||
AdditiveCipherTemplate and CFB_CipherTemplate are designed so that they don't need
|
||||
to take a policy class as a template parameter (although this is allowed), so that
|
||||
their code is not duplicated for each new cipher. Instead they each
|
||||
get a reference to an abstract policy interface by calling AccessPolicy() on itself, so
|
||||
AccessPolicy() must be overriden to return the actual policy reference. This is done
|
||||
by the ConceretePolicyHolder class. Finally, SymmetricCipherFinalTemplate implements the constructors and
|
||||
other functions that must be implemented by the most derived class.
|
||||
*/
|
||||
|
||||
#ifndef CRYPTOPP_STRCIPHR_H
|
||||
#define CRYPTOPP_STRCIPHR_H
|
||||
|
||||
#include "seckey.h"
|
||||
#include "secblock.h"
|
||||
|
||||
NAMESPACE_BEGIN(CryptoPP)
|
||||
|
||||
template <class POLICY_INTERFACE, class BASE = Empty>
|
||||
class AbstractPolicyHolder : public BASE
|
||||
{
|
||||
public:
|
||||
typedef POLICY_INTERFACE PolicyInterface;
|
||||
|
||||
protected:
|
||||
virtual const POLICY_INTERFACE & GetPolicy() const =0;
|
||||
virtual POLICY_INTERFACE & AccessPolicy() =0;
|
||||
};
|
||||
|
||||
template <class POLICY, class BASE, class POLICY_INTERFACE = CPP_TYPENAME BASE::PolicyInterface>
|
||||
class ConcretePolicyHolder : public BASE, protected POLICY
|
||||
{
|
||||
protected:
|
||||
const POLICY_INTERFACE & GetPolicy() const {return *this;}
|
||||
POLICY_INTERFACE & AccessPolicy() {return *this;}
|
||||
};
|
||||
|
||||
enum KeystreamOperation {WRITE_KEYSTREAM, XOR_KEYSTREAM, XOR_KEYSTREAM_INPLACE};
|
||||
|
||||
struct AdditiveCipherAbstractPolicy
|
||||
{
|
||||
virtual unsigned int GetAlignment() const =0;
|
||||
virtual unsigned int GetBytesPerIteration() const =0;
|
||||
virtual unsigned int GetIterationsToBuffer() const =0;
|
||||
virtual void WriteKeystream(byte *keystreamBuffer, unsigned int iterationCount) =0;
|
||||
virtual bool CanOperateKeystream() const {return false;}
|
||||
virtual void OperateKeystream(KeystreamOperation operation, byte *output, const byte *input, unsigned int iterationCount) {assert(false);}
|
||||
virtual void CipherSetKey(const NameValuePairs ¶ms, const byte *key, unsigned int length) =0;
|
||||
virtual void CipherResynchronize(byte *keystreamBuffer, const byte *iv) {throw NotImplemented("StreamTransformation: this object doesn't support resynchronization");}
|
||||
virtual bool IsRandomAccess() const =0;
|
||||
virtual void SeekToIteration(dword iterationCount) {assert(!IsRandomAccess()); throw NotImplemented("StreamTransformation: this object doesn't support random access");}
|
||||
};
|
||||
|
||||
template <typename WT, unsigned int W, unsigned int X = 1, class BASE = AdditiveCipherAbstractPolicy>
|
||||
struct AdditiveCipherConcretePolicy : public BASE
|
||||
{
|
||||
typedef WT WordType;
|
||||
|
||||
unsigned int GetAlignment() const {return sizeof(WordType);}
|
||||
unsigned int GetBytesPerIteration() const {return sizeof(WordType) * W;}
|
||||
unsigned int GetIterationsToBuffer() const {return X;}
|
||||
void WriteKeystream(byte *buffer, unsigned int iterationCount)
|
||||
{OperateKeystream(WRITE_KEYSTREAM, buffer, NULL, iterationCount);}
|
||||
bool CanOperateKeystream() const {return true;}
|
||||
virtual void OperateKeystream(KeystreamOperation operation, byte *output, const byte *input, unsigned int iterationCount) =0;
|
||||
|
||||
template <class B>
|
||||
struct KeystreamOutput
|
||||
{
|
||||
KeystreamOutput(KeystreamOperation operation, byte *output, const byte *input)
|
||||
: m_operation(operation), m_output(output), m_input(input) {}
|
||||
|
||||
inline KeystreamOutput & operator()(WordType keystreamWord)
|
||||
{
|
||||
assert(IsAligned<WordType>(m_input));
|
||||
assert(IsAligned<WordType>(m_output));
|
||||
|
||||
if (!NativeByteOrderIs(B::ToEnum()))
|
||||
keystreamWord = ByteReverse(keystreamWord);
|
||||
|
||||
if (m_operation == WRITE_KEYSTREAM)
|
||||
*(WordType*)m_output = keystreamWord;
|
||||
else if (m_operation == XOR_KEYSTREAM)
|
||||
{
|
||||
*(WordType*)m_output = keystreamWord ^ *(WordType*)m_input;
|
||||
m_input += sizeof(WordType);
|
||||
}
|
||||
else if (m_operation == XOR_KEYSTREAM_INPLACE)
|
||||
*(WordType*)m_output ^= keystreamWord;
|
||||
|
||||
m_output += sizeof(WordType);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
KeystreamOperation m_operation;
|
||||
byte *m_output;
|
||||
const byte *m_input;
|
||||
};
|
||||
};
|
||||
|
||||
template <class BASE = AbstractPolicyHolder<AdditiveCipherAbstractPolicy, TwoBases<SymmetricCipher, RandomNumberGenerator> > >
|
||||
class AdditiveCipherTemplate : public BASE
|
||||
{
|
||||
public:
|
||||
byte GenerateByte();
|
||||
void ProcessData(byte *outString, const byte *inString, unsigned int length);
|
||||
void Resynchronize(const byte *iv);
|
||||
unsigned int OptimalBlockSize() const {return this->GetPolicy().GetBytesPerIteration();}
|
||||
unsigned int GetOptimalNextBlockSize() const {return m_leftOver;}
|
||||
unsigned int OptimalDataAlignment() const {return this->GetPolicy().GetAlignment();}
|
||||
bool IsSelfInverting() const {return true;}
|
||||
bool IsForwardTransformation() const {return true;}
|
||||
bool IsRandomAccess() const {return this->GetPolicy().IsRandomAccess();}
|
||||
void Seek(dword position);
|
||||
|
||||
typedef typename BASE::PolicyInterface PolicyInterface;
|
||||
|
||||
protected:
|
||||
void UncheckedSetKey(const NameValuePairs ¶ms, const byte *key, unsigned int length);
|
||||
|
||||
unsigned int GetBufferByteSize(const PolicyInterface &policy) const {return policy.GetBytesPerIteration() * policy.GetIterationsToBuffer();}
|
||||
|
||||
inline byte * KeystreamBufferBegin() {return m_buffer.data();}
|
||||
inline byte * KeystreamBufferEnd() {return (m_buffer.data() + m_buffer.size());}
|
||||
|
||||
SecByteBlock m_buffer;
|
||||
unsigned int m_leftOver;
|
||||
};
|
||||
|
||||
struct CFB_CipherAbstractPolicy
|
||||
{
|
||||
virtual unsigned int GetAlignment() const =0;
|
||||
virtual unsigned int GetBytesPerIteration() const =0;
|
||||
virtual byte * GetRegisterBegin() =0;
|
||||
virtual void TransformRegister() =0;
|
||||
virtual bool CanIterate() const {return false;}
|
||||
virtual void Iterate(byte *output, const byte *input, CipherDir dir, unsigned int iterationCount) {assert(false);}
|
||||
virtual void CipherSetKey(const NameValuePairs ¶ms, const byte *key, unsigned int length) =0;
|
||||
virtual void CipherResynchronize(const byte *iv) {throw NotImplemented("StreamTransformation: this object doesn't support resynchronization");}
|
||||
};
|
||||
|
||||
template <typename WT, unsigned int W, class BASE = CFB_CipherAbstractPolicy>
|
||||
struct CFB_CipherConcretePolicy : public BASE
|
||||
{
|
||||
typedef WT WordType;
|
||||
|
||||
unsigned int GetAlignment() const {return sizeof(WordType);}
|
||||
unsigned int GetBytesPerIteration() const {return sizeof(WordType) * W;}
|
||||
bool CanIterate() const {return true;}
|
||||
void TransformRegister() {this->Iterate(NULL, NULL, ENCRYPTION, 1);}
|
||||
|
||||
template <class B>
|
||||
struct RegisterOutput
|
||||
{
|
||||
RegisterOutput(byte *output, const byte *input, CipherDir dir)
|
||||
: m_output(output), m_input(input), m_dir(dir) {}
|
||||
|
||||
inline RegisterOutput& operator()(WordType ®isterWord)
|
||||
{
|
||||
assert(IsAligned<WordType>(m_output));
|
||||
assert(IsAligned<WordType>(m_input));
|
||||
|
||||
if (!NativeByteOrderIs(B::ToEnum()))
|
||||
registerWord = ByteReverse(registerWord);
|
||||
|
||||
if (m_dir == ENCRYPTION)
|
||||
{
|
||||
WordType ct = *(const WordType *)m_input ^ registerWord;
|
||||
registerWord = ct;
|
||||
*(WordType*)m_output = ct;
|
||||
m_input += sizeof(WordType);
|
||||
m_output += sizeof(WordType);
|
||||
}
|
||||
else
|
||||
{
|
||||
WordType ct = *(const WordType *)m_input;
|
||||
*(WordType*)m_output = registerWord ^ ct;
|
||||
registerWord = ct;
|
||||
m_input += sizeof(WordType);
|
||||
m_output += sizeof(WordType);
|
||||
}
|
||||
|
||||
// registerWord is left unreversed so it can be xor-ed with further input
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
byte *m_output;
|
||||
const byte *m_input;
|
||||
CipherDir m_dir;
|
||||
};
|
||||
};
|
||||
|
||||
template <class BASE>
|
||||
class CFB_CipherTemplate : public BASE
|
||||
{
|
||||
public:
|
||||
void ProcessData(byte *outString, const byte *inString, unsigned int length);
|
||||
void Resynchronize(const byte *iv);
|
||||
unsigned int OptimalBlockSize() const {return this->GetPolicy().GetBytesPerIteration();}
|
||||
unsigned int GetOptimalNextBlockSize() const {return m_leftOver;}
|
||||
unsigned int OptimalDataAlignment() const {return this->GetPolicy().GetAlignment();}
|
||||
bool IsRandomAccess() const {return false;}
|
||||
bool IsSelfInverting() const {return false;}
|
||||
|
||||
typedef typename BASE::PolicyInterface PolicyInterface;
|
||||
|
||||
protected:
|
||||
virtual void CombineMessageAndShiftRegister(byte *output, byte *reg, const byte *message, unsigned int length) =0;
|
||||
|
||||
void UncheckedSetKey(const NameValuePairs ¶ms, const byte *key, unsigned int length);
|
||||
|
||||
unsigned int m_leftOver;
|
||||
};
|
||||
|
||||
template <class BASE = AbstractPolicyHolder<CFB_CipherAbstractPolicy, SymmetricCipher> >
|
||||
class CFB_EncryptionTemplate : public CFB_CipherTemplate<BASE>
|
||||
{
|
||||
bool IsForwardTransformation() const {return true;}
|
||||
void CombineMessageAndShiftRegister(byte *output, byte *reg, const byte *message, unsigned int length);
|
||||
};
|
||||
|
||||
template <class BASE = AbstractPolicyHolder<CFB_CipherAbstractPolicy, SymmetricCipher> >
|
||||
class CFB_DecryptionTemplate : public CFB_CipherTemplate<BASE>
|
||||
{
|
||||
bool IsForwardTransformation() const {return false;}
|
||||
void CombineMessageAndShiftRegister(byte *output, byte *reg, const byte *message, unsigned int length);
|
||||
};
|
||||
|
||||
template <class BASE, class INFO = BASE>
|
||||
class SymmetricCipherFinalTemplate : public AlgorithmImpl<SimpleKeyingInterfaceImpl<BASE, INFO>, INFO>
|
||||
{
|
||||
public:
|
||||
SymmetricCipherFinalTemplate() {}
|
||||
SymmetricCipherFinalTemplate(const byte *key)
|
||||
{SetKey(key, this->DEFAULT_KEYLENGTH);}
|
||||
SymmetricCipherFinalTemplate(const byte *key, unsigned int length)
|
||||
{SetKey(key, length);}
|
||||
SymmetricCipherFinalTemplate(const byte *key, unsigned int length, const byte *iv)
|
||||
{SetKey(key, length); this->Resynchronize(iv);}
|
||||
|
||||
void SetKey(const byte *key, unsigned int length, const NameValuePairs ¶ms = g_nullNameValuePairs)
|
||||
{
|
||||
this->ThrowIfInvalidKeyLength(length);
|
||||
this->UncheckedSetKey(params, key, length);
|
||||
}
|
||||
|
||||
Clonable * Clone() const {return static_cast<SymmetricCipher *>(new SymmetricCipherFinalTemplate<BASE, INFO>(*this));}
|
||||
};
|
||||
|
||||
template <class S>
|
||||
void AdditiveCipherTemplate<S>::UncheckedSetKey(const NameValuePairs ¶ms, const byte *key, unsigned int length)
|
||||
{
|
||||
PolicyInterface &policy = this->AccessPolicy();
|
||||
policy.CipherSetKey(params, key, length);
|
||||
m_buffer.New(GetBufferByteSize(policy));
|
||||
m_leftOver = 0;
|
||||
}
|
||||
|
||||
template <class BASE>
|
||||
void CFB_CipherTemplate<BASE>::UncheckedSetKey(const NameValuePairs ¶ms, const byte *key, unsigned int length)
|
||||
{
|
||||
PolicyInterface &policy = this->AccessPolicy();
|
||||
policy.CipherSetKey(params, key, length);
|
||||
m_leftOver = policy.GetBytesPerIteration();
|
||||
}
|
||||
|
||||
NAMESPACE_END
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user