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