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 = 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 = 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 = 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(dword position)
00095 {
00096 PolicyInterface &policy = 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 - 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 = 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 PolicyInterface &policy = AccessPolicy();
00123 unsigned int bytesPerIteration = policy.GetBytesPerIteration();
00124 unsigned int alignment = policy.GetAlignment();
00125 byte *reg = policy.GetRegisterBegin();
00126
00127 if (m_leftOver)
00128 {
00129 unsigned int len = STDMIN(m_leftOver, length);
00130 CombineMessageAndShiftRegister(outString, reg + bytesPerIteration - m_leftOver, inString, len);
00131 m_leftOver -= len;
00132 length -= len;
00133 inString += len;
00134 outString += len;
00135 }
00136
00137 if (!length)
00138 return;
00139
00140 assert(m_leftOver == 0);
00141
00142 if (policy.CanIterate() && length >= bytesPerIteration && IsAlignedOn(outString, alignment))
00143 {
00144 if (IsAlignedOn(inString, alignment))
00145 policy.Iterate(outString, inString, GetCipherDir(*this), length / bytesPerIteration);
00146 else
00147 {
00148 memcpy(outString, inString, length);
00149 policy.Iterate(outString, outString, GetCipherDir(*this), length / bytesPerIteration);
00150 }
00151 inString += length - length % bytesPerIteration;
00152 outString += length - length % bytesPerIteration;
00153 length %= bytesPerIteration;
00154 }
00155
00156 while (length >= bytesPerIteration)
00157 {
00158 policy.TransformRegister();
00159 CombineMessageAndShiftRegister(outString, reg, inString, bytesPerIteration);
00160 length -= bytesPerIteration;
00161 inString += bytesPerIteration;
00162 outString += bytesPerIteration;
00163 }
00164
00165 if (length > 0)
00166 {
00167 policy.TransformRegister();
00168 CombineMessageAndShiftRegister(outString, reg, inString, length);
00169 m_leftOver = bytesPerIteration - length;
00170 }
00171 }
00172
00173 template <class BASE>
00174 void CFB_EncryptionTemplate<BASE>::CombineMessageAndShiftRegister(byte *output, byte *reg, const byte *message, unsigned int length)
00175 {
00176 xorbuf(reg, message, length);
00177 memcpy(output, reg, length);
00178 }
00179
00180 template <class BASE>
00181 void CFB_DecryptionTemplate<BASE>::CombineMessageAndShiftRegister(byte *output, byte *reg, const byte *message, unsigned int length)
00182 {
00183 for (unsigned int i=0; i<length; i++)
00184 {
00185 byte b = message[i];
00186 output[i] = reg[i] ^ b;
00187 reg[i] = b;
00188 }
00189 }
00190
00191 NAMESPACE_END
00192
00193 #endif