strciphr.cpp
// strciphr.cpp - written and placed in the public domain by Wei Dai
#include "pch.h"
#ifndef CRYPTOPP_IMPORTS
#include "strciphr.h"
NAMESPACE_BEGIN(CryptoPP)
template <class S>
void AdditiveCipherTemplate<S>::UncheckedSetKey(const byte *key, unsigned int length, const NameValuePairs &params)
{
PolicyInterface &policy = this->AccessPolicy();
policy.CipherSetKey(params, key, length);
m_leftOver = 0;
unsigned int bufferByteSize = policy.CanOperateKeystream() ? GetBufferByteSize(policy) : RoundUpToMultipleOf(1024U, GetBufferByteSize(policy));
m_buffer.New(bufferByteSize);
if (this->IsResynchronizable())
{
size_t ivLength;
const byte *iv = this->GetIVAndThrowIfInvalid(params, ivLength);
policy.CipherResynchronize(m_buffer, iv, ivLength);
}
}
template <class S>
void AdditiveCipherTemplate<S>::GenerateBlock(byte *outString, size_t length)
{
if (m_leftOver > 0)
{
size_t len = STDMIN(m_leftOver, length);
memcpy(outString, KeystreamBufferEnd()-m_leftOver, len);
length -= len;
m_leftOver -= len;
outString += len;
if (!length)
return;
}
assert(m_leftOver == 0);
PolicyInterface &policy = this->AccessPolicy();
unsigned int bytesPerIteration = policy.GetBytesPerIteration();
if (length >= bytesPerIteration)
{
size_t iterations = length / bytesPerIteration;
policy.WriteKeystream(outString, iterations);
outString += iterations * bytesPerIteration;
length -= iterations * bytesPerIteration;
}
if (length > 0)
{
size_t bufferByteSize = RoundUpToMultipleOf(length, bytesPerIteration);
size_t bufferIterations = bufferByteSize / bytesPerIteration;
policy.WriteKeystream(KeystreamBufferEnd()-bufferByteSize, bufferIterations);
memcpy(outString, KeystreamBufferEnd()-bufferByteSize, length);
m_leftOver = bufferByteSize - length;
}
}
template <class S>
void AdditiveCipherTemplate<S>::ProcessData(byte *outString, const byte *inString, size_t length)
{
if (m_leftOver > 0)
{
size_t 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();
if (policy.CanOperateKeystream() && length >= bytesPerIteration)
{
size_t iterations = length / bytesPerIteration;
unsigned int alignment = policy.GetAlignment();
KeystreamOperation operation = KeystreamOperation((IsAlignedOn(inString, alignment) * 2) | (int)IsAlignedOn(outString, alignment));
policy.OperateKeystream(operation, outString, inString, iterations);
inString += iterations * bytesPerIteration;
outString += iterations * bytesPerIteration;
length -= iterations * bytesPerIteration;
if (!length)
return;
}
size_t bufferByteSize = m_buffer.size();
size_t bufferIterations = bufferByteSize / bytesPerIteration;
while (length >= bufferByteSize)
{
policy.WriteKeystream(m_buffer, bufferIterations);
xorbuf(outString, inString, KeystreamBufferBegin(), bufferByteSize);
length -= bufferByteSize;
inString += bufferByteSize;
outString += bufferByteSize;
}
if (length > 0)
{
bufferByteSize = RoundUpToMultipleOf(length, bytesPerIteration);
bufferIterations = bufferByteSize / bytesPerIteration;
policy.WriteKeystream(KeystreamBufferEnd()-bufferByteSize, bufferIterations);
xorbuf(outString, inString, KeystreamBufferEnd()-bufferByteSize, length);
m_leftOver = bufferByteSize - length;
}
}
template <class S>
void AdditiveCipherTemplate<S>::Resynchronize(const byte *iv, int length)
{
PolicyInterface &policy = this->AccessPolicy();
m_leftOver = 0;
m_buffer.New(GetBufferByteSize(policy));
policy.CipherResynchronize(m_buffer, iv, this->ThrowIfInvalidIVLength(length));
}
template <class BASE>
void AdditiveCipherTemplate<BASE>::Seek(lword position)
{
PolicyInterface &policy = this->AccessPolicy();
unsigned int bytesPerIteration = policy.GetBytesPerIteration();
policy.SeekToIteration(position / bytesPerIteration);
position %= bytesPerIteration;
if (position > 0)
{
policy.WriteKeystream(KeystreamBufferEnd()-bytesPerIteration, 1);
m_leftOver = bytesPerIteration - (unsigned int)position;
}
else
m_leftOver = 0;
}
template <class BASE>
void CFB_CipherTemplate<BASE>::UncheckedSetKey(const byte *key, unsigned int length, const NameValuePairs &params)
{
PolicyInterface &policy = this->AccessPolicy();
policy.CipherSetKey(params, key, length);
if (this->IsResynchronizable())
{
size_t ivLength;
const byte *iv = this->GetIVAndThrowIfInvalid(params, ivLength);
policy.CipherResynchronize(iv, ivLength);
}
m_leftOver = policy.GetBytesPerIteration();
}
template <class BASE>
void CFB_CipherTemplate<BASE>::Resynchronize(const byte *iv, int length)
{
PolicyInterface &policy = this->AccessPolicy();
policy.CipherResynchronize(iv, this->ThrowIfInvalidIVLength(length));
m_leftOver = policy.GetBytesPerIteration();
}
template <class BASE>
void CFB_CipherTemplate<BASE>::ProcessData(byte *outString, const byte *inString, size_t length)
{
assert(length % this->MandatoryBlockSize() == 0);
PolicyInterface &policy = this->AccessPolicy();
unsigned int bytesPerIteration = policy.GetBytesPerIteration();
unsigned int alignment = policy.GetAlignment();
byte *reg = policy.GetRegisterBegin();
if (m_leftOver)
{
size_t 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, size_t length)
{
xorbuf(reg, message, length);
memcpy(output, reg, length);
}
template <class BASE>
void CFB_DecryptionTemplate<BASE>::CombineMessageAndShiftRegister(byte *output, byte *reg, const byte *message, size_t length)
{
for (unsigned int i=0; i<length; i++)
{
byte b = message[i];
output[i] = reg[i] ^ b;
reg[i] = b;
}
}
NAMESPACE_END
#endif
AdditiveCipherTemplate::Resynchronize
void Resynchronize(const byte *iv, int length=-1)
Resynchronize the cipher.
Definition: strciphr.cpp:126
AdditiveCipherAbstractPolicy::CipherSetKey
virtual void CipherSetKey(const NameValuePairs &params, const byte *key, size_t length)=0
Key the cipher.
AdditiveCipherAbstractPolicy::OperateKeystream
virtual void OperateKeystream(KeystreamOperation operation, byte *output, const byte *input, size_t iterationCount)
Operates the keystream.
Definition: strciphr.h:153
CFB_CipherTemplate
Base class for feedback based stream ciphers with SymmetricCipher interface.
Definition: strciphr.h:487
AdditiveCipherAbstractPolicy::CanOperateKeystream
virtual bool CanOperateKeystream() const
Flag indicating.
Definition: strciphr.h:143
AdditiveCipherAbstractPolicy::WriteKeystream
virtual void WriteKeystream(byte *keystream, size_t iterationCount)
Generate the keystream.
Definition: strciphr.h:137
AdditiveCipherTemplate::Seek
void Seek(lword position)
Seeks to a random position in the stream.
Definition: strciphr.cpp:135
AdditiveCipherAbstractPolicy
Policy object for additive stream ciphers.
Definition: strciphr.h:108
IsAlignedOn
bool IsAlignedOn(const void *ptr, unsigned int alignment)
Determines whether ptr is aligned to a minimum value.
Definition: misc.h:907
AdditiveCipherTemplate::ProcessData
void ProcessData(byte *outString, const byte *inString, size_t length)
Apply keystream to data.
Definition: strciphr.cpp:67
CFB_DecryptionTemplate
Base class for feedback based stream ciphers in the reverse direction with SymmetricCipher interface...
Definition: strciphr.h:560
CFB_CipherTemplate::ProcessData
void ProcessData(byte *outString, const byte *inString, size_t length)
Apply keystream to data.
Definition: strciphr.cpp:177
AdditiveCipherAbstractPolicy::GetAlignment
virtual unsigned int GetAlignment() const
Provides data alignment requirements.
Definition: strciphr.h:116
AdditiveCipherAbstractPolicy::GetBytesPerIteration
virtual unsigned int GetBytesPerIteration() const =0
Provides number of bytes operated upon during an iteration.
AdditiveCipherAbstractPolicy::SeekToIteration
virtual void SeekToIteration(lword iterationCount)
Seeks to a random position in the stream.
Definition: strciphr.h:177
GetCipherDir
CipherDir GetCipherDir(const T &obj)
Returns the direction the cipher is being operated.
Definition: misc.h:992
CFB_EncryptionTemplate
Base class for feedback based stream ciphers in the forward direction with SymmetricCipher interface...
Definition: strciphr.h:550
AdditiveCipherTemplate::GenerateBlock
void GenerateBlock(byte *output, size_t size)
Generate random array of bytes.
Definition: strciphr.cpp:29
STDMIN
const T & STDMIN(const T &a, const T &b)
Replacement function for std::min.
Definition: misc.h:467
strciphr.h
Classes for implementing stream ciphers.
xorbuf
void xorbuf(byte *buf, const byte *mask, size_t count)
Performs an XOR of a buffer with a mask.
Definition: misc.cpp:28
AdditiveCipherAbstractPolicy::CipherResynchronize
virtual void CipherResynchronize(byte *keystreamBuffer, const byte *iv, size_t length)
Resynchronize the cipher.
Definition: strciphr.h:166
RoundUpToMultipleOf
T1 RoundUpToMultipleOf(const T1 &n, const T2 &m)
Rounds a value up to a multiple of a second value.
Definition: misc.h:865
KeystreamOperation
KeystreamOperation
Keystream operation flags.
Definition: strciphr.h:92
CryptoPP
Crypto++ library namespace.
CFB_CipherTemplate::Resynchronize
void Resynchronize(const byte *iv, int length=-1)
Resynchronize the cipher.
Definition: strciphr.cpp:169
AdditiveCipherTemplate
Base class for additive stream ciphers with SymmetricCipher interface.
Definition: strciphr.h:269
NameValuePairs
Interface for retrieving values given their names.
Definition: cryptlib.h:277