- 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 // 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