Main Page | Namespace List | Class Hierarchy | Alphabetical List | Compound List | File List | Namespace Members | Compound Members | File Members

# strciphr.cpp

    00001 // strciphr.cpp - written and placed in the public domain by Wei Dai
    00002
    00003 #include "pch.h"
    00004
    00005 #ifndef CRYPTOPP_IMPORTS
    00006
    00007 #include "strciphr.h"
    00008
    00009 NAMESPACE_BEGIN(CryptoPP)
    00010
    00011 template <class S>
    00012 byte AdditiveCipherTemplate<S>::GenerateByte()
    00013 {
    00014         PolicyInterface &policy = AccessPolicy();
    00015
    00016         if (m_leftOver == 0)
    00017         {
    00018                 policy.WriteKeystream(m_buffer, policy.GetIterationsToBuffer());
    00019                 m_leftOver = policy.GetBytesPerIteration();
    00020         }
    00021
    00022         return KeystreamBufferEnd()[-m_leftOver--];
    00023 }
    00024
    00025 template <class S>
    00026 inline void AdditiveCipherTemplate<S>::ProcessData(byte *outString, const byte *inString, unsigned int length)
    00027 {
    00028         if (m_leftOver > 0)
    00029         {
    00030                 unsigned int len = STDMIN(m_leftOver, length);
    00031                 xorbuf(outString, inString, KeystreamBufferEnd()-m_leftOver, len);
    00032                 length -= len;
    00033                 m_leftOver -= len;
    00034                 inString += len;
    00035                 outString += len;
    00036         }
    00037
    00038         if (!length)
    00039                 return;
    00040
    00041         assert(m_leftOver == 0);
    00042
    00043         PolicyInterface &policy = AccessPolicy();
    00044         unsigned int bytesPerIteration = policy.GetBytesPerIteration();
    00045         unsigned int alignment = policy.GetAlignment();
    00046
    00047         if (policy.CanOperateKeystream() && length >= bytesPerIteration && IsAlignedOn(outString, alignment))
    00048         {
    00049                 if (IsAlignedOn(inString, alignment))
    00050                         policy.OperateKeystream(XOR_KEYSTREAM, outString, inString, length / bytesPerIteration);
    00051                 else
    00052                 {
    00053                         memcpy(outString, inString, length);
    00054                         policy.OperateKeystream(XOR_KEYSTREAM_INPLACE, outString, outString, length / bytesPerIteration);
    00055                 }
    00056                 inString += length - length % bytesPerIteration;
    00057                 outString += length - length % bytesPerIteration;
    00058                 length %= bytesPerIteration;
    00059
    00060                 if (!length)
    00061                         return;
    00062         }
    00063
    00064         unsigned int bufferByteSize = GetBufferByteSize(policy);
    00065         unsigned int bufferIterations = policy.GetIterationsToBuffer();
    00066
    00067         while (length >= bufferByteSize)
    00068         {
    00069                 policy.WriteKeystream(m_buffer, bufferIterations);
    00070                 xorbuf(outString, inString, KeystreamBufferBegin(), bufferByteSize);
    00071                 length -= bufferByteSize;
    00072                 inString += bufferByteSize;
    00073                 outString += bufferByteSize;
    00074         }
    00075
    00076         if (length > 0)
    00077         {
    00078                 policy.WriteKeystream(m_buffer, bufferIterations);
    00079                 xorbuf(outString, inString, KeystreamBufferBegin(), length);
    00080                 m_leftOver = bytesPerIteration - length;
    00081         }
    00082 }
    00083
    00084 template <class S>
    00085 void AdditiveCipherTemplate<S>::Resynchronize(const byte *iv)
    00086 {
    00087         PolicyInterface &policy = AccessPolicy();
    00088         m_leftOver = 0;
    00089         m_buffer.New(GetBufferByteSize(policy));
    00090         policy.CipherResynchronize(m_buffer, iv);
    00091 }
    00092
    00093 template <class BASE>
    00094 void AdditiveCipherTemplate<BASE>::Seek(dword position)
    00095 {
    00096         PolicyInterface &policy = AccessPolicy();
    00097         unsigned int bytesPerIteration = policy.GetBytesPerIteration();
    00098
    00099         policy.SeekToIteration(position / bytesPerIteration);
    00100         position %= bytesPerIteration;
    00101
    00102         if (position > 0)
    00103         {
    00104                 policy.WriteKeystream(m_buffer, 1);
    00105                 m_leftOver = bytesPerIteration - position;
    00106         }
    00107         else
    00108                 m_leftOver = 0;
    00109 }
    00110
    00111 template <class BASE>
    00112 void CFB_CipherTemplate<BASE>::Resynchronize(const byte *iv)
    00113 {
    00114         PolicyInterface &policy = AccessPolicy();
    00115         policy.CipherResynchronize(iv);
    00116         m_leftOver = policy.GetBytesPerIteration();
    00117 }
    00118
    00119 template <class BASE>
    00120 void CFB_CipherTemplate<BASE>::ProcessData(byte *outString, const byte *inString, unsigned int length)
    00121 {
    00122         PolicyInterface &policy = AccessPolicy();
    00123         unsigned int bytesPerIteration = policy.GetBytesPerIteration();
    00124         unsigned int alignment = policy.GetAlignment();
    00125         byte *reg = policy.GetRegisterBegin();
    00126
    00127         if (m_leftOver)
    00128         {
    00129                 unsigned int len = STDMIN(m_leftOver, length);
    00130                 CombineMessageAndShiftRegister(outString, reg + bytesPerIteration - m_leftOver, inString, len);
    00131                 m_leftOver -= len;
    00132                 length -= len;
    00133                 inString += len;
    00134                 outString += len;
    00135         }
    00136
    00137         if (!length)
    00138                 return;
    00139
    00140         assert(m_leftOver == 0);
    00141
    00142         if (policy.CanIterate() && length >= bytesPerIteration && IsAlignedOn(outString, alignment))
    00143         {
    00144                 if (IsAlignedOn(inString, alignment))
    00145                         policy.Iterate(outString, inString, GetCipherDir(*this), length / bytesPerIteration);
    00146                 else
    00147                 {
    00148                         memcpy(outString, inString, length);
    00149                         policy.Iterate(outString, outString, GetCipherDir(*this), length / bytesPerIteration);
    00150                 }
    00151                 inString += length - length % bytesPerIteration;
    00152                 outString += length - length % bytesPerIteration;
    00153                 length %= bytesPerIteration;
    00154         }
    00155
    00156         while (length >= bytesPerIteration)
    00157         {
    00158                 policy.TransformRegister();
    00159                 CombineMessageAndShiftRegister(outString, reg, inString, bytesPerIteration);
    00160                 length -= bytesPerIteration;
    00161                 inString += bytesPerIteration;
    00162                 outString += bytesPerIteration;
    00163         }
    00164
    00165         if (length > 0)
    00166         {
    00167                 policy.TransformRegister();
    00168                 CombineMessageAndShiftRegister(outString, reg, inString, length);
    00169                 m_leftOver = bytesPerIteration - length;
    00170         }
    00171 }
    00172
    00173 template <class BASE>
    00174 void CFB_EncryptionTemplate<BASE>::CombineMessageAndShiftRegister(byte *output, byte *reg, const byte *message, unsigned int length)
    00175 {
    00176         xorbuf(reg, message, length);
    00177         memcpy(output, reg, length);
    00178 }
    00179
    00180 template <class BASE>
    00181 void CFB_DecryptionTemplate<BASE>::CombineMessageAndShiftRegister(byte *output, byte *reg, const byte *message, unsigned int length)
    00182 {
    00183         for (unsigned int i=0; i<length; i++)
    00184         {
    00185                 byte b = message[i];
    00186                 output[i] = reg[i] ^ b;
    00187                 reg[i] = b;
    00188         }
    00189 }
    00190
    00191 NAMESPACE_END
    00192
    00193 #endif