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

Generated on Sat Dec 23 02:07:10 2006 for Crypto++ by  doxygen 1.5.1-p1