strciphr.cpp

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

Generated on Fri Jun 1 11:11:25 2007 for Crypto++ by  doxygen 1.5.2