From b21162cf8e06f40baa1f58be6a8c17435cebc34d Mon Sep 17 00:00:00 2001 From: weidai Date: Fri, 4 Oct 2002 17:31:41 +0000 Subject: Initial revision git-svn-id: svn://svn.code.sf.net/p/cryptopp/code/trunk/c5@2 57ff6487-cd31-0410-9ec3-f628ee90f5f0 --- strciphr.cpp | 188 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 188 insertions(+) create mode 100644 strciphr.cpp (limited to 'strciphr.cpp') diff --git a/strciphr.cpp b/strciphr.cpp new file mode 100644 index 0000000..694d158 --- /dev/null +++ b/strciphr.cpp @@ -0,0 +1,188 @@ +// strciphr.cpp - written and placed in the public domain by Wei Dai + +#include "pch.h" +#include "strciphr.h" + +NAMESPACE_BEGIN(CryptoPP) + +template +byte AdditiveCipherTemplate::GenerateByte() +{ + PolicyInterface &policy = AccessPolicy(); + + if (m_leftOver == 0) + { + policy.WriteKeystream(m_buffer, policy.GetIterationsToBuffer()); + m_leftOver = policy.GetBytesPerIteration(); + } + + return KeystreamBufferEnd()[-m_leftOver--]; +} + +template +inline void AdditiveCipherTemplate::ProcessData(byte *outString, const byte *inString, unsigned int length) +{ + if (m_leftOver > 0) + { + unsigned int len = STDMIN(m_leftOver, length); + xorbuf(outString, inString, KeystreamBufferEnd()-m_leftOver, len); + length -= len; + m_leftOver -= len; + inString += len; + outString += len; + } + + if (!length) + return; + + assert(m_leftOver == 0); + + PolicyInterface &policy = AccessPolicy(); + unsigned int bytesPerIteration = policy.GetBytesPerIteration(); + unsigned int alignment = policy.GetAlignment(); + + if (policy.CanOperateKeystream() && length >= bytesPerIteration && IsAlignedOn(outString, alignment)) + { + if (IsAlignedOn(inString, alignment)) + policy.OperateKeystream(XOR_KEYSTREAM, outString, inString, length / bytesPerIteration); + else + { + memcpy(outString, inString, length); + policy.OperateKeystream(XOR_KEYSTREAM_INPLACE, outString, outString, length / bytesPerIteration); + } + inString += length - length % bytesPerIteration; + outString += length - length % bytesPerIteration; + length %= bytesPerIteration; + + if (!length) + return; + } + + unsigned int bufferByteSize = GetBufferByteSize(policy); + unsigned int bufferIterations = policy.GetIterationsToBuffer(); + + while (length >= bufferByteSize) + { + policy.WriteKeystream(m_buffer, bufferIterations); + xorbuf(outString, inString, KeystreamBufferBegin(), bufferByteSize); + length -= bufferByteSize; + inString += bufferByteSize; + outString += bufferByteSize; + } + + if (length > 0) + { + policy.WriteKeystream(m_buffer, bufferIterations); + xorbuf(outString, inString, KeystreamBufferBegin(), length); + m_leftOver = bytesPerIteration - length; + } +} + +template +void AdditiveCipherTemplate::Resynchronize(const byte *iv) +{ + PolicyInterface &policy = AccessPolicy(); + m_leftOver = 0; + m_buffer.New(GetBufferByteSize(policy)); + policy.CipherResynchronize(m_buffer, iv); +} + +template +void AdditiveCipherTemplate::Seek(dword position) +{ + PolicyInterface &policy = AccessPolicy(); + unsigned int bytesPerIteration = policy.GetBytesPerIteration(); + + policy.SeekToIteration(position / bytesPerIteration); + position %= bytesPerIteration; + + if (position > 0) + { + policy.WriteKeystream(m_buffer, 1); + m_leftOver = bytesPerIteration - position; + } + else + m_leftOver = 0; +} + +template +void CFB_CipherTemplate::Resynchronize(const byte *iv) +{ + PolicyInterface &policy = AccessPolicy(); + policy.CipherResynchronize(iv); + m_leftOver = policy.GetBytesPerIteration(); +} + +template +void CFB_CipherTemplate::ProcessData(byte *outString, const byte *inString, unsigned int length) +{ + PolicyInterface &policy = AccessPolicy(); + unsigned int bytesPerIteration = policy.GetBytesPerIteration(); + unsigned int alignment = policy.GetAlignment(); + byte *reg = policy.GetRegisterBegin(); + + if (m_leftOver) + { + unsigned int len = STDMIN(m_leftOver, length); + CombineMessageAndShiftRegister(outString, reg + bytesPerIteration - m_leftOver, inString, len); + m_leftOver -= len; + length -= len; + inString += len; + outString += len; + } + + if (!length) + return; + + assert(m_leftOver == 0); + + if (policy.CanIterate() && length >= bytesPerIteration && IsAlignedOn(outString, alignment)) + { + if (IsAlignedOn(inString, alignment)) + policy.Iterate(outString, inString, GetCipherDir(*this), length / bytesPerIteration); + else + { + memcpy(outString, inString, length); + policy.Iterate(outString, outString, GetCipherDir(*this), length / bytesPerIteration); + } + inString += length - length % bytesPerIteration; + outString += length - length % bytesPerIteration; + length %= bytesPerIteration; + } + + while (length >= bytesPerIteration) + { + policy.TransformRegister(); + CombineMessageAndShiftRegister(outString, reg, inString, bytesPerIteration); + length -= bytesPerIteration; + inString += bytesPerIteration; + outString += bytesPerIteration; + } + + if (length > 0) + { + policy.TransformRegister(); + CombineMessageAndShiftRegister(outString, reg, inString, length); + m_leftOver = bytesPerIteration - length; + } +} + +template +void CFB_EncryptionTemplate::CombineMessageAndShiftRegister(byte *output, byte *reg, const byte *message, unsigned int length) +{ + xorbuf(reg, message, length); + memcpy(output, reg, length); +} + +template +void CFB_DecryptionTemplate::CombineMessageAndShiftRegister(byte *output, byte *reg, const byte *message, unsigned int length) +{ + for (unsigned int i=0; i