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