remove unused stuff

This commit is contained in:
Glenn Maynard
2005-01-16 00:23:08 +00:00
parent 8ef0fff740
commit b573ab428f
9 changed files with 0 additions and 1042 deletions
-72
View File
@@ -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
-105
View File
@@ -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 &params)
{
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 &params, 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
-199
View File
@@ -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 &params = 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 &params, 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 &params, 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 &params, 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
-32
View File
@@ -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
-13
View File
@@ -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
-99
View File
@@ -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
-46
View File
@@ -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 &parameters) {}
protected:
void Stir();
private:
SecByteBlock pool, key;
unsigned int addPos, getPos;
};
NAMESPACE_END
#endif
-188
View File
@@ -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
-288
View File
@@ -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 &params, 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 &params, 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 &params, 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 &registerWord)
{
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 &params, 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 &params = 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 &params, 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 &params, const byte *key, unsigned int length)
{
PolicyInterface &policy = this->AccessPolicy();
policy.CipherSetKey(params, key, length);
m_leftOver = policy.GetBytesPerIteration();
}
NAMESPACE_END
#endif