Crypto++ 7.0 Free C++ class library of cryptographic schemes

strciphr.h
Go to the documentation of this file.
1 // strciphr.h - originally 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
9 /// methods to query which features are supported by a cipher.
10 /// \details Here's an explanation of these classes. The word "policy" is used here to
11 /// mean a class with a set of methods that must be implemented by individual stream
12 /// cipher implementations. This is usually much simpler than the full stream cipher
13 /// API, which is implemented by either AdditiveCipherTemplate or CFB_CipherTemplate
14 /// using the policy. So for example, an implementation of SEAL only needs to implement
15 /// the AdditiveCipherAbstractPolicy interface (since it's an additive cipher, i.e., it
16 /// xors a keystream into the plaintext). 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
21 /// need to take a policy class as a template parameter (although this is allowed), so
22 /// that their code is not duplicated for each new cipher. Instead they each get a
23 /// reference to an abstract policy interface by calling AccessPolicy() on itself, so
24 /// AccessPolicy() must be overridden to return the actual policy reference. This is done
25 /// by the ConceretePolicyHolder class. Finally, SymmetricCipherFinal implements the
26 /// constructors and 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 4231 4275)
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 /// \brief Access a stream cipher policy object
46 /// \tparam POLICY_INTERFACE class implementing AbstractPolicyHolder
47 /// \tparam BASE class or type to use as a base class
48 template <class POLICY_INTERFACE, class BASE = Empty>
49 class CRYPTOPP_NO_VTABLE AbstractPolicyHolder : public BASE
50 {
51 public:
52 typedef POLICY_INTERFACE PolicyInterface;
53 virtual ~AbstractPolicyHolder() {}
54
55 protected:
56 virtual const POLICY_INTERFACE & GetPolicy() const =0;
57 virtual POLICY_INTERFACE & AccessPolicy() =0;
58 };
59
60 /// \brief Stream cipher policy object
61 /// \tparam POLICY class implementing AbstractPolicyHolder
62 /// \tparam BASE class or type to use as a base class
63 template <class POLICY, class BASE, class POLICY_INTERFACE = typename BASE::PolicyInterface>
64 class ConcretePolicyHolder : public BASE, protected POLICY
65 {
66 public:
67 virtual ~ConcretePolicyHolder() {}
68 protected:
69 const POLICY_INTERFACE & GetPolicy() const {return *this;}
70 POLICY_INTERFACE & AccessPolicy() {return *this;}
71 };
72
73 /// \brief Keystream operation flags
74 /// \sa AdditiveCipherAbstractPolicy::GetBytesPerIteration(), AdditiveCipherAbstractPolicy::GetOptimalBlockSize()
75 /// and AdditiveCipherAbstractPolicy::GetAlignment()
76 enum KeystreamOperationFlags {
77 /// \brief Output buffer is aligned
78 OUTPUT_ALIGNED=1,
79 /// \brief Input buffer is aligned
80 INPUT_ALIGNED=2,
81 /// \brief Input buffer is NULL
82 INPUT_NULL = 4
83 };
84
85 /// \brief Keystream operation flags
86 /// \sa AdditiveCipherAbstractPolicy::GetBytesPerIteration(), AdditiveCipherAbstractPolicy::GetOptimalBlockSize()
87 /// and AdditiveCipherAbstractPolicy::GetAlignment()
88 enum KeystreamOperation {
89 /// \brief Wirte the keystream to the output buffer, input is NULL
90 WRITE_KEYSTREAM = INPUT_NULL,
91 /// \brief Wirte the keystream to the aligned output buffer, input is NULL
92 WRITE_KEYSTREAM_ALIGNED = INPUT_NULL | OUTPUT_ALIGNED,
93 /// \brief XOR the input buffer and keystream, write to the output buffer
94 XOR_KEYSTREAM = 0,
95 /// \brief XOR the aligned input buffer and keystream, write to the output buffer
96 XOR_KEYSTREAM_INPUT_ALIGNED = INPUT_ALIGNED,
97 /// \brief XOR the input buffer and keystream, write to the aligned output buffer
98 XOR_KEYSTREAM_OUTPUT_ALIGNED= OUTPUT_ALIGNED,
99 /// \brief XOR the aligned input buffer and keystream, write to the aligned output buffer
100 XOR_KEYSTREAM_BOTH_ALIGNED = OUTPUT_ALIGNED | INPUT_ALIGNED
101 };
102
103 /// \brief Policy object for additive stream ciphers
104 struct CRYPTOPP_DLL CRYPTOPP_NO_VTABLE AdditiveCipherAbstractPolicy
105 {
106 virtual ~AdditiveCipherAbstractPolicy() {}
107
108 /// \brief Provides data alignment requirements
109 /// \returns data alignment requirements, in bytes
110 /// \details Internally, the default implementation returns 1. If the stream cipher is implemented
111 /// using an SSE2 ASM or intrinsics, then the value returned is usually 16.
112 virtual unsigned int GetAlignment() const {return 1;}
113
114 /// \brief Provides number of bytes operated upon during an iteration
115 /// \returns bytes operated upon during an iteration, in bytes
116 /// \sa GetOptimalBlockSize()
117 virtual unsigned int GetBytesPerIteration() const =0;
118
119 /// \brief Provides number of ideal bytes to process
120 /// \returns the ideal number of bytes to process
121 /// \details Internally, the default implementation returns GetBytesPerIteration()
122 /// \sa GetBytesPerIteration()
123 virtual unsigned int GetOptimalBlockSize() const {return GetBytesPerIteration();}
124
125 /// \brief Provides buffer size based on iterations
126 /// \returns the buffer size based on iterations, in bytes
127 virtual unsigned int GetIterationsToBuffer() const =0;
128
129 /// \brief Generate the keystream
130 /// \param keystream the key stream
131 /// \param iterationCount the number of iterations to generate the key stream
132 /// \sa CanOperateKeystream(), OperateKeystream(), WriteKeystream()
133 virtual void WriteKeystream(byte *keystream, size_t iterationCount)
134 {OperateKeystream(KeystreamOperation(INPUT_NULL | static_cast<KeystreamOperationFlags>(IsAlignedOn(keystream, GetAlignment()))), keystream, NULLPTR, iterationCount);}
135
136 /// \brief Flag indicating
137 /// \returns true if the stream can be generated independent of the transformation input, false otherwise
138 /// \sa CanOperateKeystream(), OperateKeystream(), WriteKeystream()
139 virtual bool CanOperateKeystream() const {return false;}
140
141 /// \brief Operates the keystream
142 /// \param operation the operation with additional flags
143 /// \param output the output buffer
144 /// \param input the input buffer
145 /// \param iterationCount the number of iterations to perform on the input
146 /// \details OperateKeystream() will attempt to operate upon GetOptimalBlockSize() buffer,
147 /// which will be derived from GetBytesPerIteration().
148 /// \sa CanOperateKeystream(), OperateKeystream(), WriteKeystream(), KeystreamOperation()
149 virtual void OperateKeystream(KeystreamOperation operation, byte *output, const byte *input, size_t iterationCount)
150 {CRYPTOPP_UNUSED(operation); CRYPTOPP_UNUSED(output); CRYPTOPP_UNUSED(input);
151 CRYPTOPP_UNUSED(iterationCount); CRYPTOPP_ASSERT(false);}
152
153 /// \brief Key the cipher
154 /// \param params set of NameValuePairs use to initialize this object
155 /// \param key a byte array used to key the cipher
156 /// \param length the size of the key array
157 virtual void CipherSetKey(const NameValuePairs &params, const byte *key, size_t length) =0;
158
159 /// \brief Resynchronize the cipher
160 /// \param keystreamBuffer the keystream buffer
161 /// \param iv a byte array used to resynchronize the cipher
162 /// \param length the size of the IV array
163 virtual void CipherResynchronize(byte *keystreamBuffer, const byte *iv, size_t length)
164 {CRYPTOPP_UNUSED(keystreamBuffer); CRYPTOPP_UNUSED(iv); CRYPTOPP_UNUSED(length);
165 throw NotImplemented("SimpleKeyingInterface: this object doesn't support resynchronization");}
166
167 /// \brief Flag indicating random access
168 /// \returns true if the cipher is seekable, false otherwise
169 /// \sa SeekToIteration()
170 virtual bool CipherIsRandomAccess() const =0;
171
172 /// \brief Seeks to a random position in the stream
173 /// \sa CipherIsRandomAccess()
174 virtual void SeekToIteration(lword iterationCount)
175 {CRYPTOPP_UNUSED(iterationCount); CRYPTOPP_ASSERT(!CipherIsRandomAccess());
176 throw NotImplemented("StreamTransformation: this object doesn't support random access");}
177
178 /// \brief Retrieve the provider of this algorithm
179 /// \return the algorithm provider
180 /// \details The algorithm provider can be a name like "C++", "SSE", "NEON", "AESNI",
181 /// "ARMv8" and "Power8". C++ is standard C++ code. Other labels, like SSE,
182 /// usually indicate a specialized implementation using instructions from a higher
183 /// instruction set architecture (ISA). Future labels may include external hardware
184 /// like a hardware security module (HSM).
185 /// \details Generally speaking Wei Dai's original IA-32 ASM code falls under "SSE2".
186 /// Labels like "SSSE3" and "SSE4.1" follow after Wei's code and use intrinsics
187 /// instead of ASM.
188 /// \details Algorithms which combine different instructions or ISAs provide the
189 /// dominant one. For example on x86 <tt>AES/GCM</tt> returns "AESNI" rather than
190 /// "CLMUL" or "AES+SSE4.1" or "AES+CLMUL" or "AES+SSE4.1+CLMUL".
191 /// \note Provider is not universally implemented yet.
192 virtual std::string AlgorithmProvider() const { return "C++"; }
193 };
194
195 /// \brief Base class for additive stream ciphers
196 /// \tparam WT word type
197 /// \tparam W count of words
198 /// \tparam X bytes per iteration count
199 /// \tparam BASE AdditiveCipherAbstractPolicy derived base class
200 template <typename WT, unsigned int W, unsigned int X = 1, class BASE = AdditiveCipherAbstractPolicy>
201 struct CRYPTOPP_NO_VTABLE AdditiveCipherConcretePolicy : public BASE
202 {
203 typedef WT WordType;
204 CRYPTOPP_CONSTANT(BYTES_PER_ITERATION = sizeof(WordType) * W)
205
206 virtual ~AdditiveCipherConcretePolicy() {}
207
208 #if !(CRYPTOPP_BOOL_X86 || CRYPTOPP_BOOL_X64)
209 /// \brief Provides data alignment requirements
210 /// \returns data alignment requirements, in bytes
211 /// \details Internally, the default implementation returns 1. If the stream cipher is implemented
212 /// using an SSE2 ASM or intrinsics, then the value returned is usually 16.
213 unsigned int GetAlignment() const {return GetAlignmentOf<WordType>();}
214 #endif
215
216 /// \brief Provides number of bytes operated upon during an iteration
217 /// \returns bytes operated upon during an iteration, in bytes
218 /// \sa GetOptimalBlockSize()
219 unsigned int GetBytesPerIteration() const {return BYTES_PER_ITERATION;}
220
221 /// \brief Provides buffer size based on iterations
222 /// \returns the buffer size based on iterations, in bytes
223 unsigned int GetIterationsToBuffer() const {return X;}
224
225 /// \brief Flag indicating
226 /// \returns true if the stream can be generated independent of the transformation input, false otherwise
227 /// \sa CanOperateKeystream(), OperateKeystream(), WriteKeystream()
228 bool CanOperateKeystream() const {return true;}
229
230 /// \brief Operates the keystream
231 /// \param operation the operation with additional flags
232 /// \param output the output buffer
233 /// \param input the input buffer
234 /// \param iterationCount the number of iterations to perform on the input
235 /// \details OperateKeystream() will attempt to operate upon GetOptimalBlockSize() buffer,
236 /// which will be derived from GetBytesPerIteration().
237 /// \sa CanOperateKeystream(), OperateKeystream(), WriteKeystream(), KeystreamOperation()
238 virtual void OperateKeystream(KeystreamOperation operation, byte *output, const byte *input, size_t iterationCount) =0;
239 };
240
241 /// \brief Helper macro to implement OperateKeystream
242 /// \param x KeystreamOperation mask
243 /// \param b Endian order
244 /// \param i index in output buffer
245 /// \param a value to output
246 #define CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, b, i, a) \
247 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)));
248
249 /// \brief Helper macro to implement OperateKeystream
250 /// \param x KeystreamOperation mask
251 /// \param i index in output buffer
252 /// \param a value to output
253 #define CRYPTOPP_KEYSTREAM_OUTPUT_XMM(x, i, a) {\
254 __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));\
255 if (x & OUTPUT_ALIGNED) _mm_store_si128((__m128i *)output+i, t);\
256 else _mm_storeu_si128((__m128i *)output+i, t);}
257
258 /// \brief Helper macro to implement OperateKeystream
259 #define CRYPTOPP_KEYSTREAM_OUTPUT_SWITCH(x, y) \
260 switch (operation) \
261 { \
262 case WRITE_KEYSTREAM: \
263 x(WRITE_KEYSTREAM) \
264 break; \
265 case XOR_KEYSTREAM: \
266 x(XOR_KEYSTREAM) \
267 input += y; \
268 break; \
269 case XOR_KEYSTREAM_INPUT_ALIGNED: \
270 x(XOR_KEYSTREAM_INPUT_ALIGNED) \
271 input += y; \
272 break; \
273 case XOR_KEYSTREAM_OUTPUT_ALIGNED: \
274 x(XOR_KEYSTREAM_OUTPUT_ALIGNED) \
275 input += y; \
276 break; \
277 case WRITE_KEYSTREAM_ALIGNED: \
278 x(WRITE_KEYSTREAM_ALIGNED) \
279 break; \
280 case XOR_KEYSTREAM_BOTH_ALIGNED: \
281 x(XOR_KEYSTREAM_BOTH_ALIGNED) \
282 input += y; \
283 break; \
284 } \
285 output += y;
286
287 /// \brief Base class for additive stream ciphers with SymmetricCipher interface
288 /// \tparam BASE AbstractPolicyHolder base class
289 template <class BASE = AbstractPolicyHolder<AdditiveCipherAbstractPolicy, SymmetricCipher> >
290 class CRYPTOPP_NO_VTABLE AdditiveCipherTemplate : public BASE, public RandomNumberGenerator
291 {
292 public:
293 virtual ~AdditiveCipherTemplate() {}
294 AdditiveCipherTemplate() : m_leftOver(0) {}
295
296 /// \brief Generate random array of bytes
297 /// \param output the byte buffer
298 /// \param size the length of the buffer, in bytes
299 /// \details All generated values are uniformly distributed over the range specified
300 /// within the constraints of a particular generator.
301 void GenerateBlock(byte *output, size_t size);
302
303 /// \brief Apply keystream to data
304 /// \param outString a buffer to write the transformed data
305 /// \param inString a buffer to read the data
306 /// \param length the size fo the buffers, in bytes
307 /// \details This is the primary method to operate a stream cipher. For example:
308 /// <pre>
309 /// size_t size = 30;
310 /// byte plain[size] = "Do or do not; there is no try";
311 /// byte cipher[size];
312 /// ...
313 /// ChaCha20 chacha(key, keySize);
314 /// chacha.ProcessData(cipher, plain, size);
315 /// </pre>
316 void ProcessData(byte *outString, const byte *inString, size_t length);
317
318 /// \brief Resynchronize the cipher
319 /// \param iv a byte array used to resynchronize the cipher
320 /// \param length the size of the IV array
321 void Resynchronize(const byte *iv, int length=-1);
322
323 /// \brief Provides number of ideal bytes to process
324 /// \returns the ideal number of bytes to process
325 /// \details Internally, the default implementation returns GetBytesPerIteration()
326 /// \sa GetBytesPerIteration() and GetOptimalNextBlockSize()
327 unsigned int OptimalBlockSize() const {return this->GetPolicy().GetOptimalBlockSize();}
328
329 /// \brief Provides number of ideal bytes to process
330 /// \returns the ideal number of bytes to process
331 /// \details Internally, the default implementation returns remaining unprocessed bytes
332 /// \sa GetBytesPerIteration() and OptimalBlockSize()
333 unsigned int GetOptimalNextBlockSize() const {return (unsigned int)this->m_leftOver;}
334
335 /// \brief Provides number of ideal data alignment
336 /// \returns the ideal data alignment, in bytes
337 /// \sa GetAlignment() and OptimalBlockSize()
338 unsigned int OptimalDataAlignment() const {return this->GetPolicy().GetAlignment();}
339
340 /// \brief Determines if the cipher is self inverting
341 /// \returns true if the stream cipher is self inverting, false otherwise
342 bool IsSelfInverting() const {return true;}
343
344 /// \brief Determines if the cipher is a forward transformation
345 /// \returns true if the stream cipher is a forward transformation, false otherwise
346 bool IsForwardTransformation() const {return true;}
347
348 /// \brief Flag indicating random access
349 /// \returns true if the cipher is seekable, false otherwise
350 /// \sa Seek()
351 bool IsRandomAccess() const {return this->GetPolicy().CipherIsRandomAccess();}
352
353 /// \brief Seeks to a random position in the stream
354 /// \param position the absolute position in the stream
355 /// \sa IsRandomAccess()
356 void Seek(lword position);
357
358 /// \brief Retrieve the provider of this algorithm
359 /// \return the algorithm provider
360 /// \details The algorithm provider can be a name like "C++", "SSE", "NEON", "AESNI",
361 /// "ARMv8" and "Power8". C++ is standard C++ code. Other labels, like SSE,
362 /// usually indicate a specialized implementation using instructions from a higher
363 /// instruction set architecture (ISA). Future labels may include external hardware
364 /// like a hardware security module (HSM).
365 /// \details Generally speaking Wei Dai's original IA-32 ASM code falls under "SSE2".
366 /// Labels like "SSSE3" and "SSE4.1" follow after Wei's code and use intrinsics
367 /// instead of ASM.
368 /// \details Algorithms which combine different instructions or ISAs provide the
369 /// dominant one. For example on x86 <tt>AES/GCM</tt> returns "AESNI" rather than
370 /// "CLMUL" or "AES+SSE4.1" or "AES+CLMUL" or "AES+SSE4.1+CLMUL".
371 /// \note Provider is not universally implemented yet.
372 std::string AlgorithmProvider() const { return this->GetPolicy().AlgorithmProvider(); }
373
374 typedef typename BASE::PolicyInterface PolicyInterface;
375
376 protected:
377 void UncheckedSetKey(const byte *key, unsigned int length, const NameValuePairs &params);
378
379 unsigned int GetBufferByteSize(const PolicyInterface &policy) const {return policy.GetBytesPerIteration() * policy.GetIterationsToBuffer();}
380
381 inline byte * KeystreamBufferBegin() {return this->m_buffer.data();}
382 inline byte * KeystreamBufferEnd() {return (PtrAdd(this->m_buffer.data(), this->m_buffer.size()));}
383
384 AlignedSecByteBlock m_buffer;
385 size_t m_leftOver;
386 };
387
388 /// \brief Policy object for feeback based stream ciphers
389 class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE CFB_CipherAbstractPolicy
390 {
391 public:
392 virtual ~CFB_CipherAbstractPolicy() {}
393
394 /// \brief Provides data alignment requirements
395 /// \returns data alignment requirements, in bytes
396 /// \details Internally, the default implementation returns 1. If the stream cipher is implemented
397 /// using an SSE2 ASM or intrinsics, then the value returned is usually 16.
398 virtual unsigned int GetAlignment() const =0;
399
400 /// \brief Provides number of bytes operated upon during an iteration
401 /// \returns bytes operated upon during an iteration, in bytes
402 /// \sa GetOptimalBlockSize()
403 virtual unsigned int GetBytesPerIteration() const =0;
404
405 /// \brief Access the feedback register
406 /// \returns pointer to the first byte of the feedback register
407 virtual byte * GetRegisterBegin() =0;
408
409 /// \brief TODO
410 virtual void TransformRegister() =0;
411
412 /// \brief Flag indicating iteration support
413 /// \returns true if the cipher supports iteration, false otherwise
414 virtual bool CanIterate() const {return false;}
415
416 /// \brief Iterate the cipher
417 /// \param output the output buffer
418 /// \param input the input buffer
419 /// \param dir the direction of the cipher
420 /// \param iterationCount the number of iterations to perform on the input
421 /// \sa IsSelfInverting() and IsForwardTransformation()
422 virtual void Iterate(byte *output, const byte *input, CipherDir dir, size_t iterationCount)
423 {CRYPTOPP_UNUSED(output); CRYPTOPP_UNUSED(input); CRYPTOPP_UNUSED(dir);
424 CRYPTOPP_UNUSED(iterationCount); CRYPTOPP_ASSERT(false);
425 throw Exception(Exception::OTHER_ERROR, "SimpleKeyingInterface: unexpected error");}
426
427 /// \brief Key the cipher
428 /// \param params set of NameValuePairs use to initialize this object
429 /// \param key a byte array used to key the cipher
430 /// \param length the size of the key array
431 virtual void CipherSetKey(const NameValuePairs &params, const byte *key, size_t length) =0;
432
433 /// \brief Resynchronize the cipher
434 /// \param iv a byte array used to resynchronize the cipher
435 /// \param length the size of the IV array
436 virtual void CipherResynchronize(const byte *iv, size_t length)
437 {CRYPTOPP_UNUSED(iv); CRYPTOPP_UNUSED(length);
438 throw NotImplemented("SimpleKeyingInterface: this object doesn't support resynchronization");}
439
440 /// \brief Retrieve the provider of this algorithm
441 /// \return the algorithm provider
442 /// \details The algorithm provider can be a name like "C++", "SSE", "NEON", "AESNI",
443 /// "ARMv8" and "Power8". C++ is standard C++ code. Other labels, like SSE,
444 /// usually indicate a specialized implementation using instructions from a higher
445 /// instruction set architecture (ISA). Future labels may include external hardware
446 /// like a hardware security module (HSM).
447 /// \details Generally speaking Wei Dai's original IA-32 ASM code falls under "SSE2".
448 /// Labels like "SSSE3" and "SSE4.1" follow after Wei's code and use intrinsics
449 /// instead of ASM.
450 /// \details Algorithms which combine different instructions or ISAs provide the
451 /// dominant one. For example on x86 <tt>AES/GCM</tt> returns "AESNI" rather than
452 /// "CLMUL" or "AES+SSE4.1" or "AES+CLMUL" or "AES+SSE4.1+CLMUL".
453 /// \note Provider is not universally implemented yet.
454 virtual std::string AlgorithmProvider() const { return "C++"; }
455 };
456
457 /// \brief Base class for feedback based stream ciphers
458 /// \tparam WT word type
459 /// \tparam W count of words
460 /// \tparam BASE CFB_CipherAbstractPolicy derived base class
461 template <typename WT, unsigned int W, class BASE = CFB_CipherAbstractPolicy>
462 struct CRYPTOPP_NO_VTABLE CFB_CipherConcretePolicy : public BASE
463 {
464 typedef WT WordType;
465
466 virtual ~CFB_CipherConcretePolicy() {}
467
468 /// \brief Provides data alignment requirements
469 /// \returns data alignment requirements, in bytes
470 /// \details Internally, the default implementation returns 1. If the stream cipher is implemented
471 /// using an SSE2 ASM or intrinsics, then the value returned is usually 16.
472 unsigned int GetAlignment() const {return sizeof(WordType);}
473
474 /// \brief Provides number of bytes operated upon during an iteration
475 /// \returns bytes operated upon during an iteration, in bytes
476 /// \sa GetOptimalBlockSize()
477 unsigned int GetBytesPerIteration() const {return sizeof(WordType) * W;}
478
479 /// \brief Flag indicating iteration support
480 /// \returns true if the cipher supports iteration, false otherwise
481 bool CanIterate() const {return true;}
482
483 /// \brief Perform one iteration in the forward direction
484 void TransformRegister() {this->Iterate(NULLPTR, NULLPTR, ENCRYPTION, 1);}
485
486 /// \brief Provides alternate access to a feedback register
487 /// \tparam B enumeration indicating endianness
488 /// \details RegisterOutput() provides alternate access to the feedback register. The
489 /// enumeration B is BigEndian or LittleEndian. Repeatedly applying operator()
490 /// results in advancing in the register.
491 template <class B>
492 struct RegisterOutput
493 {
494 RegisterOutput(byte *output, const byte *input, CipherDir dir)
495 : m_output(output), m_input(input), m_dir(dir) {}
496
497 /// \brief XOR feedback register with data
498 /// \param registerWord data represented as a word type
499 /// \returns reference to the next feedback register word
500 inline RegisterOutput& operator()(WordType &registerWord)
501 {
502 //CRYPTOPP_ASSERT(IsAligned<WordType>(m_output));
503 //CRYPTOPP_ASSERT(IsAligned<WordType>(m_input));
504
505 if (!NativeByteOrderIs(B::ToEnum()))
506 registerWord = ByteReverse(registerWord);
507
508 if (m_dir == ENCRYPTION)
509 {
510 if (m_input == NULLPTR)
511 {
512 CRYPTOPP_ASSERT(m_output == NULLPTR);
513 }
514 else
515 {
516 // WordType ct = *(const WordType *)m_input ^ registerWord;
517 WordType ct = GetWord<WordType>(false, NativeByteOrder::ToEnum(), m_input) ^ registerWord;
518 registerWord = ct;
519
520 // *(WordType*)m_output = ct;
521 PutWord<WordType>(false, NativeByteOrder::ToEnum(), m_output, ct);
522
523 m_input += sizeof(WordType);
524 m_output += sizeof(WordType);
525 }
526 }
527 else
528 {
529 // WordType ct = *(const WordType *)m_input;
530 WordType ct = GetWord<WordType>(false, NativeByteOrder::ToEnum(), m_input);
531
532 // *(WordType*)m_output = registerWord ^ ct;
533 PutWord<WordType>(false, NativeByteOrder::ToEnum(), m_output, registerWord ^ ct);
534 registerWord = ct;
535
536 m_input += sizeof(WordType);
537 m_output += sizeof(WordType);
538 }
539
540 // registerWord is left unreversed so it can be xor-ed with further input
541
542 return *this;
543 }
544
545 byte *m_output;
546 const byte *m_input;
547 CipherDir m_dir;
548 };
549 };
550
551 /// \brief Base class for feedback based stream ciphers with SymmetricCipher interface
552 /// \tparam BASE AbstractPolicyHolder base class
553 template <class BASE>
554 class CRYPTOPP_NO_VTABLE CFB_CipherTemplate : public BASE
555 {
556 public:
557 virtual ~CFB_CipherTemplate() {}
558 CFB_CipherTemplate() : m_leftOver(0) {}
559
560 /// \brief Apply keystream to data
561 /// \param outString a buffer to write the transformed data
562 /// \param inString a buffer to read the data
563 /// \param length the size fo the buffers, in bytes
564 /// \details This is the primary method to operate a stream cipher. For example:
565 /// <pre>
566 /// size_t size = 30;
567 /// byte plain[size] = "Do or do not; there is no try";
568 /// byte cipher[size];
569 /// ...
570 /// ChaCha20 chacha(key, keySize);
571 /// chacha.ProcessData(cipher, plain, size);
572 /// </pre>
573 void ProcessData(byte *outString, const byte *inString, size_t length);
574
575 /// \brief Resynchronize the cipher
576 /// \param iv a byte array used to resynchronize the cipher
577 /// \param length the size of the IV array
578 void Resynchronize(const byte *iv, int length=-1);
579
580 /// \brief Provides number of ideal bytes to process
581 /// \returns the ideal number of bytes to process
582 /// \details Internally, the default implementation returns GetBytesPerIteration()
583 /// \sa GetBytesPerIteration() and GetOptimalNextBlockSize()
584 unsigned int OptimalBlockSize() const {return this->GetPolicy().GetBytesPerIteration();}
585
586 /// \brief Provides number of ideal bytes to process
587 /// \returns the ideal number of bytes to process
588 /// \details Internally, the default implementation returns remaining unprocessed bytes
589 /// \sa GetBytesPerIteration() and OptimalBlockSize()
590 unsigned int GetOptimalNextBlockSize() const {return (unsigned int)m_leftOver;}
591
592 /// \brief Provides number of ideal data alignment
593 /// \returns the ideal data alignment, in bytes
594 /// \sa GetAlignment() and OptimalBlockSize()
595 unsigned int OptimalDataAlignment() const {return this->GetPolicy().GetAlignment();}
596
597 /// \brief Flag indicating random access
598 /// \returns true if the cipher is seekable, false otherwise
599 /// \sa Seek()
600 bool IsRandomAccess() const {return false;}
601
602 /// \brief Determines if the cipher is self inverting
603 /// \returns true if the stream cipher is self inverting, false otherwise
604 bool IsSelfInverting() const {return false;}
605
606 /// \brief Retrieve the provider of this algorithm
607 /// \return the algorithm provider
608 /// \details The algorithm provider can be a name like "C++", "SSE", "NEON", "AESNI",
609 /// "ARMv8" and "Power8". C++ is standard C++ code. Other labels, like SSE,
610 /// usually indicate a specialized implementation using instructions from a higher
611 /// instruction set architecture (ISA). Future labels may include external hardware
612 /// like a hardware security module (HSM).
613 /// \details Generally speaking Wei Dai's original IA-32 ASM code falls under "SSE2".
614 /// Labels like "SSSE3" and "SSE4.1" follow after Wei's code and use intrinsics
615 /// instead of ASM.
616 /// \details Algorithms which combine different instructions or ISAs provide the
617 /// dominant one. For example on x86 <tt>AES/GCM</tt> returns "AESNI" rather than
618 /// "CLMUL" or "AES+SSE4.1" or "AES+CLMUL" or "AES+SSE4.1+CLMUL".
619 /// \note Provider is not universally implemented yet.
620 std::string AlgorithmProvider() const { return this->GetPolicy().AlgorithmProvider(); }
621
622 typedef typename BASE::PolicyInterface PolicyInterface;
623
624 protected:
625 virtual void CombineMessageAndShiftRegister(byte *output, byte *reg, const byte *message, size_t length) =0;
626
627 void UncheckedSetKey(const byte *key, unsigned int length, const NameValuePairs &params);
628
629 size_t m_leftOver;
630 };
631
632 /// \brief Base class for feedback based stream ciphers in the forward direction with SymmetricCipher interface
633 /// \tparam BASE AbstractPolicyHolder base class
634 template <class BASE = AbstractPolicyHolder<CFB_CipherAbstractPolicy, SymmetricCipher> >
635 class CRYPTOPP_NO_VTABLE CFB_EncryptionTemplate : public CFB_CipherTemplate<BASE>
636 {
637 bool IsForwardTransformation() const {return true;}
638 void CombineMessageAndShiftRegister(byte *output, byte *reg, const byte *message, size_t length);
639 };
640
641 /// \brief Base class for feedback based stream ciphers in the reverse direction with SymmetricCipher interface
642 /// \tparam BASE AbstractPolicyHolder base class
643 template <class BASE = AbstractPolicyHolder<CFB_CipherAbstractPolicy, SymmetricCipher> >
644 class CRYPTOPP_NO_VTABLE CFB_DecryptionTemplate : public CFB_CipherTemplate<BASE>
645 {
646 bool IsForwardTransformation() const {return false;}
647 void CombineMessageAndShiftRegister(byte *output, byte *reg, const byte *message, size_t length);
648 };
649
650 /// \brief Base class for feedback based stream ciphers with a mandatory block size
651 /// \tparam BASE CFB_EncryptionTemplate or CFB_DecryptionTemplate base class
652 template <class BASE>
653 class CFB_RequireFullDataBlocks : public BASE
654 {
655 public:
656 unsigned int MandatoryBlockSize() const {return this->OptimalBlockSize();}
657 };
658
659 /// \brief SymmetricCipher implementation
660 /// \tparam BASE AbstractPolicyHolder derived base class
661 /// \tparam INFO AbstractPolicyHolder derived information class
662 /// \sa Weak::ARC4, ChaCha8, ChaCha12, ChaCha20, Salsa20, SEAL, Sosemanuk, WAKE
663 template <class BASE, class INFO = BASE>
664 class SymmetricCipherFinal : public AlgorithmImpl<SimpleKeyingInterfaceImpl<BASE, INFO>, INFO>
665 {
666 public:
667 virtual ~SymmetricCipherFinal() {}
668
669 /// \brief Construct a stream cipher
670 SymmetricCipherFinal() {}
671
672 /// \brief Construct a stream cipher
673 /// \param key a byte array used to key the cipher
674 /// \details This overload uses DEFAULT_KEYLENGTH
675 SymmetricCipherFinal(const byte *key)
676 {this->SetKey(key, this->DEFAULT_KEYLENGTH);}
677
678 /// \brief Construct a stream cipher
679 /// \param key a byte array used to key the cipher
680 /// \param length the size of the key array
681 SymmetricCipherFinal(const byte *key, size_t length)
682 {this->SetKey(key, length);}
683
684 /// \brief Construct a stream cipher
685 /// \param key a byte array used to key the cipher
686 /// \param length the size of the key array
687 /// \param iv a byte array used as an initialization vector
688 SymmetricCipherFinal(const byte *key, size_t length, const byte *iv)
689 {this->SetKeyWithIV(key, length, iv);}
690
691 /// \brief Clone a SymmetricCipher
692 /// \returns a new SymmetricCipher based on this object
693 Clonable * Clone() const {return static_cast<SymmetricCipher *>(new SymmetricCipherFinal<BASE, INFO>(*this));}
694 };
695
696 NAMESPACE_END
697
698 #ifdef CRYPTOPP_MANUALLY_INSTANTIATE_TEMPLATES
699 #include "strciphr.cpp"
700 #endif
701
702 NAMESPACE_BEGIN(CryptoPP)
703 CRYPTOPP_DLL_TEMPLATE_CLASS AbstractPolicyHolder<AdditiveCipherAbstractPolicy, SymmetricCipher>;
704 CRYPTOPP_DLL_TEMPLATE_CLASS AdditiveCipherTemplate<AbstractPolicyHolder<AdditiveCipherAbstractPolicy, SymmetricCipher> >;
705 CRYPTOPP_DLL_TEMPLATE_CLASS CFB_CipherTemplate<AbstractPolicyHolder<CFB_CipherAbstractPolicy, SymmetricCipher> >;
706 CRYPTOPP_DLL_TEMPLATE_CLASS CFB_EncryptionTemplate<AbstractPolicyHolder<CFB_CipherAbstractPolicy, SymmetricCipher> >;
707 CRYPTOPP_DLL_TEMPLATE_CLASS CFB_DecryptionTemplate<AbstractPolicyHolder<CFB_CipherAbstractPolicy, SymmetricCipher> >;
708
709 NAMESPACE_END
710
711 #if CRYPTOPP_MSC_VERSION
712 # pragma warning(pop)
713 #endif
714
715 #endif
Exception
Base class for all exceptions thrown by the library.
Definition: cryptlib.h:158
CFB_CipherTemplate::GetOptimalNextBlockSize
unsigned int GetOptimalNextBlockSize() const
Provides number of ideal bytes to process.
Definition: strciphr.h:590
argnames.h
Standard names for retrieving values by name when working with NameValuePairs.
AdditiveCipherConcretePolicy::CanOperateKeystream
bool CanOperateKeystream() const
Flag indicating.
Definition: strciphr.h:228
NativeByteOrderIs
bool NativeByteOrderIs(ByteOrder order)
Determines whether order follows native byte ordering.
Definition: misc.h:1130
OUTPUT_ALIGNED
Output buffer is aligned.
Definition: strciphr.h:78
AdditiveCipherTemplate::AlgorithmProvider
std::string AlgorithmProvider() const
Retrieve the provider of this algorithm.
Definition: strciphr.h:372
SymmetricCipherFinal::SymmetricCipherFinal
SymmetricCipherFinal(const byte *key)
Construct a stream cipher.
Definition: strciphr.h:675
AdditiveCipherTemplate::OptimalBlockSize
unsigned int OptimalBlockSize() const
Provides number of ideal bytes to process.
Definition: strciphr.h:327
INPUT_ALIGNED
Input buffer is aligned.
Definition: strciphr.h:80
RandomNumberGenerator::GenerateBlock
virtual void GenerateBlock(byte *output, size_t size)
Generate random array of bytes.
Definition: cryptlib.cpp:311
CFB_CipherTemplate::IsRandomAccess
bool IsRandomAccess() const
Flag indicating random access.
Definition: strciphr.h:600
CFB_CipherConcretePolicy
Base class for feedback based stream ciphers.
Definition: strciphr.h:462
AdditiveCipherConcretePolicy
Base class for additive stream ciphers.
Definition: strciphr.h:201
AdditiveCipherAbstractPolicy::OperateKeystream
virtual void OperateKeystream(KeystreamOperation operation, byte *output, const byte *input, size_t iterationCount)
Operates the keystream.
Definition: strciphr.h:149
AdditiveCipherTemplate::GetOptimalNextBlockSize
unsigned int GetOptimalNextBlockSize() const
Provides number of ideal bytes to process.
Definition: strciphr.h:333
XOR_KEYSTREAM_OUTPUT_ALIGNED
XOR the input buffer and keystream, write to the aligned output buffer.
Definition: strciphr.h:98
CFB_CipherConcretePolicy::GetBytesPerIteration
unsigned int GetBytesPerIteration() const
Provides number of bytes operated upon during an iteration.
Definition: strciphr.h:477
XOR_KEYSTREAM
XOR the input buffer and keystream, write to the output buffer.
Definition: strciphr.h:94
CipherDir
CipherDir
Specifies a direction for a cipher to operate.
Definition: cryptlib.h:123
cryptlib.h
Abstract base classes that provide a uniform interface to this library.
CFB_CipherTemplate
Base class for feedback based stream ciphers with SymmetricCipher interface.
Definition: strciphr.h:554
AdditiveCipherTemplate::OptimalDataAlignment
unsigned int OptimalDataAlignment() const
Provides number of ideal data alignment.
Definition: strciphr.h:338
Exception::OTHER_ERROR
Some other error occurred not belonging to other categories.
Definition: cryptlib.h:177
config.h
Library configuration file.
AdditiveCipherAbstractPolicy::GetOptimalBlockSize
virtual unsigned int GetOptimalBlockSize() const
Provides number of ideal bytes to process.
Definition: strciphr.h:123
RandomNumberGenerator
Interface for random number generators.
Definition: cryptlib.h:1349
AdditiveCipherConcretePolicy::GetAlignment
unsigned int GetAlignment() const
Provides data alignment requirements.
Definition: strciphr.h:213
WRITE_KEYSTREAM
Wirte the keystream to the output buffer, input is NULL.
Definition: strciphr.h:90
ConcretePolicyHolder
Stream cipher policy object.
Definition: strciphr.h:64
AdditiveCipherAbstractPolicy::CanOperateKeystream
virtual bool CanOperateKeystream() const
Flag indicating.
Definition: strciphr.h:139
Clonable
Interface for cloning objects.
Definition: cryptlib.h:556
AdditiveCipherAbstractPolicy::WriteKeystream
virtual void WriteKeystream(byte *keystream, size_t iterationCount)
Generate the keystream.
Definition: strciphr.h:133
AdditiveCipherAbstractPolicy
Policy object for additive stream ciphers.
Definition: strciphr.h:104
ENCRYPTION
the cipher is performing encryption
Definition: cryptlib.h:125
secblock.h
Classes and functions for secure memory allocations.
CFB_CipherConcretePolicy::TransformRegister
void TransformRegister()
Perform one iteration in the forward direction.
Definition: strciphr.h:484
IsAlignedOn
bool IsAlignedOn(const void *ptr, unsigned int alignment)
Determines whether ptr is aligned to a minimum value.
Definition: misc.h:1085
INPUT_NULL
Input buffer is NULL.
Definition: strciphr.h:82
CFB_DecryptionTemplate
Base class for feedback based stream ciphers in the reverse direction with SymmetricCipher interface...
Definition: strciphr.h:644
AdditiveCipherTemplate::IsSelfInverting
bool IsSelfInverting() const
Determines if the cipher is self inverting.
Definition: strciphr.h:342
CFB_CipherConcretePolicy::RegisterOutput
Provides alternate access to a feedback register.
Definition: strciphr.h:492
AdditiveCipherConcretePolicy::GetBytesPerIteration
unsigned int GetBytesPerIteration() const
Provides number of bytes operated upon during an iteration.
Definition: strciphr.h:219
NotImplemented
A method was called which was not implemented.
Definition: cryptlib.h:223
AdditiveCipherAbstractPolicy::GetAlignment
virtual unsigned int GetAlignment() const
Provides data alignment requirements.
Definition: strciphr.h:112
CFB_CipherConcretePolicy::CanIterate
bool CanIterate() const
Flag indicating iteration support.
Definition: strciphr.h:481
CFB_CipherConcretePolicy::RegisterOutput::operator()
RegisterOutput & operator()(WordType &registerWord)
XOR feedback register with data.
Definition: strciphr.h:500
seckey.h
Classes and functions for implementing secret key algorithms.
CFB_CipherAbstractPolicy::AlgorithmProvider
virtual std::string AlgorithmProvider() const
Retrieve the provider of this algorithm.
Definition: strciphr.h:454
AdditiveCipherAbstractPolicy::SeekToIteration
virtual void SeekToIteration(lword iterationCount)
Seeks to a random position in the stream.
Definition: strciphr.h:174
CFB_CipherTemplate::OptimalBlockSize
unsigned int OptimalBlockSize() const
Provides number of ideal bytes to process.
Definition: strciphr.h:584
SymmetricCipher
Interface for one direction (encryption or decryption) of a stream cipher or cipher mode...
Definition: cryptlib.h:1256
CFB_RequireFullDataBlocks
Base class for feedback based stream ciphers with a mandatory block size.
Definition: strciphr.h:653
CFB_CipherAbstractPolicy
Policy object for feeback based stream ciphers.
Definition: strciphr.h:389
CFB_CipherTemplate::AlgorithmProvider
std::string AlgorithmProvider() const
Retrieve the provider of this algorithm.
Definition: strciphr.h:620
AlignedSecByteBlock
SecBlock using AllocatorWithCleanup<byte, true> typedef.
Definition: secblock.h:1056
CFB_EncryptionTemplate
Base class for feedback based stream ciphers in the forward direction with SymmetricCipher interface...
Definition: strciphr.h:635
SymmetricCipherFinal::SymmetricCipherFinal
SymmetricCipherFinal()
Construct a stream cipher.
Definition: strciphr.h:670
CRYPTOPP_ASSERT
#define CRYPTOPP_ASSERT(exp)
Debugging and diagnostic assertion.
Definition: trap.h:60
CFB_CipherTemplate::IsSelfInverting
bool IsSelfInverting() const
Determines if the cipher is self inverting.
Definition: strciphr.h:604
AdditiveCipherTemplate::IsRandomAccess
bool IsRandomAccess() const
Flag indicating random access.
Definition: strciphr.h:351
PtrAdd
PTR PtrAdd(PTR pointer, OFF offset)
Create a pointer with an offset.
Definition: misc.h:371
CFB_CipherTemplate::OptimalDataAlignment
unsigned int OptimalDataAlignment() const
Provides number of ideal data alignment.
Definition: strciphr.h:595
XOR_KEYSTREAM_BOTH_ALIGNED
XOR the aligned input buffer and keystream, write to the aligned output buffer.
Definition: strciphr.h:100
CFB_CipherAbstractPolicy::CanIterate
virtual bool CanIterate() const
Flag indicating iteration support.
Definition: strciphr.h:414
SymmetricCipherFinal::SymmetricCipherFinal
SymmetricCipherFinal(const byte *key, size_t length, const byte *iv)
Construct a stream cipher.
Definition: strciphr.h:688
SymmetricCipherFinal::Clone
Clonable * Clone() const
Clone a SymmetricCipher.
Definition: strciphr.h:693
AdditiveCipherAbstractPolicy::CipherResynchronize
virtual void CipherResynchronize(byte *keystreamBuffer, const byte *iv, size_t length)
Resynchronize the cipher.
Definition: strciphr.h:163
CFB_CipherAbstractPolicy::Iterate
virtual void Iterate(byte *output, const byte *input, CipherDir dir, size_t iterationCount)
Iterate the cipher.
Definition: strciphr.h:422
CFB_CipherConcretePolicy::GetAlignment
unsigned int GetAlignment() const
Provides data alignment requirements.
Definition: strciphr.h:472
KeystreamOperation
KeystreamOperation
Keystream operation flags.
Definition: strciphr.h:88
SymmetricCipherFinal::SymmetricCipherFinal
SymmetricCipherFinal(const byte *key, size_t length)
Construct a stream cipher.
Definition: strciphr.h:681
AdditiveCipherAbstractPolicy::AlgorithmProvider
virtual std::string AlgorithmProvider() const
Retrieve the provider of this algorithm.
Definition: strciphr.h:192
CFB_CipherAbstractPolicy::CipherResynchronize
virtual void CipherResynchronize(const byte *iv, size_t length)
Resynchronize the cipher.
Definition: strciphr.h:436
CryptoPP
Crypto++ library namespace.
AdditiveCipherTemplate::IsForwardTransformation
bool IsForwardTransformation() const
Determines if the cipher is a forward transformation.
Definition: strciphr.h:346
SymmetricCipherFinal
SymmetricCipher implementation.
Definition: strciphr.h:664
WRITE_KEYSTREAM_ALIGNED
Wirte the keystream to the aligned output buffer, input is NULL.
Definition: strciphr.h:92
AdditiveCipherConcretePolicy::GetIterationsToBuffer
unsigned int GetIterationsToBuffer() const
Provides buffer size based on iterations.
Definition: strciphr.h:223
ByteReverse
byte ByteReverse(byte value)
Reverses bytes in a 8-bit value.
Definition: misc.h:1906
AdditiveCipherTemplate
Base class for additive stream ciphers with SymmetricCipher interface.
Definition: strciphr.h:290
AbstractPolicyHolder
Access a stream cipher policy object.
Definition: strciphr.h:49
XOR_KEYSTREAM_INPUT_ALIGNED
XOR the aligned input buffer and keystream, write to the output buffer.
Definition: strciphr.h:96
KeystreamOperationFlags
KeystreamOperationFlags
Keystream operation flags.
Definition: strciphr.h:76
NameValuePairs
Interface for retrieving values given their names.
Definition: cryptlib.h:293
AlgorithmImpl
Base class information.
Definition: simple.h:36