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
|
#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
|
NAMESPACE_END
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -76,19 +76,6 @@ protected:
|
|||||||
|
|
||||||
#endif
|
#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
|
NAMESPACE_END
|
||||||
|
|
||||||
#endif
|
#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