• Main Page
  • Namespaces
  • Classes
  • Files
  • File List
  • 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 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

Generated on Mon Aug 9 2010 15:56:38 for Crypto++ by  doxygen 1.7.1