00001
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, size_t length)
00027 {
00028 if (m_leftOver > 0)
00029 {
00030 size_t 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, size_t 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 size_t 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, size_t 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, size_t 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