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