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