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