16 #ifndef CRYPTOPP_IMPORTS
21 #ifndef CRYPTOPP_MANUALLY_INSTANTIATE_TEMPLATES
22 extern const char STRCIPHER_FNAME[] = __FILE__;
30 PolicyInterface &policy = this->AccessPolicy();
31 policy.CipherSetKey(params, key, length);
33 unsigned int bufferByteSize = policy.CanOperateKeystream() ? GetBufferByteSize(policy) :
RoundUpToMultipleOf(1024U, GetBufferByteSize(policy));
34 m_buffer.New(bufferByteSize);
36 if (this->IsResynchronizable())
39 const byte *iv = this->GetIVAndThrowIfInvalid(params, ivLength);
40 policy.CipherResynchronize(m_buffer, iv, ivLength);
49 const size_t len =
STDMIN(m_leftOver, length);
50 std::memcpy(outString,
PtrSub(KeystreamBufferEnd(), m_leftOver), len);
52 length -= len; m_leftOver -= len;
53 outString =
PtrAdd(outString, len);
54 if (!length) {
return;}
57 PolicyInterface &policy = this->AccessPolicy();
58 size_t bytesPerIteration = policy.GetBytesPerIteration();
60 if (length >= bytesPerIteration)
62 const size_t iterations = length / bytesPerIteration;
63 policy.WriteKeystream(outString, iterations);
64 length -= iterations * bytesPerIteration;
65 outString =
PtrAdd(outString, iterations * bytesPerIteration);
71 size_t bufferIterations = bufferByteSize / bytesPerIteration;
73 policy.WriteKeystream(
PtrSub(KeystreamBufferEnd(), bufferByteSize), bufferIterations);
74 std::memcpy(outString,
PtrSub(KeystreamBufferEnd(), bufferByteSize), length);
75 m_leftOver = bufferByteSize - length;
96 PolicyInterface &policy = this->AccessPolicy();
97 size_t bytesPerIteration = policy.GetBytesPerIteration();
101 const size_t len =
STDMIN(m_leftOver, length);
102 xorbuf(outString, inString,
PtrSub(KeystreamBufferEnd(), m_leftOver), len);
104 inString =
PtrAdd(inString, len);
105 outString =
PtrAdd(outString, len);
106 length -= len; m_leftOver -= len;
109 if (!length) {
return; }
111 const word32 alignment = policy.GetAlignment();
112 const bool inAligned =
IsAlignedOn(inString, alignment);
113 const bool outAligned =
IsAlignedOn(outString, alignment);
114 CRYPTOPP_UNUSED(inAligned); CRYPTOPP_UNUSED(outAligned);
116 if (policy.CanOperateKeystream() && length >= bytesPerIteration)
118 const size_t iterations = length / bytesPerIteration;
122 policy.OperateKeystream(operation, outString, inString, iterations);
125 volatile byte* unused =
const_cast<volatile byte*
>(outString);
126 CRYPTOPP_UNUSED(unused);
128 inString =
PtrAdd(inString, iterations * bytesPerIteration);
129 outString =
PtrAdd(outString, iterations * bytesPerIteration);
130 length -= iterations * bytesPerIteration;
133 size_t bufferByteSize = m_buffer.size();
134 size_t bufferIterations = bufferByteSize / bytesPerIteration;
136 while (length >= bufferByteSize)
138 policy.WriteKeystream(m_buffer, bufferIterations);
139 xorbuf(outString, inString, KeystreamBufferBegin(), bufferByteSize);
141 inString =
PtrAdd(inString, bufferByteSize);
142 outString =
PtrAdd(outString, bufferByteSize);
143 length -= bufferByteSize;
149 bufferIterations = bufferByteSize / bytesPerIteration;
151 policy.WriteKeystream(
PtrSub(KeystreamBufferEnd(), bufferByteSize), bufferIterations);
152 xorbuf(outString, inString,
PtrSub(KeystreamBufferEnd(), bufferByteSize), length);
154 m_leftOver = bufferByteSize - length;
161 PolicyInterface &policy = this->AccessPolicy();
163 m_buffer.New(GetBufferByteSize(policy));
164 policy.CipherResynchronize(m_buffer, iv, this->ThrowIfInvalidIVLength(length));
167 template <
class BASE>
170 PolicyInterface &policy = this->AccessPolicy();
171 unsigned int bytesPerIteration = policy.GetBytesPerIteration();
173 policy.SeekToIteration(position / bytesPerIteration);
174 position %= bytesPerIteration;
178 policy.WriteKeystream(
PtrSub(KeystreamBufferEnd(), bytesPerIteration), 1);
179 m_leftOver = bytesPerIteration -
static_cast<unsigned int>(position);
185 template <
class BASE>
188 PolicyInterface &policy = this->AccessPolicy();
189 policy.CipherSetKey(params, key, length);
191 if (this->IsResynchronizable())
194 const byte *iv = this->GetIVAndThrowIfInvalid(params, ivLength);
195 policy.CipherResynchronize(iv, ivLength);
198 m_leftOver = policy.GetBytesPerIteration();
201 template <
class BASE>
204 PolicyInterface &policy = this->AccessPolicy();
205 policy.CipherResynchronize(iv, this->ThrowIfInvalidIVLength(length));
206 m_leftOver = policy.GetBytesPerIteration();
220 template <
class BASE>
226 PolicyInterface &policy = this->AccessPolicy();
227 unsigned int bytesPerIteration = policy.GetBytesPerIteration();
228 byte *reg = policy.GetRegisterBegin();
232 const size_t len =
STDMIN(m_leftOver, length);
233 CombineMessageAndShiftRegister(outString,
PtrAdd(reg, bytesPerIteration - m_leftOver), inString, len);
235 inString =
PtrAdd(inString, len);
236 outString =
PtrAdd(outString, len);
237 m_leftOver -= len; length -= len;
240 if (!length) {
return; }
242 const word32 alignment = policy.GetAlignment();
243 const bool inAligned =
IsAlignedOn(inString, alignment);
244 const bool outAligned =
IsAlignedOn(outString, alignment);
245 CRYPTOPP_UNUSED(inAligned); CRYPTOPP_UNUSED(outAligned);
247 if (policy.CanIterate() && length >= bytesPerIteration && outAligned)
250 policy.Iterate(outString, inString, cipherDir, length / bytesPerIteration);
253 volatile byte* unused =
const_cast<volatile byte*
>(outString);
254 CRYPTOPP_UNUSED(unused);
256 const size_t remainder = length % bytesPerIteration;
257 inString =
PtrAdd(inString, length - remainder);
258 outString =
PtrAdd(outString, length - remainder);
262 while (length >= bytesPerIteration)
264 policy.TransformRegister();
265 CombineMessageAndShiftRegister(outString, reg, inString, bytesPerIteration);
267 inString =
PtrAdd(inString, bytesPerIteration);
268 outString =
PtrAdd(outString, bytesPerIteration);
269 length -= bytesPerIteration;
274 policy.TransformRegister();
275 CombineMessageAndShiftRegister(outString, reg, inString, length);
276 m_leftOver = bytesPerIteration - length;
280 template <
class BASE>
283 xorbuf(reg, message, length);
284 std::memcpy(output, reg, length);
287 template <
class BASE>
290 for (
size_t i=0; i<length; i++)
293 output[i] = reg[i] ^ b;