bug fixes

pull/2/head
weidai 2002-10-06 03:23:16 +00:00
parent 1e45c2d305
commit eee814871a
5 changed files with 682 additions and 695 deletions

View File

@ -1,11 +1,11 @@
// files.cpp - written and placed in the public domain by Wei Dai
// files.cpp - written and placed in the public domain by Wei Dai
#include "pch.h"
#include "files.h"
NAMESPACE_BEGIN(CryptoPP)
using namespace std;
using namespace std;
void Files_TestInstantiations()
{
@ -20,7 +20,7 @@ void FileStore::StoreInitialize(const NameValuePairs &parameters)
if (parameters.GetValue("InputFileName", fileName))
{
ios::openmode binary = parameters.GetValueWithDefault("InputBinaryMode", true) ? ios::binary : ios::openmode(0);
m_file.open(fileName, ios::in | binary);
m_file.open(fileName, ios::in | binary);
if (!m_file)
throw OpenErr(fileName);
m_stream = &m_file;
@ -30,7 +30,7 @@ void FileStore::StoreInitialize(const NameValuePairs &parameters)
m_stream = NULL;
parameters.GetValue("InputStreamPointer", m_stream);
}
m_waiting = false;
m_waiting = false;
}
unsigned long FileStore::MaxRetrievable() const
@ -38,57 +38,42 @@ unsigned long FileStore::MaxRetrievable() const
if (!m_stream)
return 0;
streampos current = m_stream->tellg();
streampos end = m_stream->seekg(0, ios::end).tellg();
streampos current = m_stream->tellg();
streampos end = m_stream->seekg(0, ios::end).tellg();
m_stream->seekg(current);
return end-current;
}
unsigned int FileStore::Peek(byte &outByte) const
{
if (!m_stream)
return 0;
int result = m_stream->peek();
if (result == EOF) // GCC workaround: 2.95.2 doesn't have char_traits<char>::eof()
return 0;
else
{
outByte = byte(result);
return 1;
}
}
unsigned int FileStore::TransferTo2(BufferedTransformation &target, unsigned long &transferBytes, const std::string &channel, bool blocking)
unsigned int FileStore::TransferTo2(BufferedTransformation &target, unsigned long &transferBytes, const std::string &channel, bool blocking)
{
if (!m_stream)
{
transferBytes = 0;
transferBytes = 0;
return 0;
}
unsigned long size=transferBytes;
transferBytes = 0;
transferBytes = 0;
if (m_waiting)
goto output;
while (size && m_stream->good())
while (size && m_stream->good())
{
{
unsigned int spaceSize = 1024;
m_space = HelpCreatePutSpace(target, channel, 1, (unsigned int)STDMIN(size, (unsigned long)UINT_MAX), spaceSize);
m_space = HelpCreatePutSpace(target, channel, 1, (unsigned int)STDMIN(size, (unsigned long)UINT_MAX), spaceSize);
m_stream->read((char *)m_space, STDMIN(size, (unsigned long)spaceSize));
m_stream->read((char *)m_space, STDMIN(size, (unsigned long)spaceSize));
}
m_len = m_stream->gcount();
m_len = m_stream->gcount();
unsigned int blockedBytes;
output:
blockedBytes = target.ChannelPutModifiable2(channel, m_space, m_len, 0, blocking);
m_waiting = blockedBytes > 0;
blockedBytes = target.ChannelPutModifiable2(channel, m_space, m_len, 0, blocking);
m_waiting = blockedBytes > 0;
if (m_waiting)
return blockedBytes;
size -= m_len;
size -= m_len;
transferBytes += m_len;
}
@ -98,28 +83,41 @@ output:
return 0;
}
unsigned int FileStore::CopyRangeTo2(BufferedTransformation &target, unsigned long &begin, unsigned long end, const std::string &channel, bool blocking) const
unsigned int FileStore::CopyRangeTo2(BufferedTransformation &target, unsigned long &begin, unsigned long end, const std::string &channel, bool blocking) const
{
if (!m_stream)
return 0;
// TODO: figure out what happens on cin
streampos current = m_stream->tellg();
streampos endPosition = m_stream->seekg(0, ios::end).tellg();
streampos newPosition = current + (streamoff)begin;
if (begin == 0 && end == 1)
{
int result = m_stream->peek();
if (result == EOF) // GCC workaround: 2.95.2 doesn't have char_traits<char>::eof()
return 0;
else
{
unsigned int blockedBytes = target.ChannelPut(channel, byte(result), blocking);
begin += 1-blockedBytes;
return blockedBytes;
}
}
if (newPosition >= endPosition)
// TODO: figure out what happens on cin
streampos current = m_stream->tellg();
streampos endPosition = m_stream->seekg(0, ios::end).tellg();
streampos newPosition = current + (streamoff)begin;
if (newPosition >= endPosition)
{
m_stream->seekg(current);
return 0; // don't try to seek beyond the end of file
return 0; // don't try to seek beyond the end of file
}
m_stream->seekg(newPosition);
unsigned long total = 0;
unsigned long total = 0;
try
{
assert(!m_waiting);
unsigned long copyMax = end-begin;
unsigned int blockedBytes = const_cast<FileStore *>(this)->TransferTo2(target, copyMax, channel, blocking);
unsigned long copyMax = end-begin;
unsigned int blockedBytes = const_cast<FileStore *>(this)->TransferTo2(target, copyMax, channel, blocking);
begin += copyMax;
if (blockedBytes)
{
@ -139,13 +137,13 @@ unsigned int FileStore::CopyRangeTo2(BufferedTransformation &target, unsigned lo
return 0;
}
void FileSink::IsolatedInitialize(const NameValuePairs &parameters)
void FileSink::IsolatedInitialize(const NameValuePairs &parameters)
{
const char *fileName;
if (parameters.GetValue("OutputFileName", fileName))
{
ios::openmode binary = parameters.GetValueWithDefault("OutputBinaryMode", true) ? ios::binary : ios::openmode(0);
m_file.open(fileName, ios::out | ios::trunc | binary);
ios::openmode binary = parameters.GetValueWithDefault("OutputBinaryMode", true) ? ios::binary : ios::openmode(0);
m_file.open(fileName, ios::out | ios::trunc | binary);
if (!m_file)
throw OpenErr(fileName);
m_stream = &m_file;
@ -160,27 +158,27 @@ void FileSink::IsolatedInitialize(const NameValuePairs &parameters)
bool FileSink::IsolatedFlush(bool hardFlush, bool blocking)
{
if (!m_stream)
throw Err("FileSink: output stream not opened");
throw Err("FileSink: output stream not opened");
m_stream->flush();
if (!m_stream->good())
throw WriteErr();
throw WriteErr();
return false;
}
unsigned int FileSink::Put2(const byte *inString, unsigned int length, int messageEnd, bool blocking)
unsigned int FileSink::Put2(const byte *inString, unsigned int length, int messageEnd, bool blocking)
{
if (!m_stream)
throw Err("FileSink: output stream not opened");
throw Err("FileSink: output stream not opened");
m_stream->write((const char *)inString, length);
m_stream->write((const char *)inString, length);
if (messageEnd)
m_stream->flush();
if (!m_stream->good())
throw WriteErr();
throw WriteErr();
return 0;
}

66
files.h
View File

@ -1,5 +1,5 @@
#ifndef CRYPTOPP_FILES_H
#define CRYPTOPP_FILES_H
#ifndef CRYPTOPP_FILES_H
#define CRYPTOPP_FILES_H
#include "cryptlib.h"
#include "filters.h"
@ -9,31 +9,29 @@
NAMESPACE_BEGIN(CryptoPP)
//! .
class FileStore : public Store, private FilterPutSpaceHelper
//! .
class FileStore : public Store, private FilterPutSpaceHelper
{
public:
class Err : public Exception
class Err : public Exception
{
public:
Err(const std::string &s) : Exception(IO_ERROR, s) {}
Err(const std::string &s) : Exception(IO_ERROR, s) {}
};
class OpenErr : public Err {public: OpenErr(const std::string &filename) : Err("FileStore: error opening file for reading: " + filename) {}};
class ReadErr : public Err {public: ReadErr() : Err("FileStore: error reading file") {}};
class OpenErr : public Err {public: OpenErr(const std::string &filename) : Err("FileStore: error opening file for reading: " + filename) {}};
class ReadErr : public Err {public: ReadErr() : Err("FileStore: error reading file") {}};
FileStore() : m_stream(NULL) {}
FileStore() : m_stream(NULL) {}
FileStore(std::istream &in)
{StoreInitialize(MakeParameters("InputStreamPointer", &in));}
FileStore(const char *filename)
FileStore(const char *filename)
{StoreInitialize(MakeParameters("InputFileName", filename));}
std::istream* GetStream() {return m_stream;}
unsigned long MaxRetrievable() const;
unsigned int Peek(byte &outByte) const;
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;
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;
private:
void StoreInitialize(const NameValuePairs &parameters);
@ -45,47 +43,47 @@ private:
bool m_waiting;
};
//! .
//! .
class FileSource : public SourceTemplate<FileStore>
{
public:
typedef FileStore::Err Err;
typedef FileStore::OpenErr OpenErr;
typedef FileStore::ReadErr ReadErr;
typedef FileStore::Err Err;
typedef FileStore::OpenErr OpenErr;
typedef FileStore::ReadErr ReadErr;
FileSource(BufferedTransformation *attachment = NULL)
: SourceTemplate<FileStore>(attachment) {}
FileSource(std::istream &in, bool pumpAll, BufferedTransformation *attachment = NULL)
: SourceTemplate<FileStore>(attachment) {SourceInitialize(pumpAll, MakeParameters("InputStreamPointer", &in));}
FileSource(const char *filename, bool pumpAll, BufferedTransformation *attachment = NULL, bool binary=true)
: SourceTemplate<FileStore>(attachment) {SourceInitialize(pumpAll, MakeParameters("InputFileName", filename)("InputBinaryMode", binary));}
FileSource(BufferedTransformation *attachment = NULL)
: SourceTemplate<FileStore>(attachment) {}
FileSource(std::istream &in, bool pumpAll, BufferedTransformation *attachment = NULL)
: SourceTemplate<FileStore>(attachment) {SourceInitialize(pumpAll, MakeParameters("InputStreamPointer", &in));}
FileSource(const char *filename, bool pumpAll, BufferedTransformation *attachment = NULL, bool binary=true)
: SourceTemplate<FileStore>(attachment) {SourceInitialize(pumpAll, MakeParameters("InputFileName", filename)("InputBinaryMode", binary));}
std::istream* GetStream() {return m_store.GetStream();}
};
//! .
class FileSink : public Sink
//! .
class FileSink : public Sink
{
public:
class Err : public Exception
class Err : public Exception
{
public:
Err(const std::string &s) : Exception(IO_ERROR, s) {}
Err(const std::string &s) : Exception(IO_ERROR, s) {}
};
class OpenErr : public Err {public: OpenErr(const std::string &filename) : Err("FileSink: error opening file for writing: " + filename) {}};
class WriteErr : public Err {public: WriteErr() : Err("FileSink: error writing file") {}};
class OpenErr : public Err {public: OpenErr(const std::string &filename) : Err("FileSink: error opening file for writing: " + filename) {}};
class WriteErr : public Err {public: WriteErr() : Err("FileSink: error writing file") {}};
FileSink() : m_stream(NULL) {}
FileSink() : m_stream(NULL) {}
FileSink(std::ostream &out)
{IsolatedInitialize(MakeParameters("OutputStreamPointer", &out));}
FileSink(const char *filename, bool binary=true)
FileSink(const char *filename, bool binary=true)
{IsolatedInitialize(MakeParameters("OutputFileName", filename)("OutputBinaryMode", binary));}
std::ostream* GetStream() {return m_stream;}
void IsolatedInitialize(const NameValuePairs &parameters);
unsigned int Put2(const byte *inString, unsigned int length, int messageEnd, bool blocking);
bool IsolatedFlush(bool hardFlush, bool blocking);
unsigned int Put2(const byte *inString, unsigned int length, int messageEnd, bool blocking);
bool IsolatedFlush(bool hardFlush, bool blocking);
private:
std::ofstream m_file;

View File

@ -1,4 +1,4 @@
// filters.cpp - written and placed in the public domain by Wei Dai
// filters.cpp - written and placed in the public domain by Wei Dai
#include "pch.h"
#include "filters.h"
@ -11,11 +11,11 @@
NAMESPACE_BEGIN(CryptoPP)
Filter::Filter(BufferedTransformation *attachment)
: m_attachment(attachment), m_continueAt(0)
: m_attachment(attachment), m_continueAt(0)
{
}
BufferedTransformation * Filter::NewDefaultAttachment() const
BufferedTransformation * Filter::NewDefaultAttachment() const
{
return new MessageQueue;
}
@ -47,24 +47,24 @@ void Filter::Insert(Filter *filter)
NotifyAttachmentChange();
}
unsigned int Filter::CopyRangeTo2(BufferedTransformation &target, unsigned long &begin, unsigned long end, const std::string &channel, bool blocking) const
unsigned int Filter::CopyRangeTo2(BufferedTransformation &target, unsigned long &begin, unsigned long end, const std::string &channel, bool blocking) const
{
return AttachedTransformation()->CopyRangeTo2(target, begin, end, channel, blocking);
}
unsigned int Filter::TransferTo2(BufferedTransformation &target, unsigned long &transferBytes, const std::string &channel, bool blocking)
unsigned int Filter::TransferTo2(BufferedTransformation &target, unsigned long &transferBytes, const std::string &channel, bool blocking)
{
return AttachedTransformation()->TransferTo2(target, transferBytes, channel, blocking);
return AttachedTransformation()->TransferTo2(target, transferBytes, channel, blocking);
}
void Filter::Initialize(const NameValuePairs &parameters, int propagation)
{
m_continueAt = 0;
IsolatedInitialize(parameters);
PropagateInitialize(parameters, propagation);
PropagateInitialize(parameters, propagation);
}
bool Filter::Flush(bool hardFlush, int propagation, bool blocking)
bool Filter::Flush(bool hardFlush, int propagation, bool blocking)
{
switch (m_continueAt)
{
@ -78,7 +78,7 @@ bool Filter::Flush(bool hardFlush, int propagation, bool blocking)
return false;
}
bool Filter::MessageSeriesEnd(int propagation, bool blocking)
bool Filter::MessageSeriesEnd(int propagation, bool blocking)
{
switch (m_continueAt)
{
@ -86,30 +86,30 @@ bool Filter::MessageSeriesEnd(int propagation, bool blocking)
if (IsolatedMessageSeriesEnd(blocking))
return true;
case 1:
if (ShouldPropagateMessageSeriesEnd() && OutputMessageSeriesEnd(1, propagation, blocking))
if (ShouldPropagateMessageSeriesEnd() && OutputMessageSeriesEnd(1, propagation, blocking))
return true;
}
return false;
}
void Filter::PropagateInitialize(const NameValuePairs &parameters, int propagation, const std::string &channel)
void Filter::PropagateInitialize(const NameValuePairs &parameters, int propagation, const std::string &channel)
{
if (propagation)
AttachedTransformation()->ChannelInitialize(channel, parameters, propagation-1);
}
unsigned int Filter::Output(int outputSite, const byte *inString, unsigned int length, int messageEnd, bool blocking, const std::string &channel)
unsigned int Filter::Output(int outputSite, const byte *inString, unsigned int length, int messageEnd, bool blocking, const std::string &channel)
{
if (messageEnd)
messageEnd--;
unsigned int result = AttachedTransformation()->Put2(inString, length, messageEnd, blocking);
m_continueAt = result ? outputSite : 0;
unsigned int result = AttachedTransformation()->Put2(inString, length, messageEnd, blocking);
m_continueAt = result ? outputSite : 0;
return result;
}
bool Filter::OutputFlush(int outputSite, bool hardFlush, int propagation, bool blocking, const std::string &channel)
{
if (propagation && AttachedTransformation()->ChannelFlush(channel, hardFlush, propagation-1, blocking))
if (propagation && AttachedTransformation()->ChannelFlush(channel, hardFlush, propagation-1, blocking))
{
m_continueAt = outputSite;
return true;
@ -118,9 +118,9 @@ bool Filter::OutputFlush(int outputSite, bool hardFlush, int propagation, bool b
return false;
}
bool Filter::OutputMessageSeriesEnd(int outputSite, int propagation, bool blocking, const std::string &channel)
bool Filter::OutputMessageSeriesEnd(int outputSite, int propagation, bool blocking, const std::string &channel)
{
if (propagation && AttachedTransformation()->ChannelMessageSeriesEnd(channel, propagation-1, blocking))
if (propagation && AttachedTransformation()->ChannelMessageSeriesEnd(channel, propagation-1, blocking))
{
m_continueAt = outputSite;
return true;
@ -131,27 +131,27 @@ bool Filter::OutputMessageSeriesEnd(int outputSite, int propagation, bool blocki
// *************************************************************
unsigned int MeterFilter::Put2(const byte *begin, unsigned int length, int messageEnd, bool blocking)
unsigned int MeterFilter::Put2(const byte *begin, unsigned int length, int messageEnd, bool blocking)
{
FILTER_BEGIN;
m_currentMessageBytes += length;
m_totalBytes += length;
m_totalBytes += length;
if (messageEnd)
{
m_currentMessageBytes = 0;
m_currentMessageBytes = 0;
m_currentSeriesMessages++;
m_totalMessages++;
}
FILTER_OUTPUT(1, begin, length, messageEnd);
FILTER_OUTPUT(1, begin, length, messageEnd);
FILTER_END;
}
bool MeterFilter::IsolatedMessageSeriesEnd(bool blocking)
bool MeterFilter::IsolatedMessageSeriesEnd(bool blocking)
{
m_currentMessageBytes = 0;
m_currentSeriesMessages = 0;
m_currentMessageBytes = 0;
m_currentSeriesMessages = 0;
m_totalMessageSeries++;
return false;
}
@ -161,19 +161,19 @@ bool MeterFilter::IsolatedMessageSeriesEnd(bool blocking)
void FilterWithBufferedInput::BlockQueue::ResetQueue(unsigned int blockSize, unsigned int maxBlocks)
{
m_buffer.New(blockSize * maxBlocks);
m_blockSize = blockSize;
m_maxBlocks = maxBlocks;
m_blockSize = blockSize;
m_maxBlocks = maxBlocks;
m_size = 0;
m_begin = m_buffer;
m_begin = m_buffer;
}
byte *FilterWithBufferedInput::BlockQueue::GetBlock()
{
if (m_size >= m_blockSize)
{
byte *ptr = m_begin;
byte *ptr = m_begin;
if ((m_begin+=m_blockSize) == m_buffer.end())
m_begin = m_buffer;
m_begin = m_buffer;
m_size -= m_blockSize;
return ptr;
}
@ -183,62 +183,62 @@ byte *FilterWithBufferedInput::BlockQueue::GetBlock()
byte *FilterWithBufferedInput::BlockQueue::GetContigousBlocks(unsigned int &numberOfBytes)
{
numberOfBytes = STDMIN(numberOfBytes, STDMIN((unsigned int)(m_buffer.end()-m_begin), m_size));
byte *ptr = m_begin;
m_begin += numberOfBytes;
numberOfBytes = STDMIN(numberOfBytes, STDMIN((unsigned int)(m_buffer.end()-m_begin), m_size));
byte *ptr = m_begin;
m_begin += numberOfBytes;
m_size -= numberOfBytes;
if (m_size == 0 || m_begin == m_buffer.end())
m_begin = m_buffer;
if (m_size == 0 || m_begin == m_buffer.end())
m_begin = m_buffer;
return ptr;
}
unsigned int FilterWithBufferedInput::BlockQueue::GetAll(byte *outString)
{
unsigned int size = m_size;
unsigned int size = m_size;
unsigned int numberOfBytes = m_maxBlocks*m_blockSize;
const byte *ptr = GetContigousBlocks(numberOfBytes);
const byte *ptr = GetContigousBlocks(numberOfBytes);
memcpy(outString, ptr, numberOfBytes);
memcpy(outString+numberOfBytes, m_begin, m_size);
memcpy(outString+numberOfBytes, m_begin, m_size);
m_size = 0;
return size;
}
void FilterWithBufferedInput::BlockQueue::Put(const byte *inString, unsigned int length)
void FilterWithBufferedInput::BlockQueue::Put(const byte *inString, unsigned int length)
{
assert(m_size + length <= m_buffer.size());
byte *end = (m_size < (unsigned int)(m_buffer.end()-m_begin)) ? m_begin + m_size : m_begin + m_size - m_buffer.size();
unsigned int len = STDMIN(length, (unsigned int)(m_buffer.end()-end));
memcpy(end, inString, len);
if (len < length)
assert(m_size + length <= m_buffer.size());
byte *end = (m_size < (unsigned int)(m_buffer.end()-m_begin)) ? m_begin + m_size : m_begin + m_size - m_buffer.size();
unsigned int len = STDMIN(length, (unsigned int)(m_buffer.end()-end));
memcpy(end, inString, len);
if (len < length)
memcpy(m_buffer, inString+len, length-len);
m_size += length;
}
FilterWithBufferedInput::FilterWithBufferedInput(BufferedTransformation *attachment)
FilterWithBufferedInput::FilterWithBufferedInput(BufferedTransformation *attachment)
: Filter(attachment)
{
}
FilterWithBufferedInput::FilterWithBufferedInput(unsigned int firstSize, unsigned int blockSize, unsigned int lastSize, BufferedTransformation *attachment)
FilterWithBufferedInput::FilterWithBufferedInput(unsigned int firstSize, unsigned int blockSize, unsigned int lastSize, BufferedTransformation *attachment)
: Filter(attachment), m_firstSize(firstSize), m_blockSize(blockSize), m_lastSize(lastSize)
, m_firstInputDone(false)
{
if (m_firstSize < 0 || m_blockSize < 1 || m_lastSize < 0)
throw InvalidArgument("FilterWithBufferedInput: invalid buffer size");
if (m_firstSize < 0 || m_blockSize < 1 || m_lastSize < 0)
throw InvalidArgument("FilterWithBufferedInput: invalid buffer size");
m_queue.ResetQueue(1, m_firstSize);
}
void FilterWithBufferedInput::IsolatedInitialize(const NameValuePairs &parameters)
{
InitializeDerivedAndReturnNewSizes(parameters, m_firstSize, m_blockSize, m_lastSize);
if (m_firstSize < 0 || m_blockSize < 1 || m_lastSize < 0)
throw InvalidArgument("FilterWithBufferedInput: invalid buffer size");
InitializeDerivedAndReturnNewSizes(parameters, m_firstSize, m_blockSize, m_lastSize);
if (m_firstSize < 0 || m_blockSize < 1 || m_lastSize < 0)
throw InvalidArgument("FilterWithBufferedInput: invalid buffer size");
m_queue.ResetQueue(1, m_firstSize);
m_firstInputDone = false;
}
bool FilterWithBufferedInput::IsolatedFlush(bool hardFlush, bool blocking)
bool FilterWithBufferedInput::IsolatedFlush(bool hardFlush, bool blocking)
{
if (!blocking)
throw BlockingInputOnly("FilterWithBufferedInput");
@ -264,37 +264,37 @@ unsigned int FilterWithBufferedInput::PutMaybeModifiable(byte *inString, unsigne
unsigned int len = m_firstSize - m_queue.CurrentSize();
m_queue.Put(inString, len);
FirstPut(m_queue.GetContigousBlocks(m_firstSize));
assert(m_queue.CurrentSize() == 0);
m_queue.ResetQueue(m_blockSize, (2*m_blockSize+m_lastSize-2)/m_blockSize);
assert(m_queue.CurrentSize() == 0);
m_queue.ResetQueue(m_blockSize, (2*m_blockSize+m_lastSize-2)/m_blockSize);
inString += len;
inString += len;
newLength -= m_firstSize;
m_firstInputDone = true;
}
if (m_firstInputDone)
{
if (m_blockSize == 1)
if (m_blockSize == 1)
{
while (newLength > m_lastSize && m_queue.CurrentSize() > 0)
{
unsigned int len = newLength - m_lastSize;
byte *ptr = m_queue.GetContigousBlocks(len);
byte *ptr = m_queue.GetContigousBlocks(len);
NextPutModifiable(ptr, len);
newLength -= len;
}
if (newLength > m_lastSize)
if (newLength > m_lastSize)
{
unsigned int len = newLength - m_lastSize;
NextPutMaybeModifiable(inString, len, modifiable);
inString += len;
inString += len;
newLength -= len;
}
}
else
{
while (newLength >= m_blockSize + m_lastSize && m_queue.CurrentSize() >= m_blockSize)
while (newLength >= m_blockSize + m_lastSize && m_queue.CurrentSize() >= m_blockSize)
{
NextPutModifiable(m_queue.GetBlock(), m_blockSize);
newLength -= m_blockSize;
@ -305,7 +305,7 @@ unsigned int FilterWithBufferedInput::PutMaybeModifiable(byte *inString, unsigne
assert(m_queue.CurrentSize() < m_blockSize);
unsigned int len = m_blockSize - m_queue.CurrentSize();
m_queue.Put(inString, len);
inString += len;
inString += len;
NextPutModifiable(m_queue.GetBlock(), m_blockSize);
newLength -= m_blockSize;
}
@ -314,13 +314,13 @@ unsigned int FilterWithBufferedInput::PutMaybeModifiable(byte *inString, unsigne
{
unsigned int len = RoundDownToMultipleOf(newLength - m_lastSize, m_blockSize);
NextPutMaybeModifiable(inString, len, modifiable);
inString += len;
inString += len;
newLength -= len;
}
}
}
m_queue.Put(inString, newLength - m_queue.CurrentSize());
m_queue.Put(inString, newLength - m_queue.CurrentSize());
}
if (messageEnd)
@ -335,7 +335,7 @@ unsigned int FilterWithBufferedInput::PutMaybeModifiable(byte *inString, unsigne
m_firstInputDone = false;
m_queue.ResetQueue(1, m_firstSize);
Output(1, NULL, 0, messageEnd, blocking);
Output(1, NULL, 0, messageEnd, blocking);
}
return 0;
}
@ -345,80 +345,72 @@ void FilterWithBufferedInput::ForceNextPut()
if (!m_firstInputDone)
return;
if (m_blockSize > 1)
if (m_blockSize > 1)
{
while (m_queue.CurrentSize() >= m_blockSize)
while (m_queue.CurrentSize() >= m_blockSize)
NextPutModifiable(m_queue.GetBlock(), m_blockSize);
}
else
{
unsigned int len;
while ((len = m_queue.CurrentSize()) > 0)
while ((len = m_queue.CurrentSize()) > 0)
NextPutModifiable(m_queue.GetContigousBlocks(len), len);
}
}
void FilterWithBufferedInput::NextPutMultiple(const byte *inString, unsigned int length)
void FilterWithBufferedInput::NextPutMultiple(const byte *inString, unsigned int length)
{
assert(m_blockSize > 1); // m_blockSize = 1 should always override this function
while (length > 0)
while (length > 0)
{
assert(length >= m_blockSize);
NextPutSingle(inString);
inString += m_blockSize;
inString += m_blockSize;
length -= m_blockSize;
}
}
// *************************************************************
void Redirector::ChannelInitialize(const std::string &channel, const NameValuePairs &parameters, int propagation)
void Redirector::ChannelInitialize(const std::string &channel, const NameValuePairs &parameters, int propagation)
{
if (channel.empty())
{
m_target = parameters.GetValueWithDefault("RedirectionTargetPointer", (BufferedTransformation*)NULL);
m_passSignal = parameters.GetValueWithDefault("PassSignal", true);
m_passSignal = parameters.GetValueWithDefault("PassSignal", true);
}
if (m_target && m_passSignal)
if (m_target && m_passSignal)
m_target->ChannelInitialize(channel, parameters, propagation);
}
// *************************************************************
ProxyFilter::ProxyFilter(BufferedTransformation *filter, unsigned int firstSize, unsigned int lastSize, BufferedTransformation *attachment)
: FilterWithBufferedInput(firstSize, 1, lastSize, attachment), m_filter(filter), m_proxy(NULL)
ProxyFilter::ProxyFilter(BufferedTransformation *filter, unsigned int firstSize, unsigned int lastSize, BufferedTransformation *attachment)
: FilterWithBufferedInput(firstSize, 1, lastSize, attachment), m_filter(filter)
{
if (m_filter.get())
m_filter->Attach(m_proxy = new OutputProxy(*this, false));
m_filter->Attach(new OutputProxy(*this, false));
}
void ProxyFilter::IsolatedFlush(bool completeFlush)
bool ProxyFilter::IsolatedFlush(bool hardFlush, bool blocking)
{
if (m_filter.get())
{
bool passSignal = m_proxy->GetPassSignal();
m_proxy->SetPassSignal(false);
m_filter->Flush(completeFlush, -1);
m_proxy->SetPassSignal(passSignal);
}
return m_filter.get() ? m_filter->Flush(hardFlush, -1, blocking) : false;
}
void ProxyFilter::SetFilter(Filter *filter)
{
bool passSignal = m_proxy ? m_proxy->GetPassSignal() : false;
m_filter.reset(filter);
if (filter)
{
std::auto_ptr<OutputProxy> temp(m_proxy = new OutputProxy(*this, passSignal));
m_filter->TransferAllTo(*m_proxy);
OutputProxy *proxy;
std::auto_ptr<OutputProxy> temp(proxy = new OutputProxy(*this, false));
m_filter->TransferAllTo(*proxy);
m_filter->Attach(temp.release());
}
else
m_proxy=NULL;
}
void ProxyFilter::NextPutMultiple(const byte *s, unsigned int len)
void ProxyFilter::NextPutMultiple(const byte *s, unsigned int len)
{
if (m_filter.get())
m_filter->Put(s, len);
@ -426,77 +418,77 @@ void ProxyFilter::NextPutMultiple(const byte *s, unsigned int len)
// *************************************************************
unsigned int ArraySink::Put2(const byte *begin, unsigned int length, int messageEnd, bool blocking)
unsigned int ArraySink::Put2(const byte *begin, unsigned int length, int messageEnd, bool blocking)
{
memcpy(m_buf+m_total, begin, STDMIN(length, SaturatingSubtract(m_size, m_total)));
m_total += length;
memcpy(m_buf+m_total, begin, STDMIN(length, SaturatingSubtract(m_size, m_total)));
m_total += length;
return 0;
}
byte * ArraySink::CreatePutSpace(unsigned int &size)
{
size = m_size - m_total;
size = m_size - m_total;
return m_buf + m_total;
}
void ArraySink::IsolatedInitialize(const NameValuePairs &parameters)
void ArraySink::IsolatedInitialize(const NameValuePairs &parameters)
{
ByteArrayParameter array;
if (!parameters.GetValue(Name::OutputBuffer(), array))
throw InvalidArgument("ArraySink: missing OutputBuffer argument");
m_buf = array.begin();
m_buf = array.begin();
m_size = array.size();
m_total = 0;
m_total = 0;
}
unsigned int ArrayXorSink::Put2(const byte *begin, unsigned int length, int messageEnd, bool blocking)
unsigned int ArrayXorSink::Put2(const byte *begin, unsigned int length, int messageEnd, bool blocking)
{
xorbuf(m_buf+m_total, begin, STDMIN(length, SaturatingSubtract(m_size, m_total)));
m_total += length;
xorbuf(m_buf+m_total, begin, STDMIN(length, SaturatingSubtract(m_size, m_total)));
m_total += length;
return 0;
}
// *************************************************************
unsigned int StreamTransformationFilter::LastBlockSize(StreamTransformation &c, BlockPaddingScheme padding)
unsigned int StreamTransformationFilter::LastBlockSize(StreamTransformation &c, BlockPaddingScheme padding)
{
if (c.MinLastBlockSize() > 0)
return c.MinLastBlockSize();
else if (c.MandatoryBlockSize() > 1 && !c.IsForwardTransformation() && padding != NO_PADDING && padding != ZEROS_PADDING)
else if (c.MandatoryBlockSize() > 1 && !c.IsForwardTransformation() && padding != NO_PADDING && padding != ZEROS_PADDING)
return c.MandatoryBlockSize();
else
return 0;
}
StreamTransformationFilter::StreamTransformationFilter(StreamTransformation &c, BufferedTransformation *attachment, BlockPaddingScheme padding)
: FilterWithBufferedInput(0, c.MandatoryBlockSize(), LastBlockSize(c, padding), attachment)
StreamTransformationFilter::StreamTransformationFilter(StreamTransformation &c, BufferedTransformation *attachment, BlockPaddingScheme padding)
: FilterWithBufferedInput(0, c.MandatoryBlockSize(), LastBlockSize(c, padding), attachment)
, m_cipher(c)
{
assert(c.MinLastBlockSize() == 0 || c.MinLastBlockSize() > c.MandatoryBlockSize());
assert(c.MinLastBlockSize() == 0 || c.MinLastBlockSize() > c.MandatoryBlockSize());
bool isBlockCipher = (c.MandatoryBlockSize() > 1 && c.MinLastBlockSize() == 0);
bool isBlockCipher = (c.MandatoryBlockSize() > 1 && c.MinLastBlockSize() == 0);
if (padding == DEFAULT_PADDING)
if (padding == DEFAULT_PADDING)
{
if (isBlockCipher)
m_padding = PKCS_PADDING;
m_padding = PKCS_PADDING;
else
m_padding = NO_PADDING;
m_padding = NO_PADDING;
}
else
m_padding = padding;
m_padding = padding;
if (!isBlockCipher && (m_padding == PKCS_PADDING || m_padding == ONE_AND_ZEROS_PADDING))
throw InvalidArgument("StreamTransformationFilter: PKCS_PADDING and ONE_AND_ZEROS_PADDING cannot be used with " + c.AlgorithmName());
if (!isBlockCipher && (m_padding == PKCS_PADDING || m_padding == ONE_AND_ZEROS_PADDING))
throw InvalidArgument("StreamTransformationFilter: PKCS_PADDING and ONE_AND_ZEROS_PADDING cannot be used with " + c.AlgorithmName());
}
void StreamTransformationFilter::FirstPut(const byte *inString)
void StreamTransformationFilter::FirstPut(const byte *inString)
{
m_optimalBufferSize = m_cipher.OptimalBlockSize();
m_optimalBufferSize = STDMAX(m_optimalBufferSize, RoundDownToMultipleOf(4096U, m_optimalBufferSize));
m_optimalBufferSize = m_cipher.OptimalBlockSize();
m_optimalBufferSize = STDMAX(m_optimalBufferSize, RoundDownToMultipleOf(4096U, m_optimalBufferSize));
}
void StreamTransformationFilter::NextPutMultiple(const byte *inString, unsigned int length)
void StreamTransformationFilter::NextPutMultiple(const byte *inString, unsigned int length)
{
if (!length)
return;
@ -506,32 +498,32 @@ void StreamTransformationFilter::NextPutMultiple(const byte *inString, unsigned
do
{
unsigned int len = m_optimalBufferSize;
byte *space = HelpCreatePutSpace(*AttachedTransformation(), NULL_CHANNEL, s, length, len);
if (len < length)
byte *space = HelpCreatePutSpace(*AttachedTransformation(), NULL_CHANNEL, s, length, len);
if (len < length)
{
if (len == m_optimalBufferSize)
len -= m_cipher.GetOptimalBlockSizeUsed();
len = RoundDownToMultipleOf(len, s);
if (len == m_optimalBufferSize)
len -= m_cipher.GetOptimalBlockSizeUsed();
len = RoundDownToMultipleOf(len, s);
}
else
len = length;
m_cipher.ProcessString(space, inString, len);
len = length;
m_cipher.ProcessString(space, inString, len);
AttachedTransformation()->PutModifiable(space, len);
inString += len;
inString += len;
length -= len;
}
while (length > 0);
while (length > 0);
}
void StreamTransformationFilter::NextPutModifiable(byte *inString, unsigned int length)
void StreamTransformationFilter::NextPutModifiable(byte *inString, unsigned int length)
{
m_cipher.ProcessString(inString, length);
AttachedTransformation()->PutModifiable(inString, length);
}
void StreamTransformationFilter::LastPut(const byte *inString, unsigned int length)
void StreamTransformationFilter::LastPut(const byte *inString, unsigned int length)
{
byte *space = NULL;
byte *space = NULL;
switch (m_padding)
{
@ -539,30 +531,30 @@ void StreamTransformationFilter::LastPut(const byte *inString, unsigned int leng
case ZEROS_PADDING:
if (length > 0)
{
unsigned int minLastBlockSize = m_cipher.MinLastBlockSize();
unsigned int minLastBlockSize = m_cipher.MinLastBlockSize();
bool isForwardTransformation = m_cipher.IsForwardTransformation();
if (isForwardTransformation && m_padding == ZEROS_PADDING && (minLastBlockSize == 0 || length < minLastBlockSize))
if (isForwardTransformation && m_padding == ZEROS_PADDING && (minLastBlockSize == 0 || length < minLastBlockSize))
{
// do padding
unsigned int blockSize = STDMAX(minLastBlockSize, m_cipher.MandatoryBlockSize());
space = HelpCreatePutSpace(*AttachedTransformation(), NULL_CHANNEL, blockSize);
memcpy(space, inString, length);
memset(space + length, 0, blockSize - length);
m_cipher.ProcessLastBlock(space, space, blockSize);
space = HelpCreatePutSpace(*AttachedTransformation(), NULL_CHANNEL, blockSize);
memcpy(space, inString, length);
memset(space + length, 0, blockSize - length);
m_cipher.ProcessLastBlock(space, space, blockSize);
AttachedTransformation()->Put(space, blockSize);
}
else
{
if (minLastBlockSize == 0)
if (minLastBlockSize == 0)
{
if (isForwardTransformation)
throw InvalidDataFormat("StreamTransformationFilter: plaintext length is not a multiple of block size and NO_PADDING is specified");
throw InvalidDataFormat("StreamTransformationFilter: plaintext length is not a multiple of block size and NO_PADDING is specified");
else
throw InvalidCiphertext("StreamTransformationFilter: ciphertext length is not a multiple of block size");
throw InvalidCiphertext("StreamTransformationFilter: ciphertext length is not a multiple of block size");
}
space = HelpCreatePutSpace(*AttachedTransformation(), NULL_CHANNEL, length, m_optimalBufferSize);
space = HelpCreatePutSpace(*AttachedTransformation(), NULL_CHANNEL, length, m_optimalBufferSize);
m_cipher.ProcessLastBlock(space, inString, length);
AttachedTransformation()->Put(space, length);
}
@ -572,13 +564,13 @@ void StreamTransformationFilter::LastPut(const byte *inString, unsigned int leng
case PKCS_PADDING:
case ONE_AND_ZEROS_PADDING:
unsigned int s;
s = m_cipher.MandatoryBlockSize();
s = m_cipher.MandatoryBlockSize();
assert(s > 1);
space = HelpCreatePutSpace(*AttachedTransformation(), NULL_CHANNEL, s, m_optimalBufferSize);
space = HelpCreatePutSpace(*AttachedTransformation(), NULL_CHANNEL, s, m_optimalBufferSize);
if (m_cipher.IsForwardTransformation())
{
assert(length < s);
memcpy(space, inString, length);
assert(length < s);
memcpy(space, inString, length);
if (m_padding == PKCS_PADDING)
{
assert(s < 256);
@ -587,30 +579,30 @@ void StreamTransformationFilter::LastPut(const byte *inString, unsigned int leng
}
else
{
space[length] = 1;
space[length] = 1;
memset(space+length+1, 0, s-length-1);
}
m_cipher.ProcessData(space, space, s);
m_cipher.ProcessData(space, space, s);
AttachedTransformation()->Put(space, s);
}
else
{
if (length != s)
throw InvalidCiphertext("StreamTransformationFilter: ciphertext length is not a multiple of block size");
m_cipher.ProcessData(space, inString, s);
throw InvalidCiphertext("StreamTransformationFilter: ciphertext length is not a multiple of block size");
m_cipher.ProcessData(space, inString, s);
if (m_padding == PKCS_PADDING)
{
byte pad = space[s-1];
if (pad < 1 || pad > s || std::find_if(space+s-pad, space+s, std::bind2nd(std::not_equal_to<byte>(), pad)) != space+s)
if (pad < 1 || pad > s || std::find_if(space+s-pad, space+s, std::bind2nd(std::not_equal_to<byte>(), pad)) != space+s)
throw InvalidCiphertext("StreamTransformationFilter: invalid PKCS #7 block padding found");
length = s-pad;
}
else
{
while (length > 1 && space[length-1] == '\0')
while (length > 1 && space[length-1] == '\0')
--length;
if (space[--length] != '\1')
throw InvalidCiphertext("StreamTransformationFilter: invalid ones-and-zeros padding found");
if (space[--length] != '\1')
throw InvalidCiphertext("StreamTransformationFilter: invalid ones-and-zeros padding found");
}
AttachedTransformation()->Put(space, length);
}
@ -629,7 +621,7 @@ void HashFilter::IsolatedInitialize(const NameValuePairs &parameters)
m_hashModule.Restart();
}
unsigned int HashFilter::Put2(const byte *inString, unsigned int length, int messageEnd, bool blocking)
unsigned int HashFilter::Put2(const byte *inString, unsigned int length, int messageEnd, bool blocking)
{
FILTER_BEGIN;
m_hashModule.Update(inString, length);
@ -638,8 +630,8 @@ unsigned int HashFilter::Put2(const byte *inString, unsigned int length, int mes
if (messageEnd)
{
{
unsigned int size, digestSize = m_hashModule.DigestSize();
m_space = HelpCreatePutSpace(*AttachedTransformation(), NULL_CHANNEL, digestSize, digestSize, size = digestSize);
unsigned int size, digestSize = m_hashModule.DigestSize();
m_space = HelpCreatePutSpace(*AttachedTransformation(), NULL_CHANNEL, digestSize, digestSize, size = digestSize);
m_hashModule.Final(m_space);
}
FILTER_OUTPUT(2, m_space, m_hashModule.DigestSize(), messageEnd);
@ -656,65 +648,65 @@ HashVerificationFilter::HashVerificationFilter(HashTransformation &hm, BufferedT
IsolatedInitialize(MakeParameters(Name::HashVerificationFilterFlags(), flags));
}
void HashVerificationFilter::InitializeDerivedAndReturnNewSizes(const NameValuePairs &parameters, unsigned int &firstSize, unsigned int &blockSize, unsigned int &lastSize)
void HashVerificationFilter::InitializeDerivedAndReturnNewSizes(const NameValuePairs &parameters, unsigned int &firstSize, unsigned int &blockSize, unsigned int &lastSize)
{
m_flags = parameters.GetValueWithDefault(Name::HashVerificationFilterFlags(), (word32)DEFAULT_FLAGS);
m_flags = parameters.GetValueWithDefault(Name::HashVerificationFilterFlags(), (word32)DEFAULT_FLAGS);
m_hashModule.Restart();
unsigned int size = m_hashModule.DigestSize();
unsigned int size = m_hashModule.DigestSize();
m_verified = false;
firstSize = m_flags & HASH_AT_BEGIN ? size : 0;
blockSize = 1;
firstSize = m_flags & HASH_AT_BEGIN ? size : 0;
blockSize = 1;
lastSize = m_flags & HASH_AT_BEGIN ? 0 : size;
}
void HashVerificationFilter::FirstPut(const byte *inString)
void HashVerificationFilter::FirstPut(const byte *inString)
{
if (m_flags & HASH_AT_BEGIN)
if (m_flags & HASH_AT_BEGIN)
{
m_expectedHash.New(m_hashModule.DigestSize());
memcpy(m_expectedHash, inString, m_expectedHash.size());
if (m_flags & PUT_HASH)
AttachedTransformation()->Put(inString, m_expectedHash.size());
if (m_flags & PUT_HASH)
AttachedTransformation()->Put(inString, m_expectedHash.size());
}
}
void HashVerificationFilter::NextPutMultiple(const byte *inString, unsigned int length)
void HashVerificationFilter::NextPutMultiple(const byte *inString, unsigned int length)
{
m_hashModule.Update(inString, length);
if (m_flags & PUT_MESSAGE)
AttachedTransformation()->Put(inString, length);
if (m_flags & PUT_MESSAGE)
AttachedTransformation()->Put(inString, length);
}
void HashVerificationFilter::LastPut(const byte *inString, unsigned int length)
void HashVerificationFilter::LastPut(const byte *inString, unsigned int length)
{
if (m_flags & HASH_AT_BEGIN)
if (m_flags & HASH_AT_BEGIN)
{
assert(length == 0);
m_verified = m_hashModule.Verify(m_expectedHash);
}
else
{
m_verified = (length==m_hashModule.DigestSize() && m_hashModule.Verify(inString));
if (m_flags & PUT_HASH)
AttachedTransformation()->Put(inString, length);
m_verified = (length==m_hashModule.DigestSize() && m_hashModule.Verify(inString));
if (m_flags & PUT_HASH)
AttachedTransformation()->Put(inString, length);
}
if (m_flags & PUT_RESULT)
if (m_flags & PUT_RESULT)
AttachedTransformation()->Put(m_verified);
if ((m_flags & THROW_EXCEPTION) && !m_verified)
if ((m_flags & THROW_EXCEPTION) && !m_verified)
throw HashVerificationFailed();
}
// *************************************************************
void SignerFilter::IsolatedInitialize(const NameValuePairs &parameters)
void SignerFilter::IsolatedInitialize(const NameValuePairs &parameters)
{
m_putMessage = parameters.GetValueWithDefault(Name::PutMessage(), false);
m_messageAccumulator.reset(m_signer.NewSignatureAccumulator());
}
unsigned int SignerFilter::Put2(const byte *inString, unsigned int length, int messageEnd, bool blocking)
unsigned int SignerFilter::Put2(const byte *inString, unsigned int length, int messageEnd, bool blocking)
{
FILTER_BEGIN;
m_messageAccumulator->Update(inString, length);
@ -724,7 +716,7 @@ unsigned int SignerFilter::Put2(const byte *inString, unsigned int length, int m
{
m_buf.New(m_signer.SignatureLength());
m_signer.Sign(m_rng, m_messageAccumulator.release(), m_buf);
FILTER_OUTPUT(2, m_buf, m_buf.size(), messageEnd);
FILTER_OUTPUT(2, m_buf, m_buf.size(), messageEnd);
m_messageAccumulator.reset(m_signer.NewSignatureAccumulator());
}
FILTER_END_NO_MESSAGE_END;
@ -734,34 +726,34 @@ SignatureVerificationFilter::SignatureVerificationFilter(const PK_Verifier &veri
: FilterWithBufferedInput(attachment)
, m_verifier(verifier)
{
IsolatedInitialize(MakeParameters(Name::SignatureVerificationFilterFlags(), flags));
IsolatedInitialize(MakeParameters(Name::SignatureVerificationFilterFlags(), flags));
}
void SignatureVerificationFilter::InitializeDerivedAndReturnNewSizes(const NameValuePairs &parameters, unsigned int &firstSize, unsigned int &blockSize, unsigned int &lastSize)
void SignatureVerificationFilter::InitializeDerivedAndReturnNewSizes(const NameValuePairs &parameters, unsigned int &firstSize, unsigned int &blockSize, unsigned int &lastSize)
{
m_flags = parameters.GetValueWithDefault(Name::SignatureVerificationFilterFlags(), (word32)DEFAULT_FLAGS);
m_flags = parameters.GetValueWithDefault(Name::SignatureVerificationFilterFlags(), (word32)DEFAULT_FLAGS);
m_messageAccumulator.reset(m_verifier.NewVerificationAccumulator());
unsigned int size = m_verifier.SignatureLength();
unsigned int size = m_verifier.SignatureLength();
m_verified = false;
firstSize = m_flags & SIGNATURE_AT_BEGIN ? size : 0;
blockSize = 1;
lastSize = m_flags & SIGNATURE_AT_BEGIN ? 0 : size;
firstSize = m_flags & SIGNATURE_AT_BEGIN ? size : 0;
blockSize = 1;
lastSize = m_flags & SIGNATURE_AT_BEGIN ? 0 : size;
}
void SignatureVerificationFilter::FirstPut(const byte *inString)
{
if (m_flags & SIGNATURE_AT_BEGIN)
if (m_flags & SIGNATURE_AT_BEGIN)
{
if (m_verifier.SignatureUpfrontForVerification())
m_verifier.InitializeVerificationAccumulator(*m_messageAccumulator, inString);
m_verifier.InitializeVerificationAccumulator(*m_messageAccumulator, inString);
else
{
m_signature.New(m_verifier.SignatureLength());
memcpy(m_signature, inString, m_signature.size());
memcpy(m_signature, inString, m_signature.size());
}
if (m_flags & PUT_SIGNATURE)
AttachedTransformation()->Put(inString, m_signature.size());
if (m_flags & PUT_SIGNATURE)
AttachedTransformation()->Put(inString, m_signature.size());
}
else
{
@ -769,31 +761,31 @@ void SignatureVerificationFilter::FirstPut(const byte *inString)
}
}
void SignatureVerificationFilter::NextPutMultiple(const byte *inString, unsigned int length)
void SignatureVerificationFilter::NextPutMultiple(const byte *inString, unsigned int length)
{
m_messageAccumulator->Update(inString, length);
if (m_flags & PUT_MESSAGE)
AttachedTransformation()->Put(inString, length);
if (m_flags & PUT_MESSAGE)
AttachedTransformation()->Put(inString, length);
}
void SignatureVerificationFilter::LastPut(const byte *inString, unsigned int length)
void SignatureVerificationFilter::LastPut(const byte *inString, unsigned int length)
{
if (m_flags & SIGNATURE_AT_BEGIN)
if (m_flags & SIGNATURE_AT_BEGIN)
{
assert(length == 0);
m_verified = m_verifier.Verify(m_messageAccumulator.release(), m_signature);
}
else
{
m_verified = (length==m_verifier.SignatureLength() && m_verifier.Verify(m_messageAccumulator.release(), inString));
if (m_flags & PUT_SIGNATURE)
AttachedTransformation()->Put(inString, length);
m_verified = (length==m_verifier.SignatureLength() && m_verifier.Verify(m_messageAccumulator.release(), inString));
if (m_flags & PUT_SIGNATURE)
AttachedTransformation()->Put(inString, length);
}
if (m_flags & PUT_RESULT)
if (m_flags & PUT_RESULT)
AttachedTransformation()->Put(m_verified);
if ((m_flags & THROW_EXCEPTION) && !m_verified)
if ((m_flags & THROW_EXCEPTION) && !m_verified)
throw SignatureVerificationFailed();
}
@ -801,11 +793,11 @@ void SignatureVerificationFilter::LastPut(const byte *inString, unsigned int len
unsigned int Source::PumpAll2(bool blocking)
{
// TODO: switch length type
unsigned long i = UINT_MAX;
// TODO: switch length type
unsigned long i = UINT_MAX;
RETURN_IF_NONZERO(Pump2(i, blocking));
unsigned int j = UINT_MAX;
return PumpMessages2(j, blocking);
return PumpMessages2(j, blocking);
}
bool Store::GetNextMessage()
@ -819,9 +811,9 @@ bool Store::GetNextMessage()
return false;
}
unsigned int Store::CopyMessagesTo(BufferedTransformation &target, unsigned int count, const std::string &channel) const
unsigned int Store::CopyMessagesTo(BufferedTransformation &target, unsigned int count, const std::string &channel) const
{
if (m_messageEnd || count == 0)
if (m_messageEnd || count == 0)
return 0;
else
{
@ -832,53 +824,53 @@ unsigned int Store::CopyMessagesTo(BufferedTransformation &target, unsigned int
}
}
void StringStore::StoreInitialize(const NameValuePairs &parameters)
void StringStore::StoreInitialize(const NameValuePairs &parameters)
{
ConstByteArrayParameter array;
ConstByteArrayParameter array;
if (!parameters.GetValue(Name::InputBuffer(), array))
throw InvalidArgument("StringStore: missing InputBuffer argument");
m_store = array.begin();
throw InvalidArgument("StringStore: missing InputBuffer argument");
m_store = array.begin();
m_length = array.size();
m_count = 0;
m_count = 0;
}
unsigned int StringStore::TransferTo2(BufferedTransformation &target, unsigned long &transferBytes, const std::string &channel, bool blocking)
unsigned int StringStore::TransferTo2(BufferedTransformation &target, unsigned long &transferBytes, const std::string &channel, bool blocking)
{
unsigned long position = 0;
unsigned int blockedBytes = CopyRangeTo2(target, position, transferBytes, channel, blocking);
m_count += position;
transferBytes = position;
unsigned int blockedBytes = CopyRangeTo2(target, position, transferBytes, channel, blocking);
m_count += position;
transferBytes = position;
return blockedBytes;
}
unsigned int StringStore::CopyRangeTo2(BufferedTransformation &target, unsigned long &begin, unsigned long end, const std::string &channel, bool blocking) const
unsigned int StringStore::CopyRangeTo2(BufferedTransformation &target, unsigned long &begin, unsigned long end, const std::string &channel, bool blocking) const
{
unsigned int i = (unsigned int)STDMIN((unsigned long)m_count+begin, (unsigned long)m_length);
unsigned int i = (unsigned int)STDMIN((unsigned long)m_count+begin, (unsigned long)m_length);
unsigned int len = (unsigned int)STDMIN((unsigned long)m_length-i, end-begin);
unsigned int blockedBytes = target.ChannelPut2(channel, m_store+i, len, 0, blocking);
unsigned int blockedBytes = target.ChannelPut2(channel, m_store+i, len, 0, blocking);
if (!blockedBytes)
begin += len;
return blockedBytes;
}
unsigned int RandomNumberStore::TransferTo2(BufferedTransformation &target, unsigned long &transferBytes, const std::string &channel, bool blocking)
unsigned int RandomNumberStore::TransferTo2(BufferedTransformation &target, unsigned long &transferBytes, const std::string &channel, bool blocking)
{
if (!blocking)
throw NotImplemented("RandomNumberStore: nonblocking transfer is not implemented by this object");
throw NotImplemented("RandomNumberStore: nonblocking transfer is not implemented by this object");
unsigned long transferMax = transferBytes;
for (transferBytes = 0; transferBytes<transferMax && m_count < m_length; ++transferBytes, ++m_count)
unsigned long transferMax = transferBytes;
for (transferBytes = 0; transferBytes<transferMax && m_count < m_length; ++transferBytes, ++m_count)
target.ChannelPut(channel, m_rng.GenerateByte());
return 0;
}
unsigned int NullStore::CopyRangeTo2(BufferedTransformation &target, unsigned long &begin, unsigned long end, const std::string &channel, bool blocking) const
unsigned int NullStore::CopyRangeTo2(BufferedTransformation &target, unsigned long &begin, unsigned long end, const std::string &channel, bool blocking) const
{
static const byte nullBytes[128] = {0};
while (begin < end)
{
unsigned int len = STDMIN(end-begin, 128UL);
unsigned int blockedBytes = target.ChannelPut2(channel, nullBytes, len, 0, blocking);
unsigned int blockedBytes = target.ChannelPut2(channel, nullBytes, len, 0, blocking);
if (blockedBytes)
return blockedBytes;
begin += len;
@ -886,11 +878,11 @@ unsigned int NullStore::CopyRangeTo2(BufferedTransformation &target, unsigned lo
return 0;
}
unsigned int NullStore::TransferTo2(BufferedTransformation &target, unsigned long &transferBytes, const std::string &channel, bool blocking)
unsigned int NullStore::TransferTo2(BufferedTransformation &target, unsigned long &transferBytes, const std::string &channel, bool blocking)
{
unsigned long begin = 0;
unsigned int blockedBytes = NullStore::CopyRangeTo2(target, begin, transferBytes, channel, blocking);
transferBytes = begin;
unsigned long begin = 0;
unsigned int blockedBytes = NullStore::CopyRangeTo2(target, begin, transferBytes, channel, blocking);
transferBytes = begin;
m_size -= begin;
return blockedBytes;
}

495
filters.h
View File

@ -1,5 +1,5 @@
#ifndef CRYPTOPP_FILTERS_H
#define CRYPTOPP_FILTERS_H
#ifndef CRYPTOPP_FILTERS_H
#define CRYPTOPP_FILTERS_H
#include "simple.h"
#include "secblock.h"
@ -10,7 +10,7 @@
NAMESPACE_BEGIN(CryptoPP)
/// provides an implementation of BufferedTransformation's attachment interface
/// provides an implementation of BufferedTransformation's attachment interface
class Filter : public BufferedTransformation, public NotCopyable
{
public:
@ -19,48 +19,48 @@ public:
bool Attachable() {return true;}
BufferedTransformation *AttachedTransformation();
const BufferedTransformation *AttachedTransformation() const;
void Detach(BufferedTransformation *newAttachment = NULL);
void Detach(BufferedTransformation *newAttachment = NULL);
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;
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;
void Initialize(const NameValuePairs &parameters=g_nullNameValuePairs, int propagation=-1);
bool Flush(bool hardFlush, int propagation=-1, bool blocking=true);
bool Flush(bool hardFlush, int propagation=-1, bool blocking=true);
bool MessageSeriesEnd(int propagation=-1, bool blocking=true);
protected:
virtual void NotifyAttachmentChange() {}
virtual BufferedTransformation * NewDefaultAttachment() const;
void Insert(Filter *nextFilter); // insert filter after this one
virtual void NotifyAttachmentChange() {}
virtual BufferedTransformation * NewDefaultAttachment() const;
void Insert(Filter *nextFilter); // insert filter after this one
virtual bool ShouldPropagateMessageEnd() const {return true;}
virtual bool ShouldPropagateMessageSeriesEnd() const {return true;}
virtual bool ShouldPropagateMessageEnd() const {return true;}
virtual bool ShouldPropagateMessageSeriesEnd() const {return true;}
void PropagateInitialize(const NameValuePairs &parameters, int propagation, const std::string &channel=NULL_CHANNEL);
void PropagateInitialize(const NameValuePairs &parameters, int propagation, const std::string &channel=NULL_CHANNEL);
unsigned int Output(int outputSite, const byte *inString, unsigned int length, int messageEnd, bool blocking, const std::string &channel=NULL_CHANNEL);
bool OutputMessageEnd(int outputSite, int propagation, bool blocking, const std::string &channel=NULL_CHANNEL);
unsigned int Output(int outputSite, const byte *inString, unsigned int length, int messageEnd, bool blocking, const std::string &channel=NULL_CHANNEL);
bool OutputMessageEnd(int outputSite, int propagation, bool blocking, const std::string &channel=NULL_CHANNEL);
bool OutputFlush(int outputSite, bool hardFlush, int propagation, bool blocking, const std::string &channel=NULL_CHANNEL);
bool OutputMessageSeriesEnd(int outputSite, int propagation, bool blocking, const std::string &channel=NULL_CHANNEL);
bool OutputMessageSeriesEnd(int outputSite, int propagation, bool blocking, const std::string &channel=NULL_CHANNEL);
private:
member_ptr<BufferedTransformation> m_attachment;
protected:
unsigned int m_inputPosition;
int m_continueAt;
int m_continueAt;
};
struct FilterPutSpaceHelper
{
// desiredSize is how much to ask target, bufferSize is how much to allocate in m_tempSpace
byte *HelpCreatePutSpace(BufferedTransformation &target, const std::string &channel, unsigned int minSize, unsigned int desiredSize, unsigned int &bufferSize)
// desiredSize is how much to ask target, bufferSize is how much to allocate in m_tempSpace
byte *HelpCreatePutSpace(BufferedTransformation &target, const std::string &channel, unsigned int minSize, unsigned int desiredSize, unsigned int &bufferSize)
{
assert(desiredSize >= minSize && bufferSize >= minSize);
assert(desiredSize >= minSize && bufferSize >= minSize);
if (m_tempSpace.size() < minSize)
{
byte *result = target.ChannelCreatePutSpace(channel, desiredSize);
if (desiredSize >= minSize)
if (desiredSize >= minSize)
{
bufferSize = desiredSize;
return result;
@ -71,30 +71,30 @@ struct FilterPutSpaceHelper
bufferSize = m_tempSpace.size();
return m_tempSpace.begin();
}
byte *HelpCreatePutSpace(BufferedTransformation &target, const std::string &channel, unsigned int minSize)
{return HelpCreatePutSpace(target, channel, minSize, minSize, minSize);}
byte *HelpCreatePutSpace(BufferedTransformation &target, const std::string &channel, unsigned int minSize, unsigned int bufferSize)
{return HelpCreatePutSpace(target, channel, minSize, minSize, bufferSize);}
byte *HelpCreatePutSpace(BufferedTransformation &target, const std::string &channel, unsigned int minSize)
{return HelpCreatePutSpace(target, channel, minSize, minSize, minSize);}
byte *HelpCreatePutSpace(BufferedTransformation &target, const std::string &channel, unsigned int minSize, unsigned int bufferSize)
{return HelpCreatePutSpace(target, channel, minSize, minSize, bufferSize);}
SecByteBlock m_tempSpace;
};
//! measure how many byte and messages pass through, also serves as valve
class MeterFilter : public Bufferless<Filter>
//! measure how many byte and messages pass through, also serves as valve
class MeterFilter : public Bufferless<Filter>
{
public:
MeterFilter(BufferedTransformation *attachment=NULL, bool transparent=true)
: Bufferless<Filter>(attachment), m_transparent(transparent) {ResetMeter();}
void SetTransparent(bool transparent) {m_transparent = transparent;}
void ResetMeter() {m_currentMessageBytes = m_totalBytes = m_currentSeriesMessages = m_totalMessages = m_totalMessageSeries = 0;}
void ResetMeter() {m_currentMessageBytes = m_totalBytes = m_currentSeriesMessages = m_totalMessages = m_totalMessageSeries = 0;}
unsigned long GetCurrentMessageBytes() const {return m_currentMessageBytes;}
unsigned long GetTotalBytes() {return m_totalBytes;}
unsigned int GetCurrentSeriesMessages() {return m_currentSeriesMessages;}
unsigned int GetTotalMessages() {return m_totalMessages;}
unsigned int GetCurrentSeriesMessages() {return m_currentSeriesMessages;}
unsigned int GetTotalMessages() {return m_totalMessages;}
unsigned int GetTotalMessageSeries() {return m_totalMessageSeries;}
unsigned int Put2(const byte *begin, unsigned int length, int messageEnd, bool blocking);
unsigned int Put2(const byte *begin, unsigned int length, int messageEnd, bool blocking);
bool IsolatedMessageSeriesEnd(bool blocking);
private:
@ -106,93 +106,93 @@ private:
unsigned int m_currentSeriesMessages, m_totalMessages, m_totalMessageSeries;
};
//! .
class TransparentFilter : public MeterFilter
//! .
class TransparentFilter : public MeterFilter
{
public:
TransparentFilter(BufferedTransformation *attachment=NULL) : MeterFilter(attachment, true) {}
};
//! .
class OpaqueFilter : public MeterFilter
//! .
class OpaqueFilter : public MeterFilter
{
public:
OpaqueFilter(BufferedTransformation *attachment=NULL) : MeterFilter(attachment, false) {}
OpaqueFilter(BufferedTransformation *attachment=NULL) : MeterFilter(attachment, false) {}
};
/*! FilterWithBufferedInput divides up the input stream into
a first block, a number of middle blocks, and a last block.
First and last blocks are optional, and middle blocks may
be a stream instead (i.e. blockSize == 1).
/*! FilterWithBufferedInput divides up the input stream into
a first block, a number of middle blocks, and a last block.
First and last blocks are optional, and middle blocks may
be a stream instead (i.e. blockSize == 1).
*/
class FilterWithBufferedInput : public Filter
class FilterWithBufferedInput : public Filter
{
public:
FilterWithBufferedInput(BufferedTransformation *attachment);
//! firstSize and lastSize may be 0, blockSize must be at least 1
FilterWithBufferedInput(unsigned int firstSize, unsigned int blockSize, unsigned int lastSize, BufferedTransformation *attachment);
//! firstSize and lastSize may be 0, blockSize must be at least 1
FilterWithBufferedInput(unsigned int firstSize, unsigned int blockSize, unsigned int lastSize, BufferedTransformation *attachment);
void IsolatedInitialize(const NameValuePairs &parameters);
unsigned int Put2(const byte *inString, unsigned int length, int messageEnd, bool blocking)
unsigned int Put2(const byte *inString, unsigned int length, int messageEnd, bool blocking)
{
return PutMaybeModifiable(const_cast<byte *>(inString), length, messageEnd, blocking, false);
return PutMaybeModifiable(const_cast<byte *>(inString), length, messageEnd, blocking, false);
}
unsigned int PutModifiable2(byte *inString, unsigned int length, int messageEnd, bool blocking)
unsigned int PutModifiable2(byte *inString, unsigned int length, int messageEnd, bool blocking)
{
return PutMaybeModifiable(inString, length, messageEnd, blocking, true);
return PutMaybeModifiable(inString, length, messageEnd, blocking, true);
}
/*! calls ForceNextPut() if hardFlush is true */
bool IsolatedFlush(bool hardFlush, bool blocking);
/*! calls ForceNextPut() if hardFlush is true */
bool IsolatedFlush(bool hardFlush, bool blocking);
/*! the input buffer may contain more than blockSize bytes if lastSize != 0
ForceNextPut() forces a call to NextPut() if this is the case
/*! The input buffer may contain more than blockSize bytes if lastSize != 0.
ForceNextPut() forces a call to NextPut() if this is the case.
*/
void ForceNextPut();
protected:
bool DidFirstPut() {return m_firstInputDone;}
virtual void InitializeDerivedAndReturnNewSizes(const NameValuePairs &parameters, unsigned int &firstSize, unsigned int &blockSize, unsigned int &lastSize)
virtual void InitializeDerivedAndReturnNewSizes(const NameValuePairs &parameters, unsigned int &firstSize, unsigned int &blockSize, unsigned int &lastSize)
{InitializeDerived(parameters);}
virtual void InitializeDerived(const NameValuePairs &parameters) {}
// FirstPut() is called if (firstSize != 0 and totalLength >= firstSize)
// or (firstSize == 0 and (totalLength > 0 or a MessageEnd() is received))
virtual void FirstPut(const byte *inString) =0;
// NextPut() is called if totalLength >= firstSize+blockSize+lastSize
virtual void NextPutSingle(const byte *inString) {assert(false);}
// Same as NextPut() except length can be a multiple of blockSize
// Either NextPut() or NextPutMultiple() must be overriden
virtual void NextPutMultiple(const byte *inString, unsigned int length);
// Same as NextPutMultiple(), but inString can be modified
virtual void NextPutModifiable(byte *inString, unsigned int length)
virtual void InitializeDerived(const NameValuePairs &parameters) {}
// FirstPut() is called if (firstSize != 0 and totalLength >= firstSize)
// or (firstSize == 0 and (totalLength > 0 or a MessageEnd() is received))
virtual void FirstPut(const byte *inString) =0;
// NextPut() is called if totalLength >= firstSize+blockSize+lastSize
virtual void NextPutSingle(const byte *inString) {assert(false);}
// Same as NextPut() except length can be a multiple of blockSize
// Either NextPut() or NextPutMultiple() must be overriden
virtual void NextPutMultiple(const byte *inString, unsigned int length);
// Same as NextPutMultiple(), but inString can be modified
virtual void NextPutModifiable(byte *inString, unsigned int length)
{NextPutMultiple(inString, length);}
// LastPut() is always called
// if totalLength < firstSize then length == totalLength
// else if totalLength <= firstSize+lastSize then length == totalLength-firstSize
// else lastSize <= length < lastSize+blockSize
virtual void LastPut(const byte *inString, unsigned int length) =0;
virtual void FlushDerived() {}
// LastPut() is always called
// if totalLength < firstSize then length == totalLength
// else if totalLength <= firstSize+lastSize then length == totalLength-firstSize
// else lastSize <= length < lastSize+blockSize
virtual void LastPut(const byte *inString, unsigned int length) =0;
virtual void FlushDerived() {}
private:
unsigned int PutMaybeModifiable(byte *begin, unsigned int length, int messageEnd, bool blocking, bool modifiable);
void NextPutMaybeModifiable(byte *inString, unsigned int length, bool modifiable)
void NextPutMaybeModifiable(byte *inString, unsigned int length, bool modifiable)
{
if (modifiable) NextPutModifiable(inString, length);
if (modifiable) NextPutModifiable(inString, length);
else NextPutMultiple(inString, length);
}
// This function should no longer be used, put this here to cause a compiler error
// if someone tries to override NextPut().
virtual int NextPut(const byte *inString, unsigned int length) {assert(false); return 0;}
// This function should no longer be used, put this here to cause a compiler error
// if someone tries to override NextPut().
virtual int NextPut(const byte *inString, unsigned int length) {assert(false); return 0;}
class BlockQueue
{
public:
void ResetQueue(unsigned int blockSize, unsigned int maxBlocks);
void ResetQueue(unsigned int blockSize, unsigned int maxBlocks);
byte *GetBlock();
byte *GetContigousBlocks(unsigned int &numberOfBytes);
unsigned int GetAll(byte *outString);
void Put(const byte *inString, unsigned int length);
void Put(const byte *inString, unsigned int length);
unsigned int CurrentSize() const {return m_size;}
unsigned int MaxSize() const {return m_buffer.size();}
@ -207,49 +207,49 @@ private:
BlockQueue m_queue;
};
//! .
class FilterWithInputQueue : public Filter
//! .
class FilterWithInputQueue : public Filter
{
public:
FilterWithInputQueue(BufferedTransformation *attachment) : Filter(attachment) {}
unsigned int Put2(const byte *inString, unsigned int length, int messageEnd, bool blocking)
FilterWithInputQueue(BufferedTransformation *attachment) : Filter(attachment) {}
unsigned int Put2(const byte *inString, unsigned int length, int messageEnd, bool blocking)
{
if (!blocking)
throw BlockingInputOnly("FilterWithInputQueue");
m_inQueue.Put(inString, length);
m_inQueue.Put(inString, length);
if (messageEnd)
{
IsolatedMessageEnd(blocking);
Output(0, NULL, 0, messageEnd, blocking);
Output(0, NULL, 0, messageEnd, blocking);
}
return 0;
}
protected:
virtual bool IsolatedMessageEnd(bool blocking) =0;
virtual bool IsolatedMessageEnd(bool blocking) =0;
void IsolatedInitialize(const NameValuePairs &parameters) {m_inQueue.Clear();}
ByteQueue m_inQueue;
};
//! Filter Wrapper for StreamTransformation
//! Filter Wrapper for StreamTransformation
class StreamTransformationFilter : public FilterWithBufferedInput, private FilterPutSpaceHelper
{
public:
enum BlockPaddingScheme {NO_PADDING, ZEROS_PADDING, PKCS_PADDING, ONE_AND_ZEROS_PADDING, DEFAULT_PADDING};
/*! DEFAULT_PADDING means PKCS_PADDING if c.MandatoryBlockSize() > 1 && c.MinLastBlockSize() == 0 (e.g. ECB or CBC mode),
otherwise NO_PADDING (OFB, CFB, CTR, CBC-CTS modes) */
StreamTransformationFilter(StreamTransformation &c, BufferedTransformation *attachment = NULL, BlockPaddingScheme padding = DEFAULT_PADDING);
enum BlockPaddingScheme {NO_PADDING, ZEROS_PADDING, PKCS_PADDING, ONE_AND_ZEROS_PADDING, DEFAULT_PADDING};
/*! DEFAULT_PADDING means PKCS_PADDING if c.MandatoryBlockSize() > 1 && c.MinLastBlockSize() == 0 (e.g. ECB or CBC mode),
otherwise NO_PADDING (OFB, CFB, CTR, CBC-CTS modes) */
StreamTransformationFilter(StreamTransformation &c, BufferedTransformation *attachment = NULL, BlockPaddingScheme padding = DEFAULT_PADDING);
void FirstPut(const byte *inString);
void NextPutMultiple(const byte *inString, unsigned int length);
void NextPutModifiable(byte *inString, unsigned int length);
void LastPut(const byte *inString, unsigned int length);
void FirstPut(const byte *inString);
void NextPutMultiple(const byte *inString, unsigned int length);
void NextPutModifiable(byte *inString, unsigned int length);
void LastPut(const byte *inString, unsigned int length);
// byte * CreatePutSpace(unsigned int &size);
protected:
static unsigned int LastBlockSize(StreamTransformation &c, BlockPaddingScheme padding);
static unsigned int LastBlockSize(StreamTransformation &c, BlockPaddingScheme padding);
StreamTransformation &m_cipher;
BlockPaddingScheme m_padding;
@ -257,18 +257,18 @@ protected:
};
#ifdef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY
typedef StreamTransformationFilter StreamCipherFilter;
typedef StreamTransformationFilter StreamCipherFilter;
#endif
//! Filter Wrapper for HashTransformation
//! Filter Wrapper for HashTransformation
class HashFilter : public Bufferless<Filter>, private FilterPutSpaceHelper
{
public:
HashFilter(HashTransformation &hm, BufferedTransformation *attachment = NULL, bool putMessage=false)
: Bufferless<Filter>(attachment), m_hashModule(hm), m_putMessage(putMessage) {}
HashFilter(HashTransformation &hm, BufferedTransformation *attachment = NULL, bool putMessage=false)
: Bufferless<Filter>(attachment), m_hashModule(hm), m_putMessage(putMessage) {}
void IsolatedInitialize(const NameValuePairs &parameters);
unsigned int Put2(const byte *begin, unsigned int length, int messageEnd, bool blocking);
unsigned int Put2(const byte *begin, unsigned int length, int messageEnd, bool blocking);
byte * CreatePutSpace(unsigned int &size) {return m_hashModule.CreateUpdateSpace(size);}
@ -278,7 +278,7 @@ private:
byte *m_space;
};
//! Filter Wrapper for HashTransformation
//! Filter Wrapper for HashTransformation
class HashVerificationFilter : public FilterWithBufferedInput
{
public:
@ -286,23 +286,23 @@ public:
{
public:
HashVerificationFailed()
: Exception(DATA_INTEGRITY_CHECK_FAILED, "HashVerifier: message hash not valid") {}
: Exception(DATA_INTEGRITY_CHECK_FAILED, "HashVerifier: message hash not valid") {}
};
enum Flags {HASH_AT_BEGIN=1, PUT_MESSAGE=2, PUT_HASH=4, PUT_RESULT=8, THROW_EXCEPTION=16, DEFAULT_FLAGS = HASH_AT_BEGIN | PUT_RESULT};
HashVerificationFilter(HashTransformation &hm, BufferedTransformation *attachment = NULL, word32 flags = DEFAULT_FLAGS);
enum Flags {HASH_AT_BEGIN=1, PUT_MESSAGE=2, PUT_HASH=4, PUT_RESULT=8, THROW_EXCEPTION=16, DEFAULT_FLAGS = HASH_AT_BEGIN | PUT_RESULT};
HashVerificationFilter(HashTransformation &hm, BufferedTransformation *attachment = NULL, word32 flags = DEFAULT_FLAGS);
bool GetLastResult() const {return m_verified;}
protected:
void InitializeDerivedAndReturnNewSizes(const NameValuePairs &parameters, unsigned int &firstSize, unsigned int &blockSize, unsigned int &lastSize);
void FirstPut(const byte *inString);
void NextPutMultiple(const byte *inString, unsigned int length);
void LastPut(const byte *inString, unsigned int length);
void InitializeDerivedAndReturnNewSizes(const NameValuePairs &parameters, unsigned int &firstSize, unsigned int &blockSize, unsigned int &lastSize);
void FirstPut(const byte *inString);
void NextPutMultiple(const byte *inString, unsigned int length);
void LastPut(const byte *inString, unsigned int length);
private:
static inline unsigned int FirstSize(word32 flags, HashTransformation &hm) {return flags & HASH_AT_BEGIN ? hm.DigestSize() : 0;}
static inline unsigned int LastSize(word32 flags, HashTransformation &hm) {return flags & HASH_AT_BEGIN ? 0 : hm.DigestSize();}
static inline unsigned int FirstSize(word32 flags, HashTransformation &hm) {return flags & HASH_AT_BEGIN ? hm.DigestSize() : 0;}
static inline unsigned int LastSize(word32 flags, HashTransformation &hm) {return flags & HASH_AT_BEGIN ? 0 : hm.DigestSize();}
HashTransformation &m_hashModule;
word32 m_flags;
@ -310,47 +310,47 @@ private:
bool m_verified;
};
typedef HashVerificationFilter HashVerifier; // for backwards compatibility
typedef HashVerificationFilter HashVerifier; // for backwards compatibility
//! Filter Wrapper for PK_Signer
class SignerFilter : public Unflushable<Filter>
//! Filter Wrapper for PK_Signer
class SignerFilter : public Unflushable<Filter>
{
public:
SignerFilter(RandomNumberGenerator &rng, const PK_Signer &signer, BufferedTransformation *attachment = NULL, bool putMessage=false)
: Unflushable<Filter>(attachment), m_rng(rng), m_signer(signer), m_messageAccumulator(signer.NewSignatureAccumulator()), m_putMessage(putMessage) {}
void IsolatedInitialize(const NameValuePairs &parameters);
unsigned int Put2(const byte *begin, unsigned int length, int messageEnd, bool blocking);
unsigned int Put2(const byte *begin, unsigned int length, int messageEnd, bool blocking);
private:
RandomNumberGenerator &m_rng;
const PK_Signer &m_signer;
const PK_Signer &m_signer;
member_ptr<HashTransformation> m_messageAccumulator;
bool m_putMessage;
SecByteBlock m_buf;
};
//! Filter Wrapper for PK_Verifier
class SignatureVerificationFilter : public FilterWithBufferedInput
//! Filter Wrapper for PK_Verifier
class SignatureVerificationFilter : public FilterWithBufferedInput
{
public:
class SignatureVerificationFailed : public Exception
class SignatureVerificationFailed : public Exception
{
public:
SignatureVerificationFailed()
: Exception(DATA_INTEGRITY_CHECK_FAILED, "VerifierFilter: digital signature not valid") {}
: Exception(DATA_INTEGRITY_CHECK_FAILED, "VerifierFilter: digital signature not valid") {}
};
enum Flags {SIGNATURE_AT_BEGIN=1, PUT_MESSAGE=2, PUT_SIGNATURE=4, PUT_RESULT=8, THROW_EXCEPTION=16, DEFAULT_FLAGS = SIGNATURE_AT_BEGIN | PUT_RESULT};
SignatureVerificationFilter(const PK_Verifier &verifier, BufferedTransformation *attachment = NULL, word32 flags = DEFAULT_FLAGS);
enum Flags {SIGNATURE_AT_BEGIN=1, PUT_MESSAGE=2, PUT_SIGNATURE=4, PUT_RESULT=8, THROW_EXCEPTION=16, DEFAULT_FLAGS = SIGNATURE_AT_BEGIN | PUT_RESULT};
SignatureVerificationFilter(const PK_Verifier &verifier, BufferedTransformation *attachment = NULL, word32 flags = DEFAULT_FLAGS);
bool GetLastResult() const {return m_verified;}
protected:
void InitializeDerivedAndReturnNewSizes(const NameValuePairs &parameters, unsigned int &firstSize, unsigned int &blockSize, unsigned int &lastSize);
void FirstPut(const byte *inString);
void NextPutMultiple(const byte *inString, unsigned int length);
void LastPut(const byte *inString, unsigned int length);
void InitializeDerivedAndReturnNewSizes(const NameValuePairs &parameters, unsigned int &firstSize, unsigned int &blockSize, unsigned int &lastSize);
void FirstPut(const byte *inString);
void NextPutMultiple(const byte *inString, unsigned int length);
void LastPut(const byte *inString, unsigned int length);
private:
const PK_Verifier &m_verifier;
@ -360,109 +360,108 @@ private:
bool m_verified;
};
typedef SignatureVerificationFilter VerifierFilter; // for backwards compatibility
typedef SignatureVerificationFilter VerifierFilter; // for backwards compatibility
//! Redirect input to another BufferedTransformation without owning it
//! Redirect input to another BufferedTransformation without owning it
class Redirector : public CustomSignalPropagation<Sink>
{
public:
Redirector() : m_target(NULL), m_passSignal(true) {}
Redirector(BufferedTransformation &target, bool passSignal=true) : m_target(&target), m_passSignal(passSignal) {}
Redirector(BufferedTransformation &target, bool passSignal=true) : m_target(&target), m_passSignal(passSignal) {}
void Redirect(BufferedTransformation &target) {m_target = &target;}
void Redirect(BufferedTransformation &target) {m_target = &target;}
void StopRedirection() {m_target = NULL;}
bool GetPassSignal() const {return m_passSignal;}
void SetPassSignal(bool passSignal) {m_passSignal = passSignal;}
void SetPassSignal(bool passSignal) {m_passSignal = passSignal;}
unsigned int Put2(const byte *begin, unsigned int length, int messageEnd, bool blocking)
{return m_target ? m_target->Put2(begin, length, m_passSignal ? messageEnd : 0, blocking) : 0;}
unsigned int Put2(const byte *begin, unsigned int length, int messageEnd, bool blocking)
{return m_target ? m_target->Put2(begin, length, m_passSignal ? messageEnd : 0, blocking) : 0;}
void Initialize(const NameValuePairs &parameters, int propagation)
{ChannelInitialize(NULL_CHANNEL, parameters, propagation);}
bool Flush(bool hardFlush, int propagation=-1, bool blocking=true)
{return m_target && m_passSignal ? m_target->Flush(hardFlush, propagation, blocking) : false;}
bool Flush(bool hardFlush, int propagation=-1, bool blocking=true)
{return m_target && m_passSignal ? m_target->Flush(hardFlush, propagation, blocking) : false;}
bool MessageSeriesEnd(int propagation=-1, bool blocking=true)
{return m_target && m_passSignal ? m_target->MessageSeriesEnd(propagation, blocking) : false;}
{return m_target && m_passSignal ? m_target->MessageSeriesEnd(propagation, blocking) : false;}
void ChannelInitialize(const std::string &channel, const NameValuePairs &parameters=g_nullNameValuePairs, int propagation=-1);
unsigned int ChannelPut2(const std::string &channel, const byte *begin, unsigned int length, int messageEnd, bool blocking)
{return m_target ? m_target->ChannelPut2(channel, begin, length, m_passSignal ? messageEnd : 0, blocking) : 0;}
unsigned int ChannelPutModifiable2(const std::string &channel, byte *begin, unsigned int length, int messageEnd, bool blocking)
{return m_target ? m_target->ChannelPutModifiable2(channel, begin, length, m_passSignal ? messageEnd : 0, blocking) : 0;}
bool ChannelFlush(const std::string &channel, bool completeFlush, int propagation=-1, bool blocking=true)
{return m_target && m_passSignal ? m_target->ChannelFlush(channel, completeFlush, propagation, blocking) : false;}
void ChannelInitialize(const std::string &channel, const NameValuePairs &parameters=g_nullNameValuePairs, int propagation=-1);
unsigned int ChannelPut2(const std::string &channel, const byte *begin, unsigned int length, int messageEnd, bool blocking)
{return m_target ? m_target->ChannelPut2(channel, begin, length, m_passSignal ? messageEnd : 0, blocking) : 0;}
unsigned int ChannelPutModifiable2(const std::string &channel, byte *begin, unsigned int length, int messageEnd, bool blocking)
{return m_target ? m_target->ChannelPutModifiable2(channel, begin, length, m_passSignal ? messageEnd : 0, blocking) : 0;}
bool ChannelFlush(const std::string &channel, bool completeFlush, int propagation=-1, bool blocking=true)
{return m_target && m_passSignal ? m_target->ChannelFlush(channel, completeFlush, propagation, blocking) : false;}
bool ChannelMessageSeriesEnd(const std::string &channel, int propagation=-1, bool blocking=true)
{return m_target && m_passSignal ? m_target->ChannelMessageSeriesEnd(channel, propagation, blocking) : false;}
{return m_target && m_passSignal ? m_target->ChannelMessageSeriesEnd(channel, propagation, blocking) : false;}
private:
BufferedTransformation *m_target;
bool m_passSignal;
};
// Used By ProxyFilter
class OutputProxy : public CustomSignalPropagation<Sink>
// Used By ProxyFilter
class OutputProxy : public CustomSignalPropagation<Sink>
{
public:
OutputProxy(BufferedTransformation &owner, bool passSignal) : m_owner(owner), m_passSignal(passSignal) {}
OutputProxy(BufferedTransformation &owner, bool passSignal) : m_owner(owner), m_passSignal(passSignal) {}
bool GetPassSignal() const {return m_passSignal;}
void SetPassSignal(bool passSignal) {m_passSignal = passSignal;}
void SetPassSignal(bool passSignal) {m_passSignal = passSignal;}
unsigned int Put2(const byte *begin, unsigned int length, int messageEnd, bool blocking)
{return m_owner.AttachedTransformation()->Put2(begin, length, m_passSignal ? messageEnd : 0, blocking);}
unsigned int Put2(const byte *begin, unsigned int length, int messageEnd, bool blocking)
{return m_owner.AttachedTransformation()->Put2(begin, length, m_passSignal ? messageEnd : 0, blocking);}
unsigned int PutModifiable2(byte *begin, unsigned int length, int messageEnd, bool blocking)
{return m_owner.AttachedTransformation()->PutModifiable2(begin, length, m_passSignal ? messageEnd : 0, blocking);}
{return m_owner.AttachedTransformation()->PutModifiable2(begin, length, m_passSignal ? messageEnd : 0, blocking);}
void Initialize(const NameValuePairs &parameters=g_nullNameValuePairs, int propagation=-1)
{if (m_passSignal) m_owner.AttachedTransformation()->Initialize(parameters, propagation);}
bool Flush(bool hardFlush, int propagation=-1, bool blocking=true)
{return m_passSignal ? m_owner.AttachedTransformation()->Flush(hardFlush, propagation, blocking) : false;}
{if (m_passSignal) m_owner.AttachedTransformation()->Initialize(parameters, propagation);}
bool Flush(bool hardFlush, int propagation=-1, bool blocking=true)
{return m_passSignal ? m_owner.AttachedTransformation()->Flush(hardFlush, propagation, blocking) : false;}
bool MessageSeriesEnd(int propagation=-1, bool blocking=true)
{return m_passSignal ? m_owner.AttachedTransformation()->MessageSeriesEnd(propagation, blocking) : false;}
{return m_passSignal ? m_owner.AttachedTransformation()->MessageSeriesEnd(propagation, blocking) : false;}
unsigned int ChannelPut2(const std::string &channel, const byte *begin, unsigned int length, int messageEnd, bool blocking)
{return m_owner.AttachedTransformation()->ChannelPut2(channel, begin, length, m_passSignal ? messageEnd : 0, blocking);}
unsigned int ChannelPutModifiable2(const std::string &channel, byte *begin, unsigned int length, int messageEnd, bool blocking)
{return m_owner.AttachedTransformation()->ChannelPutModifiable2(channel, begin, length, m_passSignal ? messageEnd : 0, blocking);}
void ChannelInitialize(const std::string &channel, const NameValuePairs &parameters, int propagation=-1)
{if (m_passSignal) m_owner.AttachedTransformation()->ChannelInitialize(channel, parameters, propagation);}
bool ChannelFlush(const std::string &channel, bool completeFlush, int propagation=-1, bool blocking=true)
{return m_passSignal ? m_owner.AttachedTransformation()->ChannelFlush(channel, completeFlush, propagation, blocking) : false;}
unsigned int ChannelPut2(const std::string &channel, const byte *begin, unsigned int length, int messageEnd, bool blocking)
{return m_owner.AttachedTransformation()->ChannelPut2(channel, begin, length, m_passSignal ? messageEnd : 0, blocking);}
unsigned int ChannelPutModifiable2(const std::string &channel, byte *begin, unsigned int length, int messageEnd, bool blocking)
{return m_owner.AttachedTransformation()->ChannelPutModifiable2(channel, begin, length, m_passSignal ? messageEnd : 0, blocking);}
void ChannelInitialize(const std::string &channel, const NameValuePairs &parameters, int propagation=-1)
{if (m_passSignal) m_owner.AttachedTransformation()->ChannelInitialize(channel, parameters, propagation);}
bool ChannelFlush(const std::string &channel, bool completeFlush, int propagation=-1, bool blocking=true)
{return m_passSignal ? m_owner.AttachedTransformation()->ChannelFlush(channel, completeFlush, propagation, blocking) : false;}
bool ChannelMessageSeriesEnd(const std::string &channel, int propagation=-1, bool blocking=true)
{return m_passSignal ? m_owner.AttachedTransformation()->ChannelMessageSeriesEnd(channel, propagation, blocking) : false;}
{return m_passSignal ? m_owner.AttachedTransformation()->ChannelMessageSeriesEnd(channel, propagation, blocking) : false;}
private:
BufferedTransformation &m_owner;
bool m_passSignal;
};
//! Base class for Filter classes that are proxies for a chain of other filters.
class ProxyFilter : public FilterWithBufferedInput
//! Base class for Filter classes that are proxies for a chain of other filters.
class ProxyFilter : public FilterWithBufferedInput
{
public:
ProxyFilter(BufferedTransformation *filter, unsigned int firstSize, unsigned int lastSize, BufferedTransformation *attachment);
ProxyFilter(BufferedTransformation *filter, unsigned int firstSize, unsigned int lastSize, BufferedTransformation *attachment);
void IsolatedFlush(bool completeFlush);
bool IsolatedFlush(bool hardFlush, bool blocking);
void SetFilter(Filter *filter);
void NextPutMultiple(const byte *s, unsigned int len);
void NextPutMultiple(const byte *s, unsigned int len);
protected:
member_ptr<BufferedTransformation> m_filter;
OutputProxy *m_proxy;
};
//! simple proxy filter that doesn't modify the underlying filter's input or output
class SimpleProxyFilter : public ProxyFilter
//! simple proxy filter that doesn't modify the underlying filter's input or output
class SimpleProxyFilter : public ProxyFilter
{
public:
SimpleProxyFilter(BufferedTransformation *filter, BufferedTransformation *attachment)
: ProxyFilter(filter, 0, 0, attachment) {}
: ProxyFilter(filter, 0, 0, attachment) {}
void FirstPut(const byte *) {}
void LastPut(const byte *, unsigned int) {m_filter->MessageEnd();}
void FirstPut(const byte *) {}
void LastPut(const byte *, unsigned int) {m_filter->MessageEnd();}
};
//! proxy for the filter created by PK_Encryptor::CreateEncryptionFilter
/*! This class is here just to provide symmetry with VerifierFilter. */
//! proxy for the filter created by PK_Encryptor::CreateEncryptionFilter
/*! This class is here just to provide symmetry with VerifierFilter. */
class PK_EncryptorFilter : public SimpleProxyFilter
{
public:
@ -470,31 +469,31 @@ public:
: SimpleProxyFilter(encryptor.CreateEncryptionFilter(rng), attachment) {}
};
//! proxy for the filter created by PK_Decryptor::CreateDecryptionFilter
/*! This class is here just to provide symmetry with SignerFilter. */
//! proxy for the filter created by PK_Decryptor::CreateDecryptionFilter
/*! This class is here just to provide symmetry with SignerFilter. */
class PK_DecryptorFilter : public SimpleProxyFilter
{
public:
PK_DecryptorFilter(const PK_Decryptor &decryptor, BufferedTransformation *attachment = NULL)
: SimpleProxyFilter(decryptor.CreateDecryptionFilter(), attachment) {}
: SimpleProxyFilter(decryptor.CreateDecryptionFilter(), attachment) {}
};
//! Append input to a string object
template <class T>
//! Append input to a string object
template <class T>
class StringSinkTemplate : public Bufferless<Sink>
{
public:
// VC60 workaround: no T::char_type
typedef typename T::traits_type::char_type char_type;
// VC60 workaround: no T::char_type
typedef typename T::traits_type::char_type char_type;
StringSinkTemplate(T &output)
: m_output(&output) {assert(sizeof(output[0])==1);}
: m_output(&output) {assert(sizeof(output[0])==1);}
void IsolatedInitialize(const NameValuePairs &parameters)
{if (!parameters.GetValue("OutputStringPointer", m_output)) throw InvalidArgument("StringSink: OutputStringPointer not specified");}
unsigned int Put2(const byte *begin, unsigned int length, int messageEnd, bool blocking)
{if (!parameters.GetValue("OutputStringPointer", m_output)) throw InvalidArgument("StringSink: OutputStringPointer not specified");}
unsigned int Put2(const byte *begin, unsigned int length, int messageEnd, bool blocking)
{
m_output->append((const char_type *)begin, (const char_type *)begin+length);
m_output->append((const char_type *)begin, (const char_type *)begin+length);
return 0;
}
@ -502,22 +501,22 @@ private:
T *m_output;
};
//! Append input to an std::string
typedef StringSinkTemplate<std::string> StringSink;
//! Append input to an std::string
typedef StringSinkTemplate<std::string> StringSink;
//! Copy input to a memory buffer
class ArraySink : public Bufferless<Sink>
//! Copy input to a memory buffer
class ArraySink : public Bufferless<Sink>
{
public:
ArraySink(const NameValuePairs &parameters = g_nullNameValuePairs) {IsolatedInitialize(parameters);}
ArraySink(byte *buf, unsigned int size) : m_buf(buf), m_size(size), m_total(0) {}
ArraySink(const NameValuePairs &parameters = g_nullNameValuePairs) {IsolatedInitialize(parameters);}
ArraySink(byte *buf, unsigned int size) : m_buf(buf), m_size(size), m_total(0) {}
unsigned int AvailableSize() {return m_size - STDMIN(m_total, (unsigned long)m_size);}
unsigned int AvailableSize() {return m_size - STDMIN(m_total, (unsigned long)m_size);}
unsigned long TotalPutLength() {return m_total;}
void IsolatedInitialize(const NameValuePairs &parameters);
byte * CreatePutSpace(unsigned int &size);
unsigned int Put2(const byte *begin, unsigned int length, int messageEnd, bool blocking);
unsigned int Put2(const byte *begin, unsigned int length, int messageEnd, bool blocking);
protected:
byte *m_buf;
@ -525,30 +524,30 @@ protected:
unsigned long m_total;
};
//! Xor input to a memory buffer
class ArrayXorSink : public ArraySink
//! Xor input to a memory buffer
class ArrayXorSink : public ArraySink
{
public:
ArrayXorSink(byte *buf, unsigned int size)
ArrayXorSink(byte *buf, unsigned int size)
: ArraySink(buf, size) {}
unsigned int Put2(const byte *begin, unsigned int length, int messageEnd, bool blocking);
unsigned int Put2(const byte *begin, unsigned int length, int messageEnd, bool blocking);
byte * CreatePutSpace(unsigned int &size) {return BufferedTransformation::CreatePutSpace(size);}
};
//! .
class StringStore : public Store
//! .
class StringStore : public Store
{
public:
StringStore(const char *string = NULL)
{StoreInitialize(MakeParameters("InputBuffer", ConstByteArrayParameter(string)));}
StringStore(const byte *string, unsigned int length)
StringStore(const byte *string, unsigned int length)
{StoreInitialize(MakeParameters("InputBuffer", ConstByteArrayParameter(string, length)));}
template <class T> StringStore(const T &string)
template <class T> StringStore(const T &string)
{StoreInitialize(MakeParameters("InputBuffer", ConstByteArrayParameter(string)));}
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;
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;
private:
void StoreInitialize(const NameValuePairs &parameters);
@ -557,64 +556,64 @@ private:
unsigned int m_length, m_count;
};
//! .
class RandomNumberStore : public Store
//! .
class RandomNumberStore : public Store
{
public:
RandomNumberStore(RandomNumberGenerator &rng, unsigned long length)
: m_rng(rng), m_length(length), m_count(0) {}
RandomNumberStore(RandomNumberGenerator &rng, unsigned long length)
: m_rng(rng), m_length(length), m_count(0) {}
bool AnyRetrievable() const {return MaxRetrievable() != 0;}
bool AnyRetrievable() const {return MaxRetrievable() != 0;}
unsigned long MaxRetrievable() const {return m_length-m_count;}
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
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("RandomNumberStore: CopyRangeTo2() is not supported by this store");
throw NotImplemented("RandomNumberStore: CopyRangeTo2() is not supported by this store");
}
private:
void StoreInitialize(const NameValuePairs &parameters) {m_count = 0;}
void StoreInitialize(const NameValuePairs &parameters) {m_count = 0;}
RandomNumberGenerator &m_rng;
const unsigned long m_length;
const unsigned long m_length;
unsigned long m_count;
};
//! .
class NullStore : public Store
//! .
class NullStore : public Store
{
public:
NullStore(unsigned long size = ULONG_MAX) : m_size(size) {}
NullStore(unsigned long size = ULONG_MAX) : m_size(size) {}
void StoreInitialize(const NameValuePairs &parameters) {}
unsigned long MaxRetrievable() const {return m_size;}
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;
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;
private:
unsigned long m_size;
};
//! A Filter that pumps data into its attachment as input
//! A Filter that pumps data into its attachment as input
class Source : public InputRejecting<Filter>
{
public:
Source(BufferedTransformation *attachment)
: InputRejecting<Filter>(attachment) {}
unsigned long Pump(unsigned long pumpMax=ULONG_MAX)
{Pump2(pumpMax); return pumpMax;}
unsigned long Pump(unsigned long pumpMax=ULONG_MAX)
{Pump2(pumpMax); return pumpMax;}
unsigned int PumpMessages(unsigned int count=UINT_MAX)
{PumpMessages2(count); return count;}
void PumpAll()
{PumpAll2();}
virtual unsigned int Pump2(unsigned long &byteCount, bool blocking=true) =0;
virtual unsigned int PumpMessages2(unsigned int &messageCount, bool blocking=true) =0;
virtual unsigned int PumpAll2(bool blocking=true);
virtual bool SourceExhausted() const =0;
virtual unsigned int Pump2(unsigned long &byteCount, bool blocking=true) =0;
virtual unsigned int PumpMessages2(unsigned int &messageCount, bool blocking=true) =0;
virtual unsigned int PumpAll2(bool blocking=true);
virtual bool SourceExhausted() const =0;
protected:
void SourceInitialize(bool pumpAll, const NameValuePairs &parameters)
void SourceInitialize(bool pumpAll, const NameValuePairs &parameters)
{
IsolatedInitialize(parameters);
if (pumpAll)
@ -622,59 +621,59 @@ protected:
}
};
//! Turn a Store into a Source
template <class T>
//! Turn a Store into a Source
template <class T>
class SourceTemplate : public Source
{
public:
SourceTemplate<T>(BufferedTransformation *attachment)
: Source(attachment) {}
SourceTemplate<T>(BufferedTransformation *attachment, T store)
SourceTemplate<T>(BufferedTransformation *attachment, T store)
: Source(attachment), m_store(store) {}
void IsolatedInitialize(const NameValuePairs &parameters)
{m_store.IsolatedInitialize(parameters);}
unsigned int Pump2(unsigned long &byteCount, bool blocking=true)
{return m_store.TransferTo2(*AttachedTransformation(), byteCount, NULL_CHANNEL, blocking);}
unsigned int PumpMessages2(unsigned int &messageCount, bool blocking=true)
{return m_store.TransferMessagesTo2(*AttachedTransformation(), messageCount, NULL_CHANNEL, blocking);}
unsigned int Pump2(unsigned long &byteCount, bool blocking=true)
{return m_store.TransferTo2(*AttachedTransformation(), byteCount, NULL_CHANNEL, blocking);}
unsigned int PumpMessages2(unsigned int &messageCount, bool blocking=true)
{return m_store.TransferMessagesTo2(*AttachedTransformation(), messageCount, NULL_CHANNEL, blocking);}
unsigned int PumpAll2(bool blocking=true)
{return m_store.TransferAllTo2(*AttachedTransformation(), NULL_CHANNEL, blocking);}
{return m_store.TransferAllTo2(*AttachedTransformation(), NULL_CHANNEL, blocking);}
bool SourceExhausted() const
{return !m_store.AnyRetrievable() && !m_store.AnyMessages();}
{return !m_store.AnyRetrievable() && !m_store.AnyMessages();}
void SetAutoSignalPropagation(int propagation)
{m_store.SetAutoSignalPropagation(propagation);}
int GetAutoSignalPropagation() const
{return m_store.GetAutoSignalPropagation();}
int GetAutoSignalPropagation() const
{return m_store.GetAutoSignalPropagation();}
protected:
T m_store;
};
//! .
class StringSource : public SourceTemplate<StringStore>
//! .
class StringSource : public SourceTemplate<StringStore>
{
public:
StringSource(BufferedTransformation *attachment = NULL)
StringSource(BufferedTransformation *attachment = NULL)
: SourceTemplate<StringStore>(attachment) {}
StringSource(const char *string, bool pumpAll, BufferedTransformation *attachment = NULL)
StringSource(const char *string, bool pumpAll, BufferedTransformation *attachment = NULL)
: SourceTemplate<StringStore>(attachment) {SourceInitialize(pumpAll, MakeParameters("InputBuffer", ConstByteArrayParameter(string)));}
StringSource(const byte *string, unsigned int length, bool pumpAll, BufferedTransformation *attachment = NULL)
StringSource(const byte *string, unsigned int length, bool pumpAll, BufferedTransformation *attachment = NULL)
: SourceTemplate<StringStore>(attachment) {SourceInitialize(pumpAll, MakeParameters("InputBuffer", ConstByteArrayParameter(string, length)));}
#ifdef __MWERKS__ // CW60 workaround
StringSource(const std::string &string, bool pumpAll, BufferedTransformation *attachment = NULL)
#ifdef __MWERKS__ // CW60 workaround
StringSource(const std::string &string, bool pumpAll, BufferedTransformation *attachment = NULL)
#else
template <class T> StringSource(const T &string, bool pumpAll, BufferedTransformation *attachment = NULL)
template <class T> StringSource(const T &string, bool pumpAll, BufferedTransformation *attachment = NULL)
#endif
: SourceTemplate<StringStore>(attachment) {SourceInitialize(pumpAll, MakeParameters("InputBuffer", ConstByteArrayParameter(string)));}
};
//! .
//! .
class RandomNumberSource : public SourceTemplate<RandomNumberStore>
{
public:
RandomNumberSource(RandomNumberGenerator &rng, unsigned int length, bool pumpAll, BufferedTransformation *attachment = NULL)
: SourceTemplate<RandomNumberStore>(attachment, RandomNumberStore(rng, length)) {if (pumpAll) PumpAll();}
RandomNumberSource(RandomNumberGenerator &rng, unsigned int length, bool pumpAll, BufferedTransformation *attachment = NULL)
: SourceTemplate<RandomNumberStore>(attachment, RandomNumberStore(rng, length)) {if (pumpAll) PumpAll();}
};
NAMESPACE_END

280
modes.h
View File

@ -1,7 +1,7 @@
#ifndef CRYPTOPP_MODES_H
#define CRYPTOPP_MODES_H
#ifndef CRYPTOPP_MODES_H
#define CRYPTOPP_MODES_H
/*! \file
/*! \file
*/
#include "cryptlib.h"
@ -12,67 +12,67 @@
NAMESPACE_BEGIN(CryptoPP)
//! Cipher mode documentation. See NIST SP 800-38A for definitions of these modes.
//! 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.
/*! 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
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);}
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);
void SetKey(const byte *key, unsigned int length, const NameValuePairs &params = g_nullNameValuePairs);
unsigned int OptimalDataAlignment() const {return BlockSize();}
unsigned int OptimalDataAlignment() const {return BlockSize();}
unsigned int IVSize() const {return BlockSize();}
void GetNextIV(byte *IV);
virtual IV_Requirement IVRequirement() const =0;
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();}
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)
virtual void SetFeedbackSize(unsigned int feedbackSize)
{
if (!(feedbackSize == 0 || feedbackSize == BlockSize()))
throw InvalidArgument("CipherModeBase: feedback size cannot be specified for this cipher mode");
if (!(feedbackSize == 0 || feedbackSize == BlockSize()))
throw InvalidArgument("CipherModeBase: feedback size cannot be specified for this cipher mode");
}
virtual void ResizeBuffers()
virtual void ResizeBuffers()
{
m_register.New(m_cipher->BlockSize());
}
virtual void UncheckedSetKey(const NameValuePairs &params, const byte *key, unsigned int length) =0;
virtual void UncheckedSetKey(const NameValuePairs &params, const byte *key, unsigned int length) =0;
BlockCipher *m_cipher;
BlockCipher *m_cipher;
SecByteBlock m_register;
};
template <class POLICY_INTERFACE>
class ModePolicyCommonTemplate : public CipherModeBase, public POLICY_INTERFACE
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)
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);
int feedbackSize = params.GetIntValueWithDefault(Name::FeedbackSize(), 0);
SetFeedbackSize(feedbackSize);
const byte *iv = params.GetValueWithDefault(Name::IV(), (const byte *)NULL);
const byte *iv = params.GetValueWithDefault(Name::IV(), (const byte *)NULL);
SetIV(iv);
}
};
@ -83,15 +83,15 @@ public:
IV_Requirement IVRequirement() const {return RANDOM_IV;}
protected:
unsigned int GetBytesPerIteration() const {return m_feedbackSize;}
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);
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)
void CipherResynchronize(const byte *iv)
{
memcpy(m_register, iv, BlockSize());
TransformRegister();
@ -100,7 +100,7 @@ protected:
{
if (feedbackSize > BlockSize())
throw InvalidArgument("CFB_Mode: invalid feedback size");
m_feedbackSize = feedbackSize ? feedbackSize : BlockSize();
m_feedbackSize = feedbackSize ? feedbackSize : BlockSize();
}
void ResizeBuffers()
{
@ -114,65 +114,65 @@ protected:
class OFB_ModePolicy : public ModePolicyCommonTemplate<AdditiveCipherAbstractPolicy>
{
unsigned int GetBytesPerIteration() const {return BlockSize();}
unsigned int GetBytesPerIteration() const {return BlockSize();}
unsigned int GetIterationsToBuffer() const {return 1;}
void WriteKeystream(byte *keystreamBuffer, unsigned int iterationCount)
void WriteKeystream(byte *keystreamBuffer, unsigned int iterationCount)
{
assert(iterationCount == 1);
m_cipher->ProcessBlock(keystreamBuffer);
}
void CipherResynchronize(byte *keystreamBuffer, const byte *iv)
void CipherResynchronize(byte *keystreamBuffer, const byte *iv)
{
memcpy(keystreamBuffer, iv, BlockSize());
memcpy(keystreamBuffer, iv, BlockSize());
}
bool IsRandomAccess() const {return false;}
bool IsRandomAccess() const {return false;}
IV_Requirement IVRequirement() const {return STRUCTURED_IV;}
};
class CTR_ModePolicy : public ModePolicyCommonTemplate<AdditiveCipherAbstractPolicy>
{
unsigned int GetBytesPerIteration() const {return BlockSize();}
unsigned int GetBytesPerIteration() const {return BlockSize();}
unsigned int GetIterationsToBuffer() const {return m_cipher->OptimalNumberOfParallelBlocks();}
void WriteKeystream(byte *buffer, unsigned int iterationCount)
{OperateKeystream(WRITE_KEYSTREAM, buffer, NULL, iterationCount);}
bool CanOperateKeystream() const {return true;}
void OperateKeystream(KeystreamOperation operation, byte *output, const byte *input, unsigned int iterationCount);
void CipherResynchronize(byte *keystreamBuffer, const byte *iv);
bool IsRandomAccess() const {return true;}
void OperateKeystream(KeystreamOperation operation, byte *output, const byte *input, unsigned int iterationCount);
void CipherResynchronize(byte *keystreamBuffer, const byte *iv);
bool IsRandomAccess() const {return true;}
void SeekToIteration(dword iterationCount);
IV_Requirement IVRequirement() const {return STRUCTURED_IV;}
static inline void IncrementCounterByOne(byte *output, const byte *input, unsigned int s)
{
for (int i=s-1, carry=1; i>=0 && carry; i--)
carry = !(output[i] = input[i]+1);
for (int i=s-1, carry=1; i>=0; i--)
carry = !(output[i] = input[i]+1);
}
inline void ProcessMultipleBlocks(byte *output, const byte *input, unsigned int n)
inline void ProcessMultipleBlocks(byte *output, const byte *input, unsigned int n)
{
unsigned int s = BlockSize(), j = 0;
for (unsigned int i=1; i<n; i++, j+=s)
unsigned int s = BlockSize(), j = 0;
for (unsigned int i=1; i<n; i++, j+=s)
IncrementCounterByOne(m_counterArray + j + s, m_counterArray + j, s);
m_cipher->ProcessAndXorMultipleBlocks(m_counterArray, input, output, n);
IncrementCounterByOne(m_counterArray, m_counterArray + s*(n-1), s);
IncrementCounterByOne(m_counterArray, m_counterArray + s*(n-1), s);
}
SecByteBlock m_counterArray;
};
class BlockOrientedCipherModeBase : public CipherModeBase
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;}
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);
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;
virtual void ProcessBlocks(byte *outString, const byte *inString, unsigned int numberOfBlocks) =0;
void ResizeBuffers()
{
CipherModeBase::ResizeBuffers();
@ -186,23 +186,23 @@ class ECB_OneWay : public BlockOrientedCipherModeBase
{
public:
IV_Requirement IVRequirement() const {return NOT_RESYNCHRONIZABLE;}
unsigned int OptimalBlockSize() const {return BlockSize() * m_cipher->OptimalNumberOfParallelBlocks();}
void ProcessBlocks(byte *outString, const byte *inString, unsigned int numberOfBlocks)
unsigned int OptimalBlockSize() const {return BlockSize() * m_cipher->OptimalNumberOfParallelBlocks();}
void ProcessBlocks(byte *outString, const byte *inString, unsigned int numberOfBlocks)
{m_cipher->ProcessAndXorMultipleBlocks(inString, NULL, outString, numberOfBlocks);}
};
class CBC_ModeBase : public BlockOrientedCipherModeBase
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;}
unsigned int MinLastBlockSize() const {return 0;}
};
class CBC_Encryption : public CBC_ModeBase
{
public:
void ProcessBlocks(byte *outString, const byte *inString, unsigned int numberOfBlocks);
void ProcessBlocks(byte *outString, const byte *inString, unsigned int numberOfBlocks);
};
class CBC_CTS_Encryption : public CBC_Encryption
@ -211,12 +211,12 @@ public:
void SetStolenIV(byte *iv) {m_stolenIV = iv;}
protected:
void UncheckedSetKey(const NameValuePairs &params, const byte *key, unsigned int length)
void UncheckedSetKey(const NameValuePairs &params, const byte *key, unsigned int length)
{
CBC_Encryption::UncheckedSetKey(params, key, length);
m_stolenIV = params.GetValueWithDefault(Name::StolenIV(), (byte *)NULL);
CBC_Encryption::UncheckedSetKey(params, key, length);
m_stolenIV = params.GetValueWithDefault(Name::StolenIV(), (byte *)NULL);
}
unsigned int MinLastBlockSize() const {return BlockSize()+1;}
unsigned int MinLastBlockSize() const {return BlockSize()+1;}
void ProcessLastBlock(byte *outString, const byte *inString, unsigned int length);
byte *m_stolenIV;
@ -225,7 +225,7 @@ protected:
class CBC_Decryption : public CBC_ModeBase
{
public:
void ProcessBlocks(byte *outString, const byte *inString, unsigned int numberOfBlocks);
void ProcessBlocks(byte *outString, const byte *inString, unsigned int numberOfBlocks);
protected:
void ResizeBuffers()
@ -238,13 +238,13 @@ protected:
class CBC_CTS_Decryption : public CBC_Decryption
{
unsigned int MinLastBlockSize() const {return BlockSize()+1;}
unsigned int MinLastBlockSize() const {return BlockSize()+1;}
void ProcessLastBlock(byte *outString, const byte *inString, unsigned int length);
};
//! .
template <class CIPHER, class BASE>
class CipherModeFinalTemplate_CipherHolder : public ObjectHolder<CIPHER>, public BASE
//! .
template <class CIPHER, class BASE>
class CipherModeFinalTemplate_CipherHolder : public ObjectHolder<CIPHER>, public BASE
{
public:
CipherModeFinalTemplate_CipherHolder()
@ -252,24 +252,24 @@ public:
m_cipher = &m_object;
ResizeBuffers();
}
CipherModeFinalTemplate_CipherHolder(const byte *key, unsigned int length)
CipherModeFinalTemplate_CipherHolder(const byte *key, unsigned int length)
{
m_cipher = &m_object;
SetKey(key, length);
SetKey(key, length);
}
CipherModeFinalTemplate_CipherHolder(const byte *key, unsigned int length, const byte *iv, int feedbackSize = 0)
CipherModeFinalTemplate_CipherHolder(const byte *key, unsigned int length, const byte *iv, int feedbackSize = 0)
{
m_cipher = &m_object;
SetKey(key, length, MakeParameters("IV", iv)("FeedbackSize", feedbackSize));
SetKey(key, length, MakeParameters("IV", iv)("FeedbackSize", feedbackSize));
}
};
//! .
template <class BASE>
//! .
template <class BASE>
class CipherModeFinalTemplate_ExternalCipher : public BASE
{
public:
CipherModeFinalTemplate_ExternalCipher(BlockCipher &cipher, const byte *iv = NULL, int feedbackSize = 0)
CipherModeFinalTemplate_ExternalCipher(BlockCipher &cipher, const byte *iv = NULL, int feedbackSize = 0)
{
m_cipher = &cipher;
ResizeBuffers();
@ -278,101 +278,101 @@ public:
}
};
//! CFB mode
template <class CIPHER>
struct CFB_Mode : public CipherModeDocumentation
//! 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;
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;
};
//! CFB mode, external cipher
struct CFB_Mode_ExternalCipher : public CipherModeDocumentation
//! CFB mode, external cipher
struct CFB_Mode_ExternalCipher : public CipherModeDocumentation
{
typedef CipherModeFinalTemplate_ExternalCipher<ConcretePolicyHolder<Empty, CFB_EncryptionTemplate<AbstractPolicyHolder<CFB_CipherAbstractPolicy, CFB_ModePolicy> > > > Encryption;
typedef CipherModeFinalTemplate_ExternalCipher<ConcretePolicyHolder<Empty, CFB_DecryptionTemplate<AbstractPolicyHolder<CFB_CipherAbstractPolicy, CFB_ModePolicy> > > > Decryption;
typedef CipherModeFinalTemplate_ExternalCipher<ConcretePolicyHolder<Empty, CFB_EncryptionTemplate<AbstractPolicyHolder<CFB_CipherAbstractPolicy, CFB_ModePolicy> > > > Encryption;
typedef CipherModeFinalTemplate_ExternalCipher<ConcretePolicyHolder<Empty, CFB_DecryptionTemplate<AbstractPolicyHolder<CFB_CipherAbstractPolicy, CFB_ModePolicy> > > > Decryption;
};
//! OFB mode
template <class CIPHER>
struct OFB_Mode : public CipherModeDocumentation
//! OFB mode
template <class CIPHER>
struct OFB_Mode : public CipherModeDocumentation
{
typedef CipherModeFinalTemplate_CipherHolder<CPP_TYPENAME CIPHER::Encryption, ConcretePolicyHolder<Empty, AdditiveCipherTemplate<AbstractPolicyHolder<AdditiveCipherAbstractPolicy, OFB_ModePolicy> > > > Encryption;
typedef Encryption Decryption;
typedef CipherModeFinalTemplate_CipherHolder<CPP_TYPENAME CIPHER::Encryption, ConcretePolicyHolder<Empty, AdditiveCipherTemplate<AbstractPolicyHolder<AdditiveCipherAbstractPolicy, OFB_ModePolicy> > > > Encryption;
typedef Encryption Decryption;
};
//! OFB mode, external cipher
struct OFB_Mode_ExternalCipher : public CipherModeDocumentation
//! OFB mode, external cipher
struct OFB_Mode_ExternalCipher : public CipherModeDocumentation
{
typedef CipherModeFinalTemplate_ExternalCipher<ConcretePolicyHolder<Empty, AdditiveCipherTemplate<AbstractPolicyHolder<AdditiveCipherAbstractPolicy, OFB_ModePolicy> > > > Encryption;
typedef Encryption Decryption;
typedef CipherModeFinalTemplate_ExternalCipher<ConcretePolicyHolder<Empty, AdditiveCipherTemplate<AbstractPolicyHolder<AdditiveCipherAbstractPolicy, OFB_ModePolicy> > > > Encryption;
typedef Encryption Decryption;
};
//! CTR mode
template <class CIPHER>
struct CTR_Mode : public CipherModeDocumentation
//! CTR mode
template <class CIPHER>
struct CTR_Mode : public CipherModeDocumentation
{
typedef CipherModeFinalTemplate_CipherHolder<CPP_TYPENAME CIPHER::Encryption, ConcretePolicyHolder<Empty, AdditiveCipherTemplate<AbstractPolicyHolder<AdditiveCipherAbstractPolicy, CTR_ModePolicy> > > > Encryption;
typedef Encryption Decryption;
typedef CipherModeFinalTemplate_CipherHolder<CPP_TYPENAME CIPHER::Encryption, ConcretePolicyHolder<Empty, AdditiveCipherTemplate<AbstractPolicyHolder<AdditiveCipherAbstractPolicy, CTR_ModePolicy> > > > Encryption;
typedef Encryption Decryption;
};
//! CTR mode, external cipher
struct CTR_Mode_ExternalCipher : public CipherModeDocumentation
//! CTR mode, external cipher
struct CTR_Mode_ExternalCipher : public CipherModeDocumentation
{
typedef CipherModeFinalTemplate_ExternalCipher<ConcretePolicyHolder<Empty, AdditiveCipherTemplate<AbstractPolicyHolder<AdditiveCipherAbstractPolicy, CTR_ModePolicy> > > > Encryption;
typedef Encryption Decryption;
typedef CipherModeFinalTemplate_ExternalCipher<ConcretePolicyHolder<Empty, AdditiveCipherTemplate<AbstractPolicyHolder<AdditiveCipherAbstractPolicy, CTR_ModePolicy> > > > Encryption;
typedef Encryption Decryption;
};
//! ECB mode
template <class CIPHER>
struct ECB_Mode : public CipherModeDocumentation
//! ECB mode
template <class CIPHER>
struct ECB_Mode : public CipherModeDocumentation
{
typedef CipherModeFinalTemplate_CipherHolder<CPP_TYPENAME CIPHER::Encryption, ECB_OneWay> Encryption;
typedef CipherModeFinalTemplate_CipherHolder<CPP_TYPENAME CIPHER::Decryption, ECB_OneWay> Decryption;
typedef CipherModeFinalTemplate_CipherHolder<CPP_TYPENAME CIPHER::Encryption, ECB_OneWay> Encryption;
typedef CipherModeFinalTemplate_CipherHolder<CPP_TYPENAME CIPHER::Decryption, ECB_OneWay> Decryption;
};
//! ECB mode, external cipher
struct ECB_Mode_ExternalCipher : public CipherModeDocumentation
//! ECB mode, external cipher
struct ECB_Mode_ExternalCipher : public CipherModeDocumentation
{
typedef CipherModeFinalTemplate_ExternalCipher<ECB_OneWay> Encryption;
typedef Encryption Decryption;
typedef CipherModeFinalTemplate_ExternalCipher<ECB_OneWay> Encryption;
typedef Encryption Decryption;
};
//! CBC mode
template <class CIPHER>
struct CBC_Mode : public CipherModeDocumentation
//! CBC mode
template <class CIPHER>
struct CBC_Mode : public CipherModeDocumentation
{
typedef CipherModeFinalTemplate_CipherHolder<CPP_TYPENAME CIPHER::Encryption, CBC_Encryption> Encryption;
typedef CipherModeFinalTemplate_CipherHolder<CPP_TYPENAME CIPHER::Decryption, CBC_Decryption> Decryption;
typedef CipherModeFinalTemplate_CipherHolder<CPP_TYPENAME CIPHER::Encryption, CBC_Encryption> Encryption;
typedef CipherModeFinalTemplate_CipherHolder<CPP_TYPENAME CIPHER::Decryption, CBC_Decryption> Decryption;
};
//! CBC mode, external cipher
struct CBC_Mode_ExternalCipher : public CipherModeDocumentation
//! CBC mode, external cipher
struct CBC_Mode_ExternalCipher : public CipherModeDocumentation
{
typedef CipherModeFinalTemplate_ExternalCipher<CBC_Encryption> Encryption;
typedef CipherModeFinalTemplate_ExternalCipher<CBC_Decryption> Decryption;
typedef CipherModeFinalTemplate_ExternalCipher<CBC_Encryption> Encryption;
typedef CipherModeFinalTemplate_ExternalCipher<CBC_Decryption> Decryption;
};
//! CBC mode with ciphertext stealing
template <class CIPHER>
struct CBC_CTS_Mode : public CipherModeDocumentation
//! CBC mode with ciphertext stealing
template <class CIPHER>
struct CBC_CTS_Mode : public CipherModeDocumentation
{
typedef CipherModeFinalTemplate_CipherHolder<CPP_TYPENAME CIPHER::Encryption, CBC_CTS_Encryption> Encryption;
typedef CipherModeFinalTemplate_CipherHolder<CPP_TYPENAME CIPHER::Decryption, CBC_CTS_Decryption> Decryption;
typedef CipherModeFinalTemplate_CipherHolder<CPP_TYPENAME CIPHER::Encryption, CBC_CTS_Encryption> Encryption;
typedef CipherModeFinalTemplate_CipherHolder<CPP_TYPENAME CIPHER::Decryption, CBC_CTS_Decryption> Decryption;
};
//! CBC mode with ciphertext stealing, external cipher
struct CBC_CTS_Mode_ExternalCipher : public CipherModeDocumentation
//! CBC mode with ciphertext stealing, external cipher
struct CBC_CTS_Mode_ExternalCipher : public CipherModeDocumentation
{
typedef CipherModeFinalTemplate_ExternalCipher<CBC_CTS_Encryption> Encryption;
typedef CipherModeFinalTemplate_ExternalCipher<CBC_CTS_Decryption> Decryption;
typedef CipherModeFinalTemplate_ExternalCipher<CBC_CTS_Encryption> Encryption;
typedef CipherModeFinalTemplate_ExternalCipher<CBC_CTS_Decryption> Decryption;
};
#ifdef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY
typedef CFB_Mode_ExternalCipher::Encryption CFBEncryption;
typedef CFB_Mode_ExternalCipher::Decryption CFBDecryption;
typedef OFB_Mode_ExternalCipher::Encryption OFB;
typedef OFB_Mode_ExternalCipher::Encryption CounterMode;
typedef CFB_Mode_ExternalCipher::Encryption CFBEncryption;
typedef CFB_Mode_ExternalCipher::Decryption CFBDecryption;
typedef OFB_Mode_ExternalCipher::Encryption OFB;
typedef OFB_Mode_ExternalCipher::Encryption CounterMode;
#endif
NAMESPACE_END