1 | // strciphr.h - written and placed in the public domain by Wei Dai |
---|
2 | |
---|
3 | //! \file strciphr.h |
---|
4 | //! \brief Classes for implementing stream ciphers |
---|
5 | //! \details This file contains helper classes for implementing stream ciphers. |
---|
6 | //! All this infrastructure may look very complex compared to what's in Crypto++ 4.x, |
---|
7 | //! but stream ciphers implementations now support a lot of new functionality, |
---|
8 | //! including better performance (minimizing copying), resetting of keys and IVs, and methods to |
---|
9 | //! query which features are supported by a cipher. |
---|
10 | //! \details Here's an explanation of these classes. The word "policy" is used here to mean a class with a |
---|
11 | //! set of methods that must be implemented by individual stream cipher implementations. |
---|
12 | //! This is usually much simpler than the full stream cipher API, which is implemented by |
---|
13 | //! either AdditiveCipherTemplate or CFB_CipherTemplate using the policy. So for example, an |
---|
14 | //! implementation of SEAL only needs to implement the AdditiveCipherAbstractPolicy interface |
---|
15 | //! (since it's an additive cipher, i.e., it xors a keystream into the plaintext). |
---|
16 | //! See this line in seal.h: |
---|
17 | //! <pre> |
---|
18 | //! typedef SymmetricCipherFinal\<ConcretePolicyHolder\<SEAL_Policy\<B\>, AdditiveCipherTemplate\<\> \> \> Encryption; |
---|
19 | //! </pre> |
---|
20 | //! \details AdditiveCipherTemplate and CFB_CipherTemplate are designed so that they don't need |
---|
21 | //! to take a policy class as a template parameter (although this is allowed), so that |
---|
22 | //! their code is not duplicated for each new cipher. Instead they each |
---|
23 | //! get a reference to an abstract policy interface by calling AccessPolicy() on itself, so |
---|
24 | //! AccessPolicy() must be overriden to return the actual policy reference. This is done |
---|
25 | //! by the ConceretePolicyHolder class. Finally, SymmetricCipherFinal implements the constructors and |
---|
26 | //! other functions that must be implemented by the most derived class. |
---|
27 | |
---|
28 | #ifndef CRYPTOPP_STRCIPHR_H |
---|
29 | #define CRYPTOPP_STRCIPHR_H |
---|
30 | |
---|
31 | #include "config.h" |
---|
32 | |
---|
33 | #if CRYPTOPP_MSC_VERSION |
---|
34 | # pragma warning(push) |
---|
35 | # pragma warning(disable: 4127 4189) |
---|
36 | #endif |
---|
37 | |
---|
38 | #include "cryptlib.h" |
---|
39 | #include "seckey.h" |
---|
40 | #include "secblock.h" |
---|
41 | #include "argnames.h" |
---|
42 | |
---|
43 | NAMESPACE_BEGIN(CryptoPP) |
---|
44 | |
---|
45 | //! \class AbstractPolicyHolder |
---|
46 | //! \brief Access a stream cipher policy object |
---|
47 | //! \tparam POLICY_INTERFACE class implementing AbstractPolicyHolder |
---|
48 | //! \tparam BASE class or type to use as a base class |
---|
49 | template <class POLICY_INTERFACE, class BASE = Empty> |
---|
50 | class CRYPTOPP_NO_VTABLE AbstractPolicyHolder : public BASE |
---|
51 | { |
---|
52 | public: |
---|
53 | typedef POLICY_INTERFACE PolicyInterface; |
---|
54 | virtual ~AbstractPolicyHolder() {} |
---|
55 | |
---|
56 | protected: |
---|
57 | virtual const POLICY_INTERFACE & GetPolicy() const =0; |
---|
58 | virtual POLICY_INTERFACE & AccessPolicy() =0; |
---|
59 | }; |
---|
60 | |
---|
61 | //! \class ConcretePolicyHolder |
---|
62 | //! \brief Stream cipher policy object |
---|
63 | //! \tparam POLICY class implementing AbstractPolicyHolder |
---|
64 | //! \tparam BASE class or type to use as a base class |
---|
65 | template <class POLICY, class BASE, class POLICY_INTERFACE = CPP_TYPENAME BASE::PolicyInterface> |
---|
66 | class ConcretePolicyHolder : public BASE, protected POLICY |
---|
67 | { |
---|
68 | public: |
---|
69 | #ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562 |
---|
70 | virtual ~ConcretePolicyHolder() {} |
---|
71 | #endif |
---|
72 | protected: |
---|
73 | const POLICY_INTERFACE & GetPolicy() const {return *this;} |
---|
74 | POLICY_INTERFACE & AccessPolicy() {return *this;} |
---|
75 | }; |
---|
76 | |
---|
77 | //! \brief Keystream operation flags |
---|
78 | //! \sa AdditiveCipherAbstractPolicy::GetBytesPerIteration(), AdditiveCipherAbstractPolicy::GetOptimalBlockSize() |
---|
79 | //! and AdditiveCipherAbstractPolicy::GetAlignment() |
---|
80 | enum KeystreamOperationFlags { |
---|
81 | //! \brief Output buffer is aligned |
---|
82 | OUTPUT_ALIGNED=1, |
---|
83 | //! \brief Input buffer is aligned |
---|
84 | INPUT_ALIGNED=2, |
---|
85 | //! \brief Input buffer is NULL |
---|
86 | INPUT_NULL = 4 |
---|
87 | }; |
---|
88 | |
---|
89 | //! \brief Keystream operation flags |
---|
90 | //! \sa AdditiveCipherAbstractPolicy::GetBytesPerIteration(), AdditiveCipherAbstractPolicy::GetOptimalBlockSize() |
---|
91 | //! and AdditiveCipherAbstractPolicy::GetAlignment() |
---|
92 | enum KeystreamOperation { |
---|
93 | //! \brief Wirte the keystream to the output buffer, input is NULL |
---|
94 | WRITE_KEYSTREAM = INPUT_NULL, |
---|
95 | //! \brief Wirte the keystream to the aligned output buffer, input is NULL |
---|
96 | WRITE_KEYSTREAM_ALIGNED = INPUT_NULL | OUTPUT_ALIGNED, |
---|
97 | //! \brief XOR the input buffer and keystream, write to the output buffer |
---|
98 | XOR_KEYSTREAM = 0, |
---|
99 | //! \brief XOR the aligned input buffer and keystream, write to the output buffer |
---|
100 | XOR_KEYSTREAM_INPUT_ALIGNED = INPUT_ALIGNED, |
---|
101 | //! \brief XOR the input buffer and keystream, write to the aligned output buffer |
---|
102 | XOR_KEYSTREAM_OUTPUT_ALIGNED= OUTPUT_ALIGNED, |
---|
103 | //! \brief XOR the aligned input buffer and keystream, write to the aligned output buffer |
---|
104 | XOR_KEYSTREAM_BOTH_ALIGNED = OUTPUT_ALIGNED | INPUT_ALIGNED}; |
---|
105 | |
---|
106 | //! \class AdditiveCipherAbstractPolicy |
---|
107 | //! \brief Policy object for additive stream ciphers |
---|
108 | struct CRYPTOPP_DLL CRYPTOPP_NO_VTABLE AdditiveCipherAbstractPolicy |
---|
109 | { |
---|
110 | virtual ~AdditiveCipherAbstractPolicy() {} |
---|
111 | |
---|
112 | //! \brief Provides data alignment requirements |
---|
113 | //! \returns data alignment requirements, in bytes |
---|
114 | //! \details Internally, the default implementation returns 1. If the stream cipher is implemented |
---|
115 | //! using an SSE2 ASM or intrinsics, then the value returned is usually 16. |
---|
116 | virtual unsigned int GetAlignment() const {return 1;} |
---|
117 | |
---|
118 | //! \brief Provides number of bytes operated upon during an iteration |
---|
119 | //! \returns bytes operated upon during an iteration, in bytes |
---|
120 | //! \sa GetOptimalBlockSize() |
---|
121 | virtual unsigned int GetBytesPerIteration() const =0; |
---|
122 | |
---|
123 | //! \brief Provides number of ideal bytes to process |
---|
124 | //! \returns the ideal number of bytes to process |
---|
125 | //! \details Internally, the default implementation returns GetBytesPerIteration() |
---|
126 | //! \sa GetBytesPerIteration() |
---|
127 | virtual unsigned int GetOptimalBlockSize() const {return GetBytesPerIteration();} |
---|
128 | |
---|
129 | //! \brief Provides buffer size based on iterations |
---|
130 | //! \returns the buffer size based on iterations, in bytes |
---|
131 | virtual unsigned int GetIterationsToBuffer() const =0; |
---|
132 | |
---|
133 | //! \brief Generate the keystream |
---|
134 | //! \param keystream the key stream |
---|
135 | //! \param iterationCount the number of iterations to generate the key stream |
---|
136 | //! \sa CanOperateKeystream(), OperateKeystream(), WriteKeystream() |
---|
137 | virtual void WriteKeystream(byte *keystream, size_t iterationCount) |
---|
138 | {OperateKeystream(KeystreamOperation(INPUT_NULL | (KeystreamOperationFlags)IsAlignedOn(keystream, GetAlignment())), keystream, NULL, iterationCount);} |
---|
139 | |
---|
140 | //! \brief Flag indicating |
---|
141 | //! \returns true if the stream can be generated independent of the transformation input, false otherwise |
---|
142 | //! \sa CanOperateKeystream(), OperateKeystream(), WriteKeystream() |
---|
143 | virtual bool CanOperateKeystream() const {return false;} |
---|
144 | |
---|
145 | //! \brief Operates the keystream |
---|
146 | //! \param operation the operation with additional flags |
---|
147 | //! \param output the output buffer |
---|
148 | //! \param input the input buffer |
---|
149 | //! \param iterationCount the number of iterations to perform on the input |
---|
150 | //! \details OperateKeystream() will attempt to operate upon GetOptimalBlockSize() buffer, |
---|
151 | //! which will be derived from GetBytesPerIteration(). |
---|
152 | //! \sa CanOperateKeystream(), OperateKeystream(), WriteKeystream(), KeystreamOperation() |
---|
153 | virtual void OperateKeystream(KeystreamOperation operation, byte *output, const byte *input, size_t iterationCount) |
---|
154 | {CRYPTOPP_UNUSED(operation); CRYPTOPP_UNUSED(output); CRYPTOPP_UNUSED(input); CRYPTOPP_UNUSED(iterationCount); CRYPTOPP_ASSERT(false);} |
---|
155 | |
---|
156 | //! \brief Key the cipher |
---|
157 | //! \param params set of NameValuePairs use to initialize this object |
---|
158 | //! \param key a byte array used to key the cipher |
---|
159 | //! \param length the size of the key array |
---|
160 | virtual void CipherSetKey(const NameValuePairs ¶ms, const byte *key, size_t length) =0; |
---|
161 | |
---|
162 | //! \brief Resynchronize the cipher |
---|
163 | //! \param keystreamBuffer the keystream buffer |
---|
164 | //! \param iv a byte array used to resynchronize the cipher |
---|
165 | //! \param length the size of the IV array |
---|
166 | virtual void CipherResynchronize(byte *keystreamBuffer, const byte *iv, size_t length) |
---|
167 | {CRYPTOPP_UNUSED(keystreamBuffer); CRYPTOPP_UNUSED(iv); CRYPTOPP_UNUSED(length); throw NotImplemented("SimpleKeyingInterface: this object doesn't support resynchronization");} |
---|
168 | |
---|
169 | //! \brief Flag indicating random access |
---|
170 | //! \returns true if the cipher is seekable, false otherwise |
---|
171 | //! \sa SeekToIteration() |
---|
172 | virtual bool CipherIsRandomAccess() const =0; |
---|
173 | |
---|
174 | //! \brief Seeks to a random position in the stream |
---|
175 | //! \returns iterationCount |
---|
176 | //! \sa CipherIsRandomAccess() |
---|
177 | virtual void SeekToIteration(lword iterationCount) |
---|
178 | {CRYPTOPP_UNUSED(iterationCount); CRYPTOPP_ASSERT(!CipherIsRandomAccess()); throw NotImplemented("StreamTransformation: this object doesn't support random access");} |
---|
179 | }; |
---|
180 | |
---|
181 | //! \class AdditiveCipherConcretePolicy |
---|
182 | //! \brief Base class for additive stream ciphers |
---|
183 | //! \tparam WT word type |
---|
184 | //! \tparam W count of words |
---|
185 | //! \tparam X bytes per iteration count |
---|
186 | //! \tparam BASE AdditiveCipherAbstractPolicy derived base class |
---|
187 | template <typename WT, unsigned int W, unsigned int X = 1, class BASE = AdditiveCipherAbstractPolicy> |
---|
188 | struct CRYPTOPP_NO_VTABLE AdditiveCipherConcretePolicy : public BASE |
---|
189 | { |
---|
190 | typedef WT WordType; |
---|
191 | CRYPTOPP_CONSTANT(BYTES_PER_ITERATION = sizeof(WordType) * W) |
---|
192 | |
---|
193 | #if !(CRYPTOPP_BOOL_X86 || CRYPTOPP_BOOL_X64) |
---|
194 | //! \brief Provides data alignment requirements |
---|
195 | //! \returns data alignment requirements, in bytes |
---|
196 | //! \details Internally, the default implementation returns 1. If the stream cipher is implemented |
---|
197 | //! using an SSE2 ASM or intrinsics, then the value returned is usually 16. |
---|
198 | unsigned int GetAlignment() const {return GetAlignmentOf<WordType>();} |
---|
199 | #endif |
---|
200 | |
---|
201 | //! \brief Provides number of bytes operated upon during an iteration |
---|
202 | //! \returns bytes operated upon during an iteration, in bytes |
---|
203 | //! \sa GetOptimalBlockSize() |
---|
204 | unsigned int GetBytesPerIteration() const {return BYTES_PER_ITERATION;} |
---|
205 | |
---|
206 | //! \brief Provides buffer size based on iterations |
---|
207 | //! \returns the buffer size based on iterations, in bytes |
---|
208 | unsigned int GetIterationsToBuffer() const {return X;} |
---|
209 | |
---|
210 | //! \brief Flag indicating |
---|
211 | //! \returns true if the stream can be generated independent of the transformation input, false otherwise |
---|
212 | //! \sa CanOperateKeystream(), OperateKeystream(), WriteKeystream() |
---|
213 | bool CanOperateKeystream() const {return true;} |
---|
214 | |
---|
215 | //! \brief Operates the keystream |
---|
216 | //! \param operation the operation with additional flags |
---|
217 | //! \param output the output buffer |
---|
218 | //! \param input the input buffer |
---|
219 | //! \param iterationCount the number of iterations to perform on the input |
---|
220 | //! \details OperateKeystream() will attempt to operate upon GetOptimalBlockSize() buffer, |
---|
221 | //! which will be derived from GetBytesPerIteration(). |
---|
222 | //! \sa CanOperateKeystream(), OperateKeystream(), WriteKeystream(), KeystreamOperation() |
---|
223 | virtual void OperateKeystream(KeystreamOperation operation, byte *output, const byte *input, size_t iterationCount) =0; |
---|
224 | }; |
---|
225 | |
---|
226 | //! \brief Helper macro to implement OperateKeystream |
---|
227 | #define CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, b, i, a) \ |
---|
228 | PutWord(bool(x & OUTPUT_ALIGNED), b, output+i*sizeof(WordType), (x & INPUT_NULL) ? (a) : (a) ^ GetWord<WordType>(bool(x & INPUT_ALIGNED), b, input+i*sizeof(WordType))); |
---|
229 | |
---|
230 | //! \brief Helper macro to implement OperateKeystream |
---|
231 | #define CRYPTOPP_KEYSTREAM_OUTPUT_XMM(x, i, a) {\ |
---|
232 | __m128i t = (x & INPUT_NULL) ? a : _mm_xor_si128(a, (x & INPUT_ALIGNED) ? _mm_load_si128((__m128i *)input+i) : _mm_loadu_si128((__m128i *)input+i));\ |
---|
233 | if (x & OUTPUT_ALIGNED) _mm_store_si128((__m128i *)output+i, t);\ |
---|
234 | else _mm_storeu_si128((__m128i *)output+i, t);} |
---|
235 | |
---|
236 | //! \brief Helper macro to implement OperateKeystream |
---|
237 | #define CRYPTOPP_KEYSTREAM_OUTPUT_SWITCH(x, y) \ |
---|
238 | switch (operation) \ |
---|
239 | { \ |
---|
240 | case WRITE_KEYSTREAM: \ |
---|
241 | x(WRITE_KEYSTREAM) \ |
---|
242 | break; \ |
---|
243 | case XOR_KEYSTREAM: \ |
---|
244 | x(XOR_KEYSTREAM) \ |
---|
245 | input += y; \ |
---|
246 | break; \ |
---|
247 | case XOR_KEYSTREAM_INPUT_ALIGNED: \ |
---|
248 | x(XOR_KEYSTREAM_INPUT_ALIGNED) \ |
---|
249 | input += y; \ |
---|
250 | break; \ |
---|
251 | case XOR_KEYSTREAM_OUTPUT_ALIGNED: \ |
---|
252 | x(XOR_KEYSTREAM_OUTPUT_ALIGNED) \ |
---|
253 | input += y; \ |
---|
254 | break; \ |
---|
255 | case WRITE_KEYSTREAM_ALIGNED: \ |
---|
256 | x(WRITE_KEYSTREAM_ALIGNED) \ |
---|
257 | break; \ |
---|
258 | case XOR_KEYSTREAM_BOTH_ALIGNED: \ |
---|
259 | x(XOR_KEYSTREAM_BOTH_ALIGNED) \ |
---|
260 | input += y; \ |
---|
261 | break; \ |
---|
262 | } \ |
---|
263 | output += y; |
---|
264 | |
---|
265 | //! \class AdditiveCipherTemplate |
---|
266 | //! \brief Base class for additive stream ciphers with SymmetricCipher interface |
---|
267 | //! \tparam BASE AbstractPolicyHolder base class |
---|
268 | template <class BASE = AbstractPolicyHolder<AdditiveCipherAbstractPolicy, SymmetricCipher> > |
---|
269 | class CRYPTOPP_NO_VTABLE AdditiveCipherTemplate : public BASE, public RandomNumberGenerator |
---|
270 | { |
---|
271 | public: |
---|
272 | //! \brief Generate random array of bytes |
---|
273 | //! \param output the byte buffer |
---|
274 | //! \param size the length of the buffer, in bytes |
---|
275 | //! \details All generated values are uniformly distributed over the range specified within the |
---|
276 | //! the contraints of a particular generator. |
---|
277 | void GenerateBlock(byte *output, size_t size); |
---|
278 | |
---|
279 | //! \brief Apply keystream to data |
---|
280 | //! \param outString a buffer to write the transformed data |
---|
281 | //! \param inString a buffer to read the data |
---|
282 | //! \param length the size fo the buffers, in bytes |
---|
283 | //! \details This is the primary method to operate a stream cipher. For example: |
---|
284 | //! <pre> |
---|
285 | //! size_t size = 30; |
---|
286 | //! byte plain[size] = "Do or do not; there is no try"; |
---|
287 | //! byte cipher[size]; |
---|
288 | //! ... |
---|
289 | //! ChaCha20 chacha(key, keySize); |
---|
290 | //! chacha.ProcessData(cipher, plain, size); |
---|
291 | //! </pre> |
---|
292 | void ProcessData(byte *outString, const byte *inString, size_t length); |
---|
293 | |
---|
294 | //! \brief Resynchronize the cipher |
---|
295 | //! \param iv a byte array used to resynchronize the cipher |
---|
296 | //! \param length the size of the IV array |
---|
297 | void Resynchronize(const byte *iv, int length=-1); |
---|
298 | |
---|
299 | //! \brief Provides number of ideal bytes to process |
---|
300 | //! \returns the ideal number of bytes to process |
---|
301 | //! \details Internally, the default implementation returns GetBytesPerIteration() |
---|
302 | //! \sa GetBytesPerIteration() and GetOptimalNextBlockSize() |
---|
303 | unsigned int OptimalBlockSize() const {return this->GetPolicy().GetOptimalBlockSize();} |
---|
304 | |
---|
305 | //! \brief Provides number of ideal bytes to process |
---|
306 | //! \returns the ideal number of bytes to process |
---|
307 | //! \details Internally, the default implementation returns remaining unprocessed bytes |
---|
308 | //! \sa GetBytesPerIteration() and OptimalBlockSize() |
---|
309 | unsigned int GetOptimalNextBlockSize() const {return (unsigned int)this->m_leftOver;} |
---|
310 | |
---|
311 | //! \brief Provides number of ideal data alignment |
---|
312 | //! \returns the ideal data alignment, in bytes |
---|
313 | //! \sa GetAlignment() and OptimalBlockSize() |
---|
314 | unsigned int OptimalDataAlignment() const {return this->GetPolicy().GetAlignment();} |
---|
315 | |
---|
316 | //! \brief Determines if the cipher is self inverting |
---|
317 | //! \returns true if the stream cipher is self inverting, false otherwise |
---|
318 | bool IsSelfInverting() const {return true;} |
---|
319 | |
---|
320 | //! \brief Determines if the cipher is a forward transformation |
---|
321 | //! \returns true if the stream cipher is a forward transformation, false otherwise |
---|
322 | bool IsForwardTransformation() const {return true;} |
---|
323 | |
---|
324 | //! \brief Flag indicating random access |
---|
325 | //! \returns true if the cipher is seekable, false otherwise |
---|
326 | //! \sa Seek() |
---|
327 | bool IsRandomAccess() const {return this->GetPolicy().CipherIsRandomAccess();} |
---|
328 | |
---|
329 | //! \brief Seeks to a random position in the stream |
---|
330 | //! \param position the absolute position in the stream |
---|
331 | //! \sa IsRandomAccess() |
---|
332 | void Seek(lword position); |
---|
333 | |
---|
334 | typedef typename BASE::PolicyInterface PolicyInterface; |
---|
335 | |
---|
336 | protected: |
---|
337 | void UncheckedSetKey(const byte *key, unsigned int length, const NameValuePairs ¶ms); |
---|
338 | |
---|
339 | unsigned int GetBufferByteSize(const PolicyInterface &policy) const {return policy.GetBytesPerIteration() * policy.GetIterationsToBuffer();} |
---|
340 | |
---|
341 | inline byte * KeystreamBufferBegin() {return this->m_buffer.data();} |
---|
342 | inline byte * KeystreamBufferEnd() {return (this->m_buffer.data() + this->m_buffer.size());} |
---|
343 | |
---|
344 | SecByteBlock m_buffer; |
---|
345 | size_t m_leftOver; |
---|
346 | }; |
---|
347 | |
---|
348 | //! \class CFB_CipherAbstractPolicy |
---|
349 | //! \brief Policy object for feeback based stream ciphers |
---|
350 | class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE CFB_CipherAbstractPolicy |
---|
351 | { |
---|
352 | public: |
---|
353 | virtual ~CFB_CipherAbstractPolicy() {} |
---|
354 | |
---|
355 | //! \brief Provides data alignment requirements |
---|
356 | //! \returns data alignment requirements, in bytes |
---|
357 | //! \details Internally, the default implementation returns 1. If the stream cipher is implemented |
---|
358 | //! using an SSE2 ASM or intrinsics, then the value returned is usually 16. |
---|
359 | virtual unsigned int GetAlignment() const =0; |
---|
360 | |
---|
361 | //! \brief Provides number of bytes operated upon during an iteration |
---|
362 | //! \returns bytes operated upon during an iteration, in bytes |
---|
363 | //! \sa GetOptimalBlockSize() |
---|
364 | virtual unsigned int GetBytesPerIteration() const =0; |
---|
365 | |
---|
366 | //! \brief Access the feedback register |
---|
367 | //! \returns pointer to the first byte of the feedback register |
---|
368 | virtual byte * GetRegisterBegin() =0; |
---|
369 | |
---|
370 | //! \brief TODO |
---|
371 | virtual void TransformRegister() =0; |
---|
372 | |
---|
373 | //! \brief Flag indicating iteration support |
---|
374 | //! \returns true if the cipher supports iteration, false otherwise |
---|
375 | virtual bool CanIterate() const {return false;} |
---|
376 | |
---|
377 | //! \brief Iterate the cipher |
---|
378 | //! \param output the output buffer |
---|
379 | //! \param input the input buffer |
---|
380 | //! \param dir the direction of the cipher |
---|
381 | //! \param iterationCount the number of iterations to perform on the input |
---|
382 | //! \sa IsSelfInverting() and IsForwardTransformation() |
---|
383 | virtual void Iterate(byte *output, const byte *input, CipherDir dir, size_t iterationCount) |
---|
384 | {CRYPTOPP_UNUSED(output); CRYPTOPP_UNUSED(input); CRYPTOPP_UNUSED(dir); CRYPTOPP_UNUSED(iterationCount); |
---|
385 | CRYPTOPP_ASSERT(false); /*throw 0;*/ throw Exception(Exception::OTHER_ERROR, "SimpleKeyingInterface: unexpected error");} |
---|
386 | |
---|
387 | //! \brief Key the cipher |
---|
388 | //! \param params set of NameValuePairs use to initialize this object |
---|
389 | //! \param key a byte array used to key the cipher |
---|
390 | //! \param length the size of the key array |
---|
391 | virtual void CipherSetKey(const NameValuePairs ¶ms, const byte *key, size_t length) =0; |
---|
392 | |
---|
393 | //! \brief Resynchronize the cipher |
---|
394 | //! \param iv a byte array used to resynchronize the cipher |
---|
395 | //! \param length the size of the IV array |
---|
396 | virtual void CipherResynchronize(const byte *iv, size_t length) |
---|
397 | {CRYPTOPP_UNUSED(iv); CRYPTOPP_UNUSED(length); throw NotImplemented("SimpleKeyingInterface: this object doesn't support resynchronization");} |
---|
398 | }; |
---|
399 | |
---|
400 | //! \class CFB_CipherConcretePolicy |
---|
401 | //! \brief Base class for feedback based stream ciphers |
---|
402 | //! \tparam WT word type |
---|
403 | //! \tparam W count of words |
---|
404 | //! \tparam BASE CFB_CipherAbstractPolicy derived base class |
---|
405 | template <typename WT, unsigned int W, class BASE = CFB_CipherAbstractPolicy> |
---|
406 | struct CRYPTOPP_NO_VTABLE CFB_CipherConcretePolicy : public BASE |
---|
407 | { |
---|
408 | typedef WT WordType; |
---|
409 | |
---|
410 | //! \brief Provides data alignment requirements |
---|
411 | //! \returns data alignment requirements, in bytes |
---|
412 | //! \details Internally, the default implementation returns 1. If the stream cipher is implemented |
---|
413 | //! using an SSE2 ASM or intrinsics, then the value returned is usually 16. |
---|
414 | unsigned int GetAlignment() const {return sizeof(WordType);} |
---|
415 | |
---|
416 | //! \brief Provides number of bytes operated upon during an iteration |
---|
417 | //! \returns bytes operated upon during an iteration, in bytes |
---|
418 | //! \sa GetOptimalBlockSize() |
---|
419 | unsigned int GetBytesPerIteration() const {return sizeof(WordType) * W;} |
---|
420 | |
---|
421 | //! \brief Flag indicating iteration support |
---|
422 | //! \returns true if the cipher supports iteration, false otherwise |
---|
423 | bool CanIterate() const {return true;} |
---|
424 | |
---|
425 | //! \brief Perform one iteration in the forward direction |
---|
426 | void TransformRegister() {this->Iterate(NULL, NULL, ENCRYPTION, 1);} |
---|
427 | |
---|
428 | //! \brief |
---|
429 | //! \tparam B enumeration indicating endianess |
---|
430 | //! \details RegisterOutput() provides alternate access to the feedback register. The |
---|
431 | //! enumeration B is BigEndian or LittleEndian. Repeatedly applying operator() |
---|
432 | //! results in advancing in the register. |
---|
433 | template <class B> |
---|
434 | struct RegisterOutput |
---|
435 | { |
---|
436 | RegisterOutput(byte *output, const byte *input, CipherDir dir) |
---|
437 | : m_output(output), m_input(input), m_dir(dir) {} |
---|
438 | |
---|
439 | //! \brief XOR feedback register with data |
---|
440 | //! \param registerWord data represented as a word type |
---|
441 | //! \returns reference to the next feedback register word |
---|
442 | inline RegisterOutput& operator()(WordType ®isterWord) |
---|
443 | { |
---|
444 | CRYPTOPP_ASSERT(IsAligned<WordType>(m_output)); |
---|
445 | CRYPTOPP_ASSERT(IsAligned<WordType>(m_input)); |
---|
446 | |
---|
447 | if (!NativeByteOrderIs(B::ToEnum())) |
---|
448 | registerWord = ByteReverse(registerWord); |
---|
449 | |
---|
450 | if (m_dir == ENCRYPTION) |
---|
451 | { |
---|
452 | if (m_input == NULL) |
---|
453 | { |
---|
454 | CRYPTOPP_ASSERT(m_output == NULL); |
---|
455 | } |
---|
456 | else |
---|
457 | { |
---|
458 | WordType ct = *(const WordType *)m_input ^ registerWord; |
---|
459 | registerWord = ct; |
---|
460 | *(WordType*)m_output = ct; |
---|
461 | m_input += sizeof(WordType); |
---|
462 | m_output += sizeof(WordType); |
---|
463 | } |
---|
464 | } |
---|
465 | else |
---|
466 | { |
---|
467 | WordType ct = *(const WordType *)m_input; |
---|
468 | *(WordType*)m_output = registerWord ^ ct; |
---|
469 | registerWord = ct; |
---|
470 | m_input += sizeof(WordType); |
---|
471 | m_output += sizeof(WordType); |
---|
472 | } |
---|
473 | |
---|
474 | // registerWord is left unreversed so it can be xor-ed with further input |
---|
475 | |
---|
476 | return *this; |
---|
477 | } |
---|
478 | |
---|
479 | byte *m_output; |
---|
480 | const byte *m_input; |
---|
481 | CipherDir m_dir; |
---|
482 | }; |
---|
483 | }; |
---|
484 | |
---|
485 | //! \class CFB_CipherTemplate |
---|
486 | //! \brief Base class for feedback based stream ciphers with SymmetricCipher interface |
---|
487 | //! \tparam BASE AbstractPolicyHolder base class |
---|
488 | template <class BASE> |
---|
489 | class CRYPTOPP_NO_VTABLE CFB_CipherTemplate : public BASE |
---|
490 | { |
---|
491 | public: |
---|
492 | //! \brief Apply keystream to data |
---|
493 | //! \param outString a buffer to write the transformed data |
---|
494 | //! \param inString a buffer to read the data |
---|
495 | //! \param length the size fo the buffers, in bytes |
---|
496 | //! \details This is the primary method to operate a stream cipher. For example: |
---|
497 | //! <pre> |
---|
498 | //! size_t size = 30; |
---|
499 | //! byte plain[size] = "Do or do not; there is no try"; |
---|
500 | //! byte cipher[size]; |
---|
501 | //! ... |
---|
502 | //! ChaCha20 chacha(key, keySize); |
---|
503 | //! chacha.ProcessData(cipher, plain, size); |
---|
504 | //! </pre> |
---|
505 | void ProcessData(byte *outString, const byte *inString, size_t length); |
---|
506 | |
---|
507 | //! \brief Resynchronize the cipher |
---|
508 | //! \param iv a byte array used to resynchronize the cipher |
---|
509 | //! \param length the size of the IV array |
---|
510 | void Resynchronize(const byte *iv, int length=-1); |
---|
511 | |
---|
512 | //! \brief Provides number of ideal bytes to process |
---|
513 | //! \returns the ideal number of bytes to process |
---|
514 | //! \details Internally, the default implementation returns GetBytesPerIteration() |
---|
515 | //! \sa GetBytesPerIteration() and GetOptimalNextBlockSize() |
---|
516 | unsigned int OptimalBlockSize() const {return this->GetPolicy().GetBytesPerIteration();} |
---|
517 | |
---|
518 | //! \brief Provides number of ideal bytes to process |
---|
519 | //! \returns the ideal number of bytes to process |
---|
520 | //! \details Internally, the default implementation returns remaining unprocessed bytes |
---|
521 | //! \sa GetBytesPerIteration() and OptimalBlockSize() |
---|
522 | unsigned int GetOptimalNextBlockSize() const {return (unsigned int)m_leftOver;} |
---|
523 | |
---|
524 | //! \brief Provides number of ideal data alignment |
---|
525 | //! \returns the ideal data alignment, in bytes |
---|
526 | //! \sa GetAlignment() and OptimalBlockSize() |
---|
527 | unsigned int OptimalDataAlignment() const {return this->GetPolicy().GetAlignment();} |
---|
528 | |
---|
529 | //! \brief Flag indicating random access |
---|
530 | //! \returns true if the cipher is seekable, false otherwise |
---|
531 | //! \sa Seek() |
---|
532 | bool IsRandomAccess() const {return false;} |
---|
533 | |
---|
534 | //! \brief Determines if the cipher is self inverting |
---|
535 | //! \returns true if the stream cipher is self inverting, false otherwise |
---|
536 | bool IsSelfInverting() const {return false;} |
---|
537 | |
---|
538 | typedef typename BASE::PolicyInterface PolicyInterface; |
---|
539 | |
---|
540 | protected: |
---|
541 | virtual void CombineMessageAndShiftRegister(byte *output, byte *reg, const byte *message, size_t length) =0; |
---|
542 | |
---|
543 | void UncheckedSetKey(const byte *key, unsigned int length, const NameValuePairs ¶ms); |
---|
544 | |
---|
545 | size_t m_leftOver; |
---|
546 | }; |
---|
547 | |
---|
548 | //! \class CFB_EncryptionTemplate |
---|
549 | //! \brief Base class for feedback based stream ciphers in the forward direction with SymmetricCipher interface |
---|
550 | //! \tparam BASE AbstractPolicyHolder base class |
---|
551 | template <class BASE = AbstractPolicyHolder<CFB_CipherAbstractPolicy, SymmetricCipher> > |
---|
552 | class CRYPTOPP_NO_VTABLE CFB_EncryptionTemplate : public CFB_CipherTemplate<BASE> |
---|
553 | { |
---|
554 | bool IsForwardTransformation() const {return true;} |
---|
555 | void CombineMessageAndShiftRegister(byte *output, byte *reg, const byte *message, size_t length); |
---|
556 | }; |
---|
557 | |
---|
558 | //! \class CFB_DecryptionTemplate |
---|
559 | //! \brief Base class for feedback based stream ciphers in the reverse direction with SymmetricCipher interface |
---|
560 | //! \tparam BASE AbstractPolicyHolder base class |
---|
561 | template <class BASE = AbstractPolicyHolder<CFB_CipherAbstractPolicy, SymmetricCipher> > |
---|
562 | class CRYPTOPP_NO_VTABLE CFB_DecryptionTemplate : public CFB_CipherTemplate<BASE> |
---|
563 | { |
---|
564 | bool IsForwardTransformation() const {return false;} |
---|
565 | void CombineMessageAndShiftRegister(byte *output, byte *reg, const byte *message, size_t length); |
---|
566 | }; |
---|
567 | |
---|
568 | //! \class CFB_RequireFullDataBlocks |
---|
569 | //! \brief Base class for feedback based stream ciphers with a mandatory block size |
---|
570 | //! \tparam BASE CFB_EncryptionTemplate or CFB_DecryptionTemplate base class |
---|
571 | template <class BASE> |
---|
572 | class CFB_RequireFullDataBlocks : public BASE |
---|
573 | { |
---|
574 | public: |
---|
575 | unsigned int MandatoryBlockSize() const {return this->OptimalBlockSize();} |
---|
576 | }; |
---|
577 | |
---|
578 | //! \class SymmetricCipherFinal |
---|
579 | //! \brief SymmetricCipher implementation |
---|
580 | //! \tparam BASE AbstractPolicyHolder derived base class |
---|
581 | //! \tparam INFO AbstractPolicyHolder derived information class |
---|
582 | //! \sa Weak::ARC4, ChaCha8, ChaCha12, ChaCha20, Salsa20, SEAL, Sosemanuk, WAKE |
---|
583 | template <class BASE, class INFO = BASE> |
---|
584 | class SymmetricCipherFinal : public AlgorithmImpl<SimpleKeyingInterfaceImpl<BASE, INFO>, INFO> |
---|
585 | { |
---|
586 | public: |
---|
587 | //! \brief Construct a stream cipher |
---|
588 | SymmetricCipherFinal() {} |
---|
589 | |
---|
590 | //! \brief Construct a stream cipher |
---|
591 | //! \param key a byte array used to key the cipher |
---|
592 | //! \details This overload uses DEFAULT_KEYLENGTH |
---|
593 | SymmetricCipherFinal(const byte *key) |
---|
594 | {this->SetKey(key, this->DEFAULT_KEYLENGTH);} |
---|
595 | |
---|
596 | //! \brief Construct a stream cipher |
---|
597 | //! \param key a byte array used to key the cipher |
---|
598 | //! \param length the size of the key array |
---|
599 | SymmetricCipherFinal(const byte *key, size_t length) |
---|
600 | {this->SetKey(key, length);} |
---|
601 | |
---|
602 | //! \brief Construct a stream cipher |
---|
603 | //! \param key a byte array used to key the cipher |
---|
604 | //! \param length the size of the key array |
---|
605 | //! \param iv a byte array used as an initialization vector |
---|
606 | SymmetricCipherFinal(const byte *key, size_t length, const byte *iv) |
---|
607 | {this->SetKeyWithIV(key, length, iv);} |
---|
608 | |
---|
609 | //! \brief Clone a SymmetricCipher |
---|
610 | //! \returns a new SymmetricCipher based on this object |
---|
611 | Clonable * Clone() const {return static_cast<SymmetricCipher *>(new SymmetricCipherFinal<BASE, INFO>(*this));} |
---|
612 | }; |
---|
613 | |
---|
614 | NAMESPACE_END |
---|
615 | |
---|
616 | #ifdef CRYPTOPP_MANUALLY_INSTANTIATE_TEMPLATES |
---|
617 | #include "strciphr.cpp" |
---|
618 | #endif |
---|
619 | |
---|
620 | NAMESPACE_BEGIN(CryptoPP) |
---|
621 | CRYPTOPP_DLL_TEMPLATE_CLASS AbstractPolicyHolder<AdditiveCipherAbstractPolicy, SymmetricCipher>; |
---|
622 | CRYPTOPP_DLL_TEMPLATE_CLASS AdditiveCipherTemplate<AbstractPolicyHolder<AdditiveCipherAbstractPolicy, SymmetricCipher> >; |
---|
623 | CRYPTOPP_DLL_TEMPLATE_CLASS CFB_CipherTemplate<AbstractPolicyHolder<CFB_CipherAbstractPolicy, SymmetricCipher> >; |
---|
624 | CRYPTOPP_DLL_TEMPLATE_CLASS CFB_EncryptionTemplate<AbstractPolicyHolder<CFB_CipherAbstractPolicy, SymmetricCipher> >; |
---|
625 | CRYPTOPP_DLL_TEMPLATE_CLASS CFB_DecryptionTemplate<AbstractPolicyHolder<CFB_CipherAbstractPolicy, SymmetricCipher> >; |
---|
626 | |
---|
627 | NAMESPACE_END |
---|
628 | |
---|
629 | #if CRYPTOPP_MSC_VERSION |
---|
630 | # pragma warning(pop) |
---|
631 | #endif |
---|
632 | |
---|
633 | #endif |
---|