source: trunk/src-cryptopp/strciphr.h

Last change on this file was e230cb0, checked in by David Stainton <dstainton415@…>, at 2016-10-12T13:27:29Z

Add cryptopp from tag CRYPTOPP_5_6_5

  • Property mode set to 100644
File size: 27.3 KB
Line 
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
43NAMESPACE_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
49template <class POLICY_INTERFACE, class BASE = Empty>
50class CRYPTOPP_NO_VTABLE AbstractPolicyHolder : public BASE
51{
52public:
53        typedef POLICY_INTERFACE PolicyInterface;
54        virtual ~AbstractPolicyHolder() {}
55
56protected:
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
65template <class POLICY, class BASE, class POLICY_INTERFACE = CPP_TYPENAME BASE::PolicyInterface>
66class ConcretePolicyHolder : public BASE, protected POLICY
67{
68public:
69#ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562
70        virtual ~ConcretePolicyHolder() {}
71#endif
72protected:
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()
80enum KeystreamOperationFlags {
81        //! \brief Output buffer is aligned
82        OUTPUT_ALIGNED=1,
83        //! \brief Input buffer is aligned
84        INPUT_ALIGNED=2,
85        //! \brief Input buffer is NULL
86        INPUT_NULL = 4
87};
88
89//! \brief Keystream operation flags
90//! \sa AdditiveCipherAbstractPolicy::GetBytesPerIteration(), AdditiveCipherAbstractPolicy::GetOptimalBlockSize()
91//!   and AdditiveCipherAbstractPolicy::GetAlignment()
92enum KeystreamOperation {
93        //! \brief Wirte the keystream to the output buffer, input is NULL
94        WRITE_KEYSTREAM                         = INPUT_NULL,
95        //! \brief Wirte the keystream to the aligned output buffer, input is NULL
96        WRITE_KEYSTREAM_ALIGNED         = INPUT_NULL | OUTPUT_ALIGNED,
97        //! \brief XOR the input buffer and keystream, write to the output buffer
98        XOR_KEYSTREAM                           = 0,
99        //! \brief XOR the aligned input buffer and keystream, write to the output buffer
100        XOR_KEYSTREAM_INPUT_ALIGNED = INPUT_ALIGNED,
101        //! \brief XOR the input buffer and keystream, write to the aligned output buffer
102        XOR_KEYSTREAM_OUTPUT_ALIGNED= OUTPUT_ALIGNED,
103        //! \brief XOR the aligned input buffer and keystream, write to the aligned output buffer
104        XOR_KEYSTREAM_BOTH_ALIGNED      = OUTPUT_ALIGNED | INPUT_ALIGNED};
105
106//! \class AdditiveCipherAbstractPolicy
107//! \brief Policy object for additive stream ciphers
108struct 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); CRYPTOPP_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); CRYPTOPP_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
187template <typename WT, unsigned int W, unsigned int X = 1, class BASE = AdditiveCipherAbstractPolicy>
188struct 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
268template <class BASE = AbstractPolicyHolder<AdditiveCipherAbstractPolicy, SymmetricCipher> >
269class CRYPTOPP_NO_VTABLE AdditiveCipherTemplate : public BASE, public RandomNumberGenerator
270{
271public:
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
336protected:
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
350class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE CFB_CipherAbstractPolicy
351{
352public:
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                 CRYPTOPP_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
405template <typename WT, unsigned int W, class BASE = CFB_CipherAbstractPolicy>
406struct 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>
434        struct RegisterOutput
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                        CRYPTOPP_ASSERT(IsAligned<WordType>(m_output));
445                        CRYPTOPP_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                                {
454                                        CRYPTOPP_ASSERT(m_output == NULL);
455                                }
456                                else
457                                {
458                                        WordType ct = *(const WordType *)m_input ^ registerWord;
459                                        registerWord = ct;
460                                        *(WordType*)m_output = ct;
461                                        m_input += sizeof(WordType);
462                                        m_output += sizeof(WordType);
463                                }
464                        }
465                        else
466                        {
467                                WordType ct = *(const WordType *)m_input;
468                                *(WordType*)m_output = registerWord ^ ct;
469                                registerWord = ct;
470                                m_input += sizeof(WordType);
471                                m_output += sizeof(WordType);
472                        }
473
474                        // registerWord is left unreversed so it can be xor-ed with further input
475
476                        return *this;
477                }
478
479                byte *m_output;
480                const byte *m_input;
481                CipherDir m_dir;
482        };
483};
484
485//! \class CFB_CipherTemplate
486//! \brief Base class for feedback based stream ciphers with SymmetricCipher interface
487//! \tparam BASE AbstractPolicyHolder base class
488template <class BASE>
489class CRYPTOPP_NO_VTABLE CFB_CipherTemplate : public BASE
490{
491public:
492        //! \brief Apply keystream to data
493        //! \param outString a buffer to write the transformed data
494        //! \param inString a buffer to read the data
495        //! \param length the size fo the buffers, in bytes
496        //! \details This is the primary method to operate a stream cipher. For example:
497        //! <pre>
498        //!     size_t size = 30;
499        //!     byte plain[size] = "Do or do not; there is no try";
500        //!     byte cipher[size];
501        //!     ...
502        //!     ChaCha20 chacha(key, keySize);
503        //!     chacha.ProcessData(cipher, plain, size);
504        //! </pre>
505        void ProcessData(byte *outString, const byte *inString, size_t length);
506
507        //! \brief Resynchronize the cipher
508        //! \param iv a byte array used to resynchronize the cipher
509        //! \param length the size of the IV array
510        void Resynchronize(const byte *iv, int length=-1);
511
512        //! \brief Provides number of ideal bytes to process
513        //! \returns the ideal number of bytes to process
514        //! \details Internally, the default implementation returns GetBytesPerIteration()
515        //! \sa GetBytesPerIteration() and GetOptimalNextBlockSize()
516        unsigned int OptimalBlockSize() const {return this->GetPolicy().GetBytesPerIteration();}
517
518        //! \brief Provides number of ideal bytes to process
519        //! \returns the ideal number of bytes to process
520        //! \details Internally, the default implementation returns remaining unprocessed bytes
521        //! \sa GetBytesPerIteration() and OptimalBlockSize()
522        unsigned int GetOptimalNextBlockSize() const {return (unsigned int)m_leftOver;}
523
524        //! \brief Provides number of ideal data alignment
525        //! \returns the ideal data alignment, in bytes
526        //! \sa GetAlignment() and OptimalBlockSize()
527        unsigned int OptimalDataAlignment() const {return this->GetPolicy().GetAlignment();}
528
529        //! \brief Flag indicating random access
530        //! \returns true if the cipher is seekable, false otherwise
531        //! \sa Seek()
532        bool IsRandomAccess() const {return false;}
533
534        //! \brief Determines if the cipher is self inverting
535        //! \returns true if the stream cipher is self inverting, false otherwise
536        bool IsSelfInverting() const {return false;}
537
538        typedef typename BASE::PolicyInterface PolicyInterface;
539
540protected:
541        virtual void CombineMessageAndShiftRegister(byte *output, byte *reg, const byte *message, size_t length) =0;
542
543        void UncheckedSetKey(const byte *key, unsigned int length, const NameValuePairs &params);
544
545        size_t m_leftOver;
546};
547
548//! \class CFB_EncryptionTemplate
549//! \brief Base class for feedback based stream ciphers in the forward direction with SymmetricCipher interface
550//! \tparam BASE AbstractPolicyHolder base class
551template <class BASE = AbstractPolicyHolder<CFB_CipherAbstractPolicy, SymmetricCipher> >
552class CRYPTOPP_NO_VTABLE CFB_EncryptionTemplate : public CFB_CipherTemplate<BASE>
553{
554        bool IsForwardTransformation() const {return true;}
555        void CombineMessageAndShiftRegister(byte *output, byte *reg, const byte *message, size_t length);
556};
557
558//! \class CFB_DecryptionTemplate
559//! \brief Base class for feedback based stream ciphers in the reverse direction with SymmetricCipher interface
560//! \tparam BASE AbstractPolicyHolder base class
561template <class BASE = AbstractPolicyHolder<CFB_CipherAbstractPolicy, SymmetricCipher> >
562class CRYPTOPP_NO_VTABLE CFB_DecryptionTemplate : public CFB_CipherTemplate<BASE>
563{
564        bool IsForwardTransformation() const {return false;}
565        void CombineMessageAndShiftRegister(byte *output, byte *reg, const byte *message, size_t length);
566};
567
568//! \class CFB_RequireFullDataBlocks
569//! \brief Base class for feedback based stream ciphers with a mandatory block size
570//! \tparam BASE CFB_EncryptionTemplate or CFB_DecryptionTemplate base class
571template <class BASE>
572class CFB_RequireFullDataBlocks : public BASE
573{
574public:
575        unsigned int MandatoryBlockSize() const {return this->OptimalBlockSize();}
576};
577
578//! \class SymmetricCipherFinal
579//! \brief SymmetricCipher implementation
580//! \tparam BASE AbstractPolicyHolder derived base class
581//! \tparam INFO AbstractPolicyHolder derived information class
582//! \sa Weak::ARC4, ChaCha8, ChaCha12, ChaCha20, Salsa20, SEAL, Sosemanuk, WAKE
583template <class BASE, class INFO = BASE>
584class SymmetricCipherFinal : public AlgorithmImpl<SimpleKeyingInterfaceImpl<BASE, INFO>, INFO>
585{
586public:
587        //! \brief Construct a stream cipher
588        SymmetricCipherFinal() {}
589
590        //! \brief Construct a stream cipher
591        //! \param key a byte array used to key the cipher
592        //! \details This overload uses DEFAULT_KEYLENGTH
593        SymmetricCipherFinal(const byte *key)
594                {this->SetKey(key, this->DEFAULT_KEYLENGTH);}
595
596        //! \brief Construct a stream cipher
597        //! \param key a byte array used to key the cipher
598        //! \param length the size of the key array
599        SymmetricCipherFinal(const byte *key, size_t length)
600                {this->SetKey(key, length);}
601
602        //! \brief Construct a stream cipher
603        //! \param key a byte array used to key the cipher
604        //! \param length the size of the key array
605        //! \param iv a byte array used as an initialization vector
606        SymmetricCipherFinal(const byte *key, size_t length, const byte *iv)
607                {this->SetKeyWithIV(key, length, iv);}
608
609        //! \brief Clone a SymmetricCipher
610        //! \returns a new SymmetricCipher based on this object
611        Clonable * Clone() const {return static_cast<SymmetricCipher *>(new SymmetricCipherFinal<BASE, INFO>(*this));}
612};
613
614NAMESPACE_END
615
616#ifdef CRYPTOPP_MANUALLY_INSTANTIATE_TEMPLATES
617#include "strciphr.cpp"
618#endif
619
620NAMESPACE_BEGIN(CryptoPP)
621CRYPTOPP_DLL_TEMPLATE_CLASS AbstractPolicyHolder<AdditiveCipherAbstractPolicy, SymmetricCipher>;
622CRYPTOPP_DLL_TEMPLATE_CLASS AdditiveCipherTemplate<AbstractPolicyHolder<AdditiveCipherAbstractPolicy, SymmetricCipher> >;
623CRYPTOPP_DLL_TEMPLATE_CLASS CFB_CipherTemplate<AbstractPolicyHolder<CFB_CipherAbstractPolicy, SymmetricCipher> >;
624CRYPTOPP_DLL_TEMPLATE_CLASS CFB_EncryptionTemplate<AbstractPolicyHolder<CFB_CipherAbstractPolicy, SymmetricCipher> >;
625CRYPTOPP_DLL_TEMPLATE_CLASS CFB_DecryptionTemplate<AbstractPolicyHolder<CFB_CipherAbstractPolicy, SymmetricCipher> >;
626
627NAMESPACE_END
628
629#if CRYPTOPP_MSC_VERSION
630# pragma warning(pop)
631#endif
632
633#endif
Note: See TracBrowser for help on using the repository browser.