Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Namespace Members | Class 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 = this->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 = this->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 = this->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(lword position)
    00095 {
    00096         PolicyInterface &policy = this->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 - (unsigned int)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 = this->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         assert(length % this->MandatoryBlockSize() == 0);
    00123
    00124         PolicyInterface &policy = this->AccessPolicy();
    00125         unsigned int bytesPerIteration = policy.GetBytesPerIteration();
    00126         unsigned int alignment = policy.GetAlignment();
    00127         byte *reg = policy.GetRegisterBegin();
    00128
    00129         if (m_leftOver)
    00130         {
    00131                 unsigned int len = STDMIN(m_leftOver, length);
    00132                 CombineMessageAndShiftRegister(outString, reg + bytesPerIteration - m_leftOver, inString, len);
    00133                 m_leftOver -= len;
    00134                 length -= len;
    00135                 inString += len;
    00136                 outString += len;
    00137         }
    00138
    00139         if (!length)
    00140                 return;
    00141
    00142         assert(m_leftOver == 0);
    00143
    00144         if (policy.CanIterate() && length >= bytesPerIteration && IsAlignedOn(outString, alignment))
    00145         {
    00146                 if (IsAlignedOn(inString, alignment))
    00147                         policy.Iterate(outString, inString, GetCipherDir(*this), length / bytesPerIteration);
    00148                 else
    00149                 {
    00150                         memcpy(outString, inString, length);
    00151                         policy.Iterate(outString, outString, GetCipherDir(*this), length / bytesPerIteration);
    00152                 }
    00153                 inString += length - length % bytesPerIteration;
    00154                 outString += length - length % bytesPerIteration;
    00155                 length %= bytesPerIteration;
    00156         }
    00157
    00158         while (length >= bytesPerIteration)
    00159         {
    00160                 policy.TransformRegister();
    00161                 CombineMessageAndShiftRegister(outString, reg, inString, bytesPerIteration);
    00162                 length -= bytesPerIteration;
    00163                 inString += bytesPerIteration;
    00164                 outString += bytesPerIteration;
    00165         }
    00166
    00167         if (length > 0)
    00168         {
    00169                 policy.TransformRegister();
    00170                 CombineMessageAndShiftRegister(outString, reg, inString, length);
    00171                 m_leftOver = bytesPerIteration - length;
    00172         }
    00173 }
    00174
    00175 template <class BASE>
    00176 void CFB_EncryptionTemplate<BASE>::CombineMessageAndShiftRegister(byte *output, byte *reg, const byte *message, unsigned int length)
    00177 {
    00178         xorbuf(reg, message, length);
    00179         memcpy(output, reg, length);
    00180 }
    00181
    00182 template <class BASE>
    00183 void CFB_DecryptionTemplate<BASE>::CombineMessageAndShiftRegister(byte *output, byte *reg, const byte *message, unsigned int length)
    00184 {
    00185         for (unsigned int i=0; i<length; i++)
    00186         {
    00187                 byte b = message[i];
    00188                 output[i] = reg[i] ^ b;
    00189                 reg[i] = b;
    00190         }
    00191 }
    00192
    00193 NAMESPACE_END
    00194
    00195 #endif