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

Generated on Wed Nov 17 21:26:10 2004 for Crypto++ by  doxygen 1.3.9.1