- Main Page
- Namespaces
- Classes
- Files

# 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 void AdditiveCipherTemplate<S>::UncheckedSetKey(const byte *key, unsigned int length, const NameValuePairs &params)
    00013 {
    00014         PolicyInterface &policy = this->AccessPolicy();
    00015         policy.CipherSetKey(params, key, length);
    00016         m_leftOver = 0;
    00017         unsigned int bufferByteSize = policy.CanOperateKeystream() ? GetBufferByteSize(policy) : RoundUpToMultipleOf(1024U, GetBufferByteSize(policy));
    00018         m_buffer.New(bufferByteSize);
    00019
    00020         if (this->IsResynchronizable())
    00021         {
    00022                 size_t ivLength;
    00023                 const byte *iv = this->GetIVAndThrowIfInvalid(params, ivLength);
    00024                 policy.CipherResynchronize(m_buffer, iv, ivLength);
    00025         }
    00026 }
    00027
    00028 template <class S>
    00029 void AdditiveCipherTemplate<S>::GenerateBlock(byte *outString, size_t length)
    00030 {
    00031         if (m_leftOver > 0)
    00032         {
    00033                 size_t len = STDMIN(m_leftOver, length);
    00034                 memcpy(outString, KeystreamBufferEnd()-m_leftOver, len);
    00035                 length -= len;
    00036                 m_leftOver -= len;
    00037                 outString += len;
    00038
    00039                 if (!length)
    00040                         return;
    00041         }
    00042         assert(m_leftOver == 0);
    00043
    00044         PolicyInterface &policy = this->AccessPolicy();
    00045         unsigned int bytesPerIteration = policy.GetBytesPerIteration();
    00046
    00047         if (length >= bytesPerIteration)
    00048         {
    00049                 size_t iterations = length / bytesPerIteration;
    00050                 policy.WriteKeystream(outString, iterations);
    00051                 outString += iterations * bytesPerIteration;
    00052                 length -= iterations * bytesPerIteration;
    00053         }
    00054
    00055         if (length > 0)
    00056         {
    00057                 size_t bufferByteSize = RoundUpToMultipleOf(length, bytesPerIteration);
    00058                 size_t bufferIterations = bufferByteSize / bytesPerIteration;
    00059
    00060                 policy.WriteKeystream(KeystreamBufferEnd()-bufferByteSize, bufferIterations);
    00061                 memcpy(outString, KeystreamBufferEnd()-bufferByteSize, length);
    00062                 m_leftOver = bufferByteSize - length;
    00063         }
    00064 }
    00065
    00066 template <class S>
    00067 void AdditiveCipherTemplate<S>::ProcessData(byte *outString, const byte *inString, size_t length)
    00068 {
    00069         if (m_leftOver > 0)
    00070         {
    00071                 size_t len = STDMIN(m_leftOver, length);
    00072                 xorbuf(outString, inString, KeystreamBufferEnd()-m_leftOver, len);
    00073                 length -= len;
    00074                 m_leftOver -= len;
    00075                 inString += len;
    00076                 outString += len;
    00077
    00078                 if (!length)
    00079                         return;
    00080         }
    00081         assert(m_leftOver == 0);
    00082
    00083         PolicyInterface &policy = this->AccessPolicy();
    00084         unsigned int bytesPerIteration = policy.GetBytesPerIteration();
    00085
    00086         if (policy.CanOperateKeystream() && length >= bytesPerIteration)
    00087         {
    00088                 size_t iterations = length / bytesPerIteration;
    00089                 unsigned int alignment = policy.GetAlignment();
    00090                 KeystreamOperation operation = KeystreamOperation((IsAlignedOn(inString, alignment) * 2) | (int)IsAlignedOn(outString, alignment));
    00091
    00092                 policy.OperateKeystream(operation, outString, inString, iterations);
    00093
    00094                 inString += iterations * bytesPerIteration;
    00095                 outString += iterations * bytesPerIteration;
    00096                 length -= iterations * bytesPerIteration;
    00097
    00098                 if (!length)
    00099                         return;
    00100         }
    00101
    00102         size_t bufferByteSize = m_buffer.size();
    00103         size_t bufferIterations = bufferByteSize / bytesPerIteration;
    00104
    00105         while (length >= bufferByteSize)
    00106         {
    00107                 policy.WriteKeystream(m_buffer, bufferIterations);
    00108                 xorbuf(outString, inString, KeystreamBufferBegin(), bufferByteSize);
    00109                 length -= bufferByteSize;
    00110                 inString += bufferByteSize;
    00111                 outString += bufferByteSize;
    00112         }
    00113
    00114         if (length > 0)
    00115         {
    00116                 bufferByteSize = RoundUpToMultipleOf(length, bytesPerIteration);
    00117                 bufferIterations = bufferByteSize / bytesPerIteration;
    00118
    00119                 policy.WriteKeystream(KeystreamBufferEnd()-bufferByteSize, bufferIterations);
    00120                 xorbuf(outString, inString, KeystreamBufferEnd()-bufferByteSize, length);
    00121                 m_leftOver = bufferByteSize - length;
    00122         }
    00123 }
    00124
    00125 template <class S>
    00126 void AdditiveCipherTemplate<S>::Resynchronize(const byte *iv, int length)
    00127 {
    00128         PolicyInterface &policy = this->AccessPolicy();
    00129         m_leftOver = 0;
    00130         m_buffer.New(GetBufferByteSize(policy));
    00131         policy.CipherResynchronize(m_buffer, iv, this->ThrowIfInvalidIVLength(length));
    00132 }
    00133
    00134 template <class BASE>
    00135 void AdditiveCipherTemplate<BASE>::Seek(lword position)
    00136 {
    00137         PolicyInterface &policy = this->AccessPolicy();
    00138         unsigned int bytesPerIteration = policy.GetBytesPerIteration();
    00139
    00140         policy.SeekToIteration(position / bytesPerIteration);
    00141         position %= bytesPerIteration;
    00142
    00143         if (position > 0)
    00144         {
    00145                 policy.WriteKeystream(KeystreamBufferEnd()-bytesPerIteration, 1);
    00146                 m_leftOver = bytesPerIteration - (unsigned int)position;
    00147         }
    00148         else
    00149                 m_leftOver = 0;
    00150 }
    00151
    00152 template <class BASE>
    00153 void CFB_CipherTemplate<BASE>::UncheckedSetKey(const byte *key, unsigned int length, const NameValuePairs &params)
    00154 {
    00155         PolicyInterface &policy = this->AccessPolicy();
    00156         policy.CipherSetKey(params, key, length);
    00157
    00158         if (this->IsResynchronizable())
    00159         {
    00160                 size_t ivLength;
    00161                 const byte *iv = this->GetIVAndThrowIfInvalid(params, ivLength);
    00162                 policy.CipherResynchronize(iv, ivLength);
    00163         }
    00164
    00165         m_leftOver = policy.GetBytesPerIteration();
    00166 }
    00167
    00168 template <class BASE>
    00169 void CFB_CipherTemplate<BASE>::Resynchronize(const byte *iv, int length)
    00170 {
    00171         PolicyInterface &policy = this->AccessPolicy();
    00172         policy.CipherResynchronize(iv, this->ThrowIfInvalidIVLength(length));
    00173         m_leftOver = policy.GetBytesPerIteration();
    00174 }
    00175
    00176 template <class BASE>
    00177 void CFB_CipherTemplate<BASE>::ProcessData(byte *outString, const byte *inString, size_t length)
    00178 {
    00179         assert(length % this->MandatoryBlockSize() == 0);
    00180
    00181         PolicyInterface &policy = this->AccessPolicy();
    00182         unsigned int bytesPerIteration = policy.GetBytesPerIteration();
    00183         unsigned int alignment = policy.GetAlignment();
    00184         byte *reg = policy.GetRegisterBegin();
    00185
    00186         if (m_leftOver)
    00187         {
    00188                 size_t len = STDMIN(m_leftOver, length);
    00189                 CombineMessageAndShiftRegister(outString, reg + bytesPerIteration - m_leftOver, inString, len);
    00190                 m_leftOver -= len;
    00191                 length -= len;
    00192                 inString += len;
    00193                 outString += len;
    00194         }
    00195
    00196         if (!length)
    00197                 return;
    00198
    00199         assert(m_leftOver == 0);
    00200
    00201         if (policy.CanIterate() && length >= bytesPerIteration && IsAlignedOn(outString, alignment))
    00202         {
    00203                 if (IsAlignedOn(inString, alignment))
    00204                         policy.Iterate(outString, inString, GetCipherDir(*this), length / bytesPerIteration);
    00205                 else
    00206                 {
    00207                         memcpy(outString, inString, length);
    00208                         policy.Iterate(outString, outString, GetCipherDir(*this), length / bytesPerIteration);
    00209                 }
    00210                 inString += length - length % bytesPerIteration;
    00211                 outString += length - length % bytesPerIteration;
    00212                 length %= bytesPerIteration;
    00213         }
    00214
    00215         while (length >= bytesPerIteration)
    00216         {
    00217                 policy.TransformRegister();
    00218                 CombineMessageAndShiftRegister(outString, reg, inString, bytesPerIteration);
    00219                 length -= bytesPerIteration;
    00220                 inString += bytesPerIteration;
    00221                 outString += bytesPerIteration;
    00222         }
    00223
    00224         if (length > 0)
    00225         {
    00226                 policy.TransformRegister();
    00227                 CombineMessageAndShiftRegister(outString, reg, inString, length);
    00228                 m_leftOver = bytesPerIteration - length;
    00229         }
    00230 }
    00231
    00232 template <class BASE>
    00233 void CFB_EncryptionTemplate<BASE>::CombineMessageAndShiftRegister(byte *output, byte *reg, const byte *message, size_t length)
    00234 {
    00235         xorbuf(reg, message, length);
    00236         memcpy(output, reg, length);
    00237 }
    00238
    00239 template <class BASE>
    00240 void CFB_DecryptionTemplate<BASE>::CombineMessageAndShiftRegister(byte *output, byte *reg, const byte *message, size_t length)
    00241 {
    00242         for (unsigned int i=0; i<length; i++)
    00243         {
    00244                 byte b = message[i];
    00245                 output[i] = reg[i] ^ b;
    00246                 reg[i] = b;
    00247         }
    00248 }
    00249
    00250 NAMESPACE_END
    00251
    00252 #endif