Crypto++  5.6.3
Free C++ class library of cryptographic schemes
strciphr.h
Go to the documentation of this file.
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()
81  //! \brief Output buffer is aligned
83  //! \brief Input buffer is aligned
85  //! \brief Input buffer is NULL
87 };
88 
89 //! \brief Keystream operation flags
90 //! \sa AdditiveCipherAbstractPolicy::GetBytesPerIteration(), AdditiveCipherAbstractPolicy::GetOptimalBlockSize()
91 //! and AdditiveCipherAbstractPolicy::GetAlignment()
93  //! \brief Wirte the keystream to the output buffer, input is NULL
95  //! \brief Wirte the keystream to the aligned output buffer, input is NULL
97  //! \brief XOR the input buffer and keystream, write to the output buffer
99  //! \brief XOR the aligned input buffer and keystream, write to the output buffer
101  //! \brief XOR the input buffer and keystream, write to the aligned output buffer
103  //! \brief XOR the aligned input buffer and keystream, write to the aligned output buffer
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); 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 &params, 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); 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 &params);
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  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 &params, 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>
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 &registerWord)
443  {
444  assert(IsAligned<WordType>(m_output));
445  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  assert(m_output == NULL);
454  else
455  {
456  WordType ct = *(const WordType *)m_input ^ registerWord;
457  registerWord = ct;
458  *(WordType*)m_output = ct;
459  m_input += sizeof(WordType);
460  m_output += sizeof(WordType);
461  }
462  }
463  else
464  {
465  WordType ct = *(const WordType *)m_input;
466  *(WordType*)m_output = registerWord ^ ct;
467  registerWord = ct;
468  m_input += sizeof(WordType);
469  m_output += sizeof(WordType);
470  }
471 
472  // registerWord is left unreversed so it can be xor-ed with further input
473 
474  return *this;
475  }
476 
477  byte *m_output;
478  const byte *m_input;
479  CipherDir m_dir;
480  };
481 };
482 
483 //! \class CFB_CipherTemplate
484 //! \brief Base class for feedback based stream ciphers with SymmetricCipher interface
485 //! \tparam BASE AbstractPolicyHolder base class
486 template <class BASE>
487 class CRYPTOPP_NO_VTABLE CFB_CipherTemplate : public BASE
488 {
489 public:
490  //! \brief Apply keystream to data
491  //! \param outString a buffer to write the transformed data
492  //! \param inString a buffer to read the data
493  //! \param length the size fo the buffers, in bytes
494  //! \details This is the primary method to operate a stream cipher. For example:
495  //! <pre>
496  //! size_t size = 30;
497  //! byte plain[size] = "Do or do not; there is no try";
498  //! byte cipher[size];
499  //! ...
500  //! ChaCha20 chacha(key, keySize);
501  //! chacha.ProcessData(cipher, plain, size);
502  //! </pre>
503  void ProcessData(byte *outString, const byte *inString, size_t length);
504 
505  //! \brief Resynchronize the cipher
506  //! \param iv a byte array used to resynchronize the cipher
507  //! \param length the size of the IV array
508  void Resynchronize(const byte *iv, int length=-1);
509 
510  //! \brief Provides number of ideal bytes to process
511  //! \returns the ideal number of bytes to process
512  //! \details Internally, the default implementation returns GetBytesPerIteration()
513  //! \sa GetBytesPerIteration() and GetOptimalNextBlockSize()
514  unsigned int OptimalBlockSize() const {return this->GetPolicy().GetBytesPerIteration();}
515 
516  //! \brief Provides number of ideal bytes to process
517  //! \returns the ideal number of bytes to process
518  //! \details Internally, the default implementation returns remaining unprocessed bytes
519  //! \sa GetBytesPerIteration() and OptimalBlockSize()
520  unsigned int GetOptimalNextBlockSize() const {return (unsigned int)m_leftOver;}
521 
522  //! \brief Provides number of ideal data alignment
523  //! \returns the ideal data alignment, in bytes
524  //! \sa GetAlignment() and OptimalBlockSize()
525  unsigned int OptimalDataAlignment() const {return this->GetPolicy().GetAlignment();}
526 
527  //! \brief Flag indicating random access
528  //! \returns true if the cipher is seekable, false otherwise
529  //! \sa Seek()
530  bool IsRandomAccess() const {return false;}
531 
532  //! \brief Determines if the cipher is self inverting
533  //! \returns true if the stream cipher is self inverting, false otherwise
534  bool IsSelfInverting() const {return false;}
535 
536  typedef typename BASE::PolicyInterface PolicyInterface;
537 
538 protected:
539  virtual void CombineMessageAndShiftRegister(byte *output, byte *reg, const byte *message, size_t length) =0;
540 
541  void UncheckedSetKey(const byte *key, unsigned int length, const NameValuePairs &params);
542 
543  size_t m_leftOver;
544 };
545 
546 //! \class CFB_EncryptionTemplate
547 //! \brief Base class for feedback based stream ciphers in the forward direction with SymmetricCipher interface
548 //! \tparam BASE AbstractPolicyHolder base class
549 template <class BASE = AbstractPolicyHolder<CFB_CipherAbstractPolicy, SymmetricCipher> >
550 class CRYPTOPP_NO_VTABLE CFB_EncryptionTemplate : public CFB_CipherTemplate<BASE>
551 {
552  bool IsForwardTransformation() const {return true;}
553  void CombineMessageAndShiftRegister(byte *output, byte *reg, const byte *message, size_t length);
554 };
555 
556 //! \class CFB_DecryptionTemplate
557 //! \brief Base class for feedback based stream ciphers in the reverse direction with SymmetricCipher interface
558 //! \tparam BASE AbstractPolicyHolder base class
559 template <class BASE = AbstractPolicyHolder<CFB_CipherAbstractPolicy, SymmetricCipher> >
560 class CRYPTOPP_NO_VTABLE CFB_DecryptionTemplate : public CFB_CipherTemplate<BASE>
561 {
562  bool IsForwardTransformation() const {return false;}
563  void CombineMessageAndShiftRegister(byte *output, byte *reg, const byte *message, size_t length);
564 };
565 
566 //! \class CFB_RequireFullDataBlocks
567 //! \brief Base class for feedback based stream ciphers with a mandatory block size
568 //! \tparam BASE CFB_EncryptionTemplate or CFB_DecryptionTemplate base class
569 template <class BASE>
570 class CFB_RequireFullDataBlocks : public BASE
571 {
572 public:
573  unsigned int MandatoryBlockSize() const {return this->OptimalBlockSize();}
574 };
575 
576 //! \class SymmetricCipherFinal
577 //! \brief SymmetricCipher implementation
578 //! \tparam BASE AbstractPolicyHolder derived base class
579 //! \tparam INFO AbstractPolicyHolder derived information class
580 //! \sa Weak::ARC4, ChaCha8, ChaCha12, ChaCha20, Salsa20, SEAL, Sosemanuk, WAKE
581 template <class BASE, class INFO = BASE>
582 class SymmetricCipherFinal : public AlgorithmImpl<SimpleKeyingInterfaceImpl<BASE, INFO>, INFO>
583 {
584 public:
585  //! \brief Construct a stream cipher
587 
588  //! \brief Construct a stream cipher
589  //! \param key a byte array used to key the cipher
590  //! \details This overload uses DEFAULT_KEYLENGTH
591  SymmetricCipherFinal(const byte *key)
592  {this->SetKey(key, this->DEFAULT_KEYLENGTH);}
593 
594  //! \brief Construct a stream cipher
595  //! \param key a byte array used to key the cipher
596  //! \param length the size of the key array
597  SymmetricCipherFinal(const byte *key, size_t length)
598  {this->SetKey(key, length);}
599 
600  //! \brief Construct a stream cipher
601  //! \param key a byte array used to key the cipher
602  //! \param length the size of the key array
603  //! \param iv a byte array used as an initialization vector
604  SymmetricCipherFinal(const byte *key, size_t length, const byte *iv)
605  {this->SetKeyWithIV(key, length, iv);}
606 
607  //! \brief Clone a SymmetricCipher
608  //! \returns a new SymmetricCipher based on this object
609  Clonable * Clone() const {return static_cast<SymmetricCipher *>(new SymmetricCipherFinal<BASE, INFO>(*this));}
610 };
611 
612 NAMESPACE_END
613 
614 #ifdef CRYPTOPP_MANUALLY_INSTANTIATE_TEMPLATES
615 #include "strciphr.cpp"
616 #endif
617 
618 NAMESPACE_BEGIN(CryptoPP)
620 CRYPTOPP_DLL_TEMPLATE_CLASS AdditiveCipherTemplate<AbstractPolicyHolder<AdditiveCipherAbstractPolicy, SymmetricCipher> >;
621 CRYPTOPP_DLL_TEMPLATE_CLASS CFB_CipherTemplate<AbstractPolicyHolder<CFB_CipherAbstractPolicy, SymmetricCipher> >;
622 CRYPTOPP_DLL_TEMPLATE_CLASS CFB_EncryptionTemplate<AbstractPolicyHolder<CFB_CipherAbstractPolicy, SymmetricCipher> >;
623 CRYPTOPP_DLL_TEMPLATE_CLASS CFB_DecryptionTemplate<AbstractPolicyHolder<CFB_CipherAbstractPolicy, SymmetricCipher> >;
624 
625 NAMESPACE_END
626 
627 #if CRYPTOPP_MSC_VERSION
628 # pragma warning(pop)
629 #endif
630 
631 #endif
Base class for all exceptions thrown by the library.
Definition: cryptlib.h:139
Standard names for retrieving values by name when working with NameValuePairs.
virtual unsigned int GetOptimalBlockSize() const
Provides number of ideal bytes to process.
Definition: strciphr.h:127
bool NativeByteOrderIs(ByteOrder order)
Determines whether order follows native byte ordering.
Definition: misc.h:929
Output buffer is aligned.
Definition: strciphr.h:82
SymmetricCipherFinal(const byte *key)
Construct a stream cipher.
Definition: strciphr.h:591
Input buffer is aligned.
Definition: strciphr.h:84
virtual void GenerateBlock(byte *output, size_t size)
Generate random array of bytes.
Definition: cryptlib.cpp:329
unsigned int GetBytesPerIteration() const
Provides number of bytes operated upon during an iteration.
Definition: strciphr.h:419
unsigned int GetAlignment() const
Provides data alignment requirements.
Definition: strciphr.h:198
Base class for feedback based stream ciphers.
Definition: strciphr.h:406
Base class for additive stream ciphers.
Definition: strciphr.h:188
virtual void OperateKeystream(KeystreamOperation operation, byte *output, const byte *input, size_t iterationCount)
Operates the keystream.
Definition: strciphr.h:153
XOR the input buffer and keystream, write to the aligned output buffer.
Definition: strciphr.h:102
XOR the input buffer and keystream, write to the output buffer.
Definition: strciphr.h:98
CipherDir
Specifies a direction for a cipher to operate.
Definition: cryptlib.h:103
Abstract base classes that provide a uniform interface to this library.
Base class for feedback based stream ciphers with SymmetricCipher interface.
Definition: strciphr.h:487
Some other error occurred not belonging to other categories.
Definition: cryptlib.h:158
Library configuration file.
Interface for random number generators.
Definition: cryptlib.h:1186
Wirte the keystream to the output buffer, input is NULL.
Definition: strciphr.h:94
SecBlock typedef.
Definition: secblock.h:728
Stream cipher policy object.
Definition: strciphr.h:66
Interface for cloning objects.
Definition: cryptlib.h:480
unsigned int OptimalBlockSize() const
Provides number of ideal bytes to process.
Definition: strciphr.h:303
virtual void WriteKeystream(byte *keystream, size_t iterationCount)
Generate the keystream.
Definition: strciphr.h:137
Policy object for additive stream ciphers.
Definition: strciphr.h:108
the cipher is performing encryption
Definition: cryptlib.h:105
Classes and functions for secure memory allocations.
virtual unsigned int GetAlignment() const
Provides data alignment requirements.
Definition: strciphr.h:116
void TransformRegister()
Perform one iteration in the forward direction.
Definition: strciphr.h:426
bool IsAlignedOn(const void *ptr, unsigned int alignment)
Determines whether ptr is aligned to a minimum value.
Definition: misc.h:888
Input buffer is NULL.
Definition: strciphr.h:86
Base class for feedback based stream ciphers in the reverse direction with SymmetricCipher interface...
Definition: strciphr.h:560
unsigned int OptimalDataAlignment() const
Provides number of ideal data alignment.
Definition: strciphr.h:525
A method was called which was not implemented.
Definition: cryptlib.h:203
RegisterOutput & operator()(WordType &registerWord)
XOR feedback register with data.
Definition: strciphr.h:442
Classes and functions for implementing secret key algorithms.
bool IsSelfInverting() const
Determines if the cipher is self inverting.
Definition: strciphr.h:318
virtual void SeekToIteration(lword iterationCount)
Seeks to a random position in the stream.
Definition: strciphr.h:177
Interface for one direction (encryption or decryption) of a stream cipher or cipher mode...
Definition: cryptlib.h:1099
Base class for feedback based stream ciphers with a mandatory block size.
Definition: strciphr.h:570
Policy object for feeback based stream ciphers.
Definition: strciphr.h:350
bool CanIterate() const
Flag indicating iteration support.
Definition: strciphr.h:423
unsigned int GetAlignment() const
Provides data alignment requirements.
Definition: strciphr.h:414
Base class for feedback based stream ciphers in the forward direction with SymmetricCipher interface...
Definition: strciphr.h:550
Clonable * Clone() const
Clone a SymmetricCipher.
Definition: strciphr.h:609
SymmetricCipherFinal()
Construct a stream cipher.
Definition: strciphr.h:586
virtual bool CanIterate() const
Flag indicating iteration support.
Definition: strciphr.h:375
unsigned int OptimalBlockSize() const
Provides number of ideal bytes to process.
Definition: strciphr.h:514
bool IsRandomAccess() const
Flag indicating random access.
Definition: strciphr.h:327
XOR the aligned input buffer and keystream, write to the aligned output buffer.
Definition: strciphr.h:104
unsigned int OptimalDataAlignment() const
Provides number of ideal data alignment.
Definition: strciphr.h:314
SymmetricCipherFinal(const byte *key, size_t length, const byte *iv)
Construct a stream cipher.
Definition: strciphr.h:604
unsigned int GetOptimalNextBlockSize() const
Provides number of ideal bytes to process.
Definition: strciphr.h:309
unsigned int GetBytesPerIteration() const
Provides number of bytes operated upon during an iteration.
Definition: strciphr.h:204
bool IsForwardTransformation() const
Determines if the cipher is a forward transformation.
Definition: strciphr.h:322
virtual void CipherResynchronize(byte *keystreamBuffer, const byte *iv, size_t length)
Resynchronize the cipher.
Definition: strciphr.h:166
virtual void Iterate(byte *output, const byte *input, CipherDir dir, size_t iterationCount)
Iterate the cipher.
Definition: strciphr.h:383
An Empty class.
Definition: misc.h:175
virtual bool CanOperateKeystream() const
Flag indicating.
Definition: strciphr.h:143
KeystreamOperation
Keystream operation flags.
Definition: strciphr.h:92
bool IsSelfInverting() const
Determines if the cipher is self inverting.
Definition: strciphr.h:534
SymmetricCipherFinal(const byte *key, size_t length)
Construct a stream cipher.
Definition: strciphr.h:597
unsigned int GetIterationsToBuffer() const
Provides buffer size based on iterations.
Definition: strciphr.h:208
virtual void CipherResynchronize(const byte *iv, size_t length)
Resynchronize the cipher.
Definition: strciphr.h:396
Crypto++ library namespace.
bool IsRandomAccess() const
Flag indicating random access.
Definition: strciphr.h:530
SymmetricCipher implementation.
Definition: strciphr.h:582
Wirte the keystream to the aligned output buffer, input is NULL.
Definition: strciphr.h:96
bool CanOperateKeystream() const
Flag indicating.
Definition: strciphr.h:213
unsigned int GetOptimalNextBlockSize() const
Provides number of ideal bytes to process.
Definition: strciphr.h:520
byte ByteReverse(byte value)
Reverses bytes in a 8-bit value.
Definition: misc.h:1668
Base class for additive stream ciphers with SymmetricCipher interface.
Definition: strciphr.h:269
Access a stream cipher policy object.
Definition: strciphr.h:50
XOR the aligned input buffer and keystream, write to the output buffer.
Definition: strciphr.h:100
KeystreamOperationFlags
Keystream operation flags.
Definition: strciphr.h:80
Interface for retrieving values given their names.
Definition: cryptlib.h:277
Base class for identifying alogorithm.
Definition: simple.h:38