Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:55:09

0001 // strciphr.h - originally written and placed in the public domain by Wei Dai

0002 
0003 /// \file strciphr.h

0004 /// \brief Classes for implementing stream ciphers

0005 /// \details This file contains helper classes for implementing stream ciphers.

0006 ///  All this infrastructure may look very complex compared to what's in Crypto++ 4.x,

0007 ///  but stream ciphers implementations now support a lot of new functionality,

0008 ///  including better performance (minimizing copying), resetting of keys and IVs, and

0009 ///  methods to query which features are supported by a cipher.

0010 /// \details Here's an explanation of these classes. The word "policy" is used here to

0011 ///  mean a class with a set of methods that must be implemented by individual stream

0012 ///  cipher implementations. This is usually much simpler than the full stream cipher

0013 ///  API, which is implemented by either AdditiveCipherTemplate or CFB_CipherTemplate

0014 ///  using the policy. So for example, an implementation of SEAL only needs to implement

0015 ///  the AdditiveCipherAbstractPolicy interface (since it's an additive cipher, i.e., it

0016 ///  xors a keystream into the plaintext). See this line in seal.h:

0017 /// <pre>

0018 ///     typedef SymmetricCipherFinal\<ConcretePolicyHolder\<SEAL_Policy\<B\>, AdditiveCipherTemplate\<\> \> \> Encryption;

0019 /// </pre>

0020 /// \details AdditiveCipherTemplate and CFB_CipherTemplate are designed so that they don't

0021 ///  need to take a policy class as a template parameter (although this is allowed), so

0022 ///  that their code is not duplicated for each new cipher. Instead they each get a

0023 ///  reference to an abstract policy interface by calling AccessPolicy() on itself, so

0024 ///  AccessPolicy() must be overridden to return the actual policy reference. This is done

0025 ///  by the ConcretePolicyHolder class. Finally, SymmetricCipherFinal implements the

0026 ///  constructors and other functions that must be implemented by the most derived class.

0027 
0028 #ifndef CRYPTOPP_STRCIPHR_H
0029 #define CRYPTOPP_STRCIPHR_H
0030 
0031 #include "config.h"
0032 
0033 #if CRYPTOPP_MSC_VERSION
0034 # pragma warning(push)
0035 # pragma warning(disable: 4127 4189 4231 4275)
0036 #endif
0037 
0038 #include "cryptlib.h"
0039 #include "seckey.h"
0040 #include "secblock.h"
0041 #include "argnames.h"
0042 
0043 NAMESPACE_BEGIN(CryptoPP)
0044 
0045 /// \brief Access a stream cipher policy object

0046 /// \tparam POLICY_INTERFACE class implementing AbstractPolicyHolder

0047 /// \tparam BASE class or type to use as a base class

0048 template <class POLICY_INTERFACE, class BASE = Empty>
0049 class CRYPTOPP_NO_VTABLE AbstractPolicyHolder : public BASE
0050 {
0051 public:
0052     typedef POLICY_INTERFACE PolicyInterface;
0053     virtual ~AbstractPolicyHolder() {}
0054 
0055 protected:
0056     virtual const POLICY_INTERFACE & GetPolicy() const =0;
0057     virtual POLICY_INTERFACE & AccessPolicy() =0;
0058 };
0059 
0060 /// \brief Stream cipher policy object

0061 /// \tparam POLICY class implementing AbstractPolicyHolder

0062 /// \tparam BASE class or type to use as a base class

0063 template <class POLICY, class BASE, class POLICY_INTERFACE = typename BASE::PolicyInterface>
0064 class ConcretePolicyHolder : public BASE, protected POLICY
0065 {
0066 public:
0067     virtual ~ConcretePolicyHolder() {}
0068 protected:
0069     const POLICY_INTERFACE & GetPolicy() const {return *this;}
0070     POLICY_INTERFACE & AccessPolicy() {return *this;}
0071 };
0072 
0073 /// \brief Keystream operation flags

0074 /// \sa AdditiveCipherAbstractPolicy::GetBytesPerIteration(), AdditiveCipherAbstractPolicy::GetOptimalBlockSize()

0075 ///  and AdditiveCipherAbstractPolicy::GetAlignment()

0076 enum KeystreamOperationFlags {
0077     /// \brief Output buffer is aligned

0078     OUTPUT_ALIGNED=1,
0079     /// \brief Input buffer is aligned

0080     INPUT_ALIGNED=2,
0081     /// \brief Input buffer is NULL

0082     INPUT_NULL = 4
0083 };
0084 
0085 /// \brief Keystream operation flags

0086 /// \sa AdditiveCipherAbstractPolicy::GetBytesPerIteration(), AdditiveCipherAbstractPolicy::GetOptimalBlockSize()

0087 ///  and AdditiveCipherAbstractPolicy::GetAlignment()

0088 enum KeystreamOperation {
0089     /// \brief Write the keystream to the output buffer, input is NULL

0090     WRITE_KEYSTREAM             = INPUT_NULL,
0091     /// \brief Write the keystream to the aligned output buffer, input is NULL

0092     WRITE_KEYSTREAM_ALIGNED     = INPUT_NULL | OUTPUT_ALIGNED,
0093     /// \brief XOR the input buffer and keystream, write to the output buffer

0094     XOR_KEYSTREAM               = 0,
0095     /// \brief XOR the aligned input buffer and keystream, write to the output buffer

0096     XOR_KEYSTREAM_INPUT_ALIGNED = INPUT_ALIGNED,
0097     /// \brief XOR the input buffer and keystream, write to the aligned output buffer

0098     XOR_KEYSTREAM_OUTPUT_ALIGNED= OUTPUT_ALIGNED,
0099     /// \brief XOR the aligned input buffer and keystream, write to the aligned output buffer

0100     XOR_KEYSTREAM_BOTH_ALIGNED  = OUTPUT_ALIGNED | INPUT_ALIGNED
0101 };
0102 
0103 /// \brief Policy object for additive stream ciphers

0104 struct CRYPTOPP_DLL CRYPTOPP_NO_VTABLE AdditiveCipherAbstractPolicy
0105 {
0106     virtual ~AdditiveCipherAbstractPolicy() {}
0107 
0108     /// \brief Provides data alignment requirements

0109     /// \return data alignment requirements, in bytes

0110     /// \details Internally, the default implementation returns 1. If the stream cipher is implemented

0111     ///  using an SSE2 ASM or intrinsics, then the value returned is usually 16.

0112     virtual unsigned int GetAlignment() const {return 1;}
0113 
0114     /// \brief Provides number of bytes operated upon during an iteration

0115     /// \return bytes operated upon during an iteration, in bytes

0116     /// \sa GetOptimalBlockSize()

0117     virtual unsigned int GetBytesPerIteration() const =0;
0118 
0119     /// \brief Provides number of ideal bytes to process

0120     /// \return the ideal number of bytes to process

0121     /// \details Internally, the default implementation returns GetBytesPerIteration()

0122     /// \sa GetBytesPerIteration()

0123     virtual unsigned int GetOptimalBlockSize() const {return GetBytesPerIteration();}
0124 
0125     /// \brief Provides buffer size based on iterations

0126     /// \return the buffer size based on iterations, in bytes

0127     virtual unsigned int GetIterationsToBuffer() const =0;
0128 
0129     /// \brief Generate the keystream

0130     /// \param keystream the key stream

0131     /// \param iterationCount the number of iterations to generate the key stream

0132     /// \sa CanOperateKeystream(), OperateKeystream(), WriteKeystream()

0133     virtual void WriteKeystream(byte *keystream, size_t iterationCount)
0134         {OperateKeystream(KeystreamOperation(INPUT_NULL | static_cast<KeystreamOperationFlags>(IsAlignedOn(keystream, GetAlignment()))), keystream, NULLPTR, iterationCount);}
0135 
0136     /// \brief Flag indicating

0137     /// \return true if the stream can be generated independent of the transformation input, false otherwise

0138     /// \sa CanOperateKeystream(), OperateKeystream(), WriteKeystream()

0139     virtual bool CanOperateKeystream() const {return false;}
0140 
0141     /// \brief Operates the keystream

0142     /// \param operation the operation with additional flags

0143     /// \param output the output buffer

0144     /// \param input the input buffer

0145     /// \param iterationCount the number of iterations to perform on the input

0146     /// \details OperateKeystream() will attempt to operate upon GetOptimalBlockSize() buffer,

0147     ///  which will be derived from GetBytesPerIteration().

0148     /// \sa CanOperateKeystream(), OperateKeystream(), WriteKeystream(), KeystreamOperation()

0149     virtual void OperateKeystream(KeystreamOperation operation, byte *output, const byte *input, size_t iterationCount)
0150         {CRYPTOPP_UNUSED(operation); CRYPTOPP_UNUSED(output); CRYPTOPP_UNUSED(input);
0151         CRYPTOPP_UNUSED(iterationCount); CRYPTOPP_ASSERT(false);}
0152 
0153     /// \brief Key the cipher

0154     /// \param params set of NameValuePairs use to initialize this object

0155     /// \param key a byte array used to key the cipher

0156     /// \param length the size of the key array

0157     virtual void CipherSetKey(const NameValuePairs &params, const byte *key, size_t length) =0;
0158 
0159     /// \brief Resynchronize the cipher

0160     /// \param keystreamBuffer the keystream buffer

0161     /// \param iv a byte array used to resynchronize the cipher

0162     /// \param length the size of the IV array

0163     virtual void CipherResynchronize(byte *keystreamBuffer, const byte *iv, size_t length)
0164         {CRYPTOPP_UNUSED(keystreamBuffer); CRYPTOPP_UNUSED(iv); CRYPTOPP_UNUSED(length);
0165         throw NotImplemented("SimpleKeyingInterface: this object doesn't support resynchronization");}
0166 
0167     /// \brief Flag indicating random access

0168     /// \return true if the cipher is seekable, false otherwise

0169     /// \sa SeekToIteration()

0170     virtual bool CipherIsRandomAccess() const =0;
0171 
0172     /// \brief Seeks to a random position in the stream

0173     /// \sa CipherIsRandomAccess()

0174     virtual void SeekToIteration(lword iterationCount)
0175         {CRYPTOPP_UNUSED(iterationCount); CRYPTOPP_ASSERT(!CipherIsRandomAccess());
0176         throw NotImplemented("StreamTransformation: this object doesn't support random access");}
0177 
0178     /// \brief Retrieve the provider of this algorithm

0179     /// \return the algorithm provider

0180     /// \details The algorithm provider can be a name like "C++", "SSE", "NEON", "AESNI",

0181     ///  "ARMv8" and "Power8". C++ is standard C++ code. Other labels, like SSE,

0182     ///  usually indicate a specialized implementation using instructions from a higher

0183     ///  instruction set architecture (ISA). Future labels may include external hardware

0184     ///  like a hardware security module (HSM).

0185     /// \details Generally speaking Wei Dai's original IA-32 ASM code falls under "SSE2".

0186     ///  Labels like "SSSE3" and "SSE4.1" follow after Wei's code and use intrinsics

0187     ///  instead of ASM.

0188     /// \details Algorithms which combine different instructions or ISAs provide the

0189     ///  dominant one. For example on x86 <tt>AES/GCM</tt> returns "AESNI" rather than

0190     ///  "CLMUL" or "AES+SSE4.1" or "AES+CLMUL" or "AES+SSE4.1+CLMUL".

0191     /// \note Provider is not universally implemented yet.

0192     virtual std::string AlgorithmProvider() const { return "C++"; }
0193 };
0194 
0195 /// \brief Base class for additive stream ciphers

0196 /// \tparam WT word type

0197 /// \tparam W count of words

0198 /// \tparam X bytes per iteration count

0199 /// \tparam BASE AdditiveCipherAbstractPolicy derived base class

0200 template <typename WT, unsigned int W, unsigned int X = 1, class BASE = AdditiveCipherAbstractPolicy>
0201 struct CRYPTOPP_NO_VTABLE AdditiveCipherConcretePolicy : public BASE
0202 {
0203     /// \brief Word type for the cipher

0204     typedef WT WordType;
0205 
0206     /// \brief Number of bytes for an iteration

0207     /// \details BYTES_PER_ITERATION is the product <tt>sizeof(WordType) * W</tt>.

0208     ///  For example, ChaCha uses 16 each <tt>word32</tt>, and the value of

0209     ///  BYTES_PER_ITERATION is 64. Each invocation of the ChaCha block function

0210     ///  produces 64 bytes of keystream.

0211     CRYPTOPP_CONSTANT(BYTES_PER_ITERATION = sizeof(WordType) * W);
0212 
0213     virtual ~AdditiveCipherConcretePolicy() {}
0214 
0215     /// \brief Provides data alignment requirements

0216     /// \return data alignment requirements, in bytes

0217     /// \details Internally, the default implementation returns 1. If the stream

0218     ///  cipher is implemented using an SSE2 ASM or intrinsics, then the value

0219     ///  returned is usually 16.

0220     unsigned int GetAlignment() const {return GetAlignmentOf<WordType>();}
0221 
0222     /// \brief Provides number of bytes operated upon during an iteration

0223     /// \return bytes operated upon during an iteration, in bytes

0224     /// \sa GetOptimalBlockSize()

0225     unsigned int GetBytesPerIteration() const {return BYTES_PER_ITERATION;}
0226 
0227     /// \brief Provides buffer size based on iterations

0228     /// \return the buffer size based on iterations, in bytes

0229     unsigned int GetIterationsToBuffer() const {return X;}
0230 
0231     /// \brief Flag indicating

0232     /// \return true if the stream can be generated independent of the

0233     ///  transformation input, false otherwise

0234     /// \sa CanOperateKeystream(), OperateKeystream(), WriteKeystream()

0235     bool CanOperateKeystream() const {return true;}
0236 
0237     /// \brief Operates the keystream

0238     /// \param operation the operation with additional flags

0239     /// \param output the output buffer

0240     /// \param input the input buffer

0241     /// \param iterationCount the number of iterations to perform on the input

0242     /// \details OperateKeystream() will attempt to operate upon GetOptimalBlockSize() buffer,

0243     ///  which will be derived from GetBytesPerIteration().

0244     /// \sa CanOperateKeystream(), OperateKeystream(), WriteKeystream(), KeystreamOperation()

0245     virtual void OperateKeystream(KeystreamOperation operation, byte *output, const byte *input, size_t iterationCount) =0;
0246 };
0247 
0248 /// \brief Helper macro to implement OperateKeystream

0249 /// \param x KeystreamOperation mask

0250 /// \param b Endian order

0251 /// \param i index in output buffer

0252 /// \param a value to output

0253 #define CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, b, i, a)  \
0254     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)));
0255 
0256 /// \brief Helper macro to implement OperateKeystream

0257 /// \param x KeystreamOperation mask

0258 /// \param i index in output buffer

0259 /// \param a value to output

0260 #define CRYPTOPP_KEYSTREAM_OUTPUT_XMM(x, i, a)  {\
0261     __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));\
0262     if (x & OUTPUT_ALIGNED) _mm_store_si128((__m128i *)output+i, t);\
0263     else _mm_storeu_si128((__m128i *)output+i, t);}
0264 
0265 /// \brief Helper macro to implement OperateKeystream

0266 #define CRYPTOPP_KEYSTREAM_OUTPUT_SWITCH(x, y)      \
0267     switch (operation)                              \
0268     {                                               \
0269         case WRITE_KEYSTREAM:                       \
0270             x(EnumToInt(WRITE_KEYSTREAM))   \
0271             break;                                  \
0272         case XOR_KEYSTREAM:                         \
0273             x(EnumToInt(XOR_KEYSTREAM))     \
0274             input += y;                             \
0275             break;                                  \
0276         case XOR_KEYSTREAM_INPUT_ALIGNED:           \
0277             x(EnumToInt(XOR_KEYSTREAM_INPUT_ALIGNED))       \
0278             input += y;                             \
0279             break;                                  \
0280         case XOR_KEYSTREAM_OUTPUT_ALIGNED:          \
0281             x(EnumToInt(XOR_KEYSTREAM_OUTPUT_ALIGNED))      \
0282             input += y;                             \
0283             break;                                  \
0284         case WRITE_KEYSTREAM_ALIGNED:               \
0285             x(EnumToInt(WRITE_KEYSTREAM_ALIGNED))           \
0286             break;                                  \
0287         case XOR_KEYSTREAM_BOTH_ALIGNED:            \
0288             x(EnumToInt(XOR_KEYSTREAM_BOTH_ALIGNED))        \
0289             input += y;                             \
0290             break;                                  \
0291     }                                               \
0292     output += y;
0293 
0294 /// \brief Base class for additive stream ciphers with SymmetricCipher interface

0295 /// \tparam BASE AbstractPolicyHolder base class

0296 template <class BASE = AbstractPolicyHolder<AdditiveCipherAbstractPolicy, SymmetricCipher> >
0297 class CRYPTOPP_NO_VTABLE AdditiveCipherTemplate : public BASE, public RandomNumberGenerator
0298 {
0299 public:
0300     virtual ~AdditiveCipherTemplate() {}
0301     AdditiveCipherTemplate() : m_leftOver(0) {}
0302 
0303     /// \brief Generate random array of bytes

0304     /// \param output the byte buffer

0305     /// \param size the length of the buffer, in bytes

0306     /// \details All generated values are uniformly distributed over the range specified

0307     ///  within the constraints of a particular generator.

0308     void GenerateBlock(byte *output, size_t size);
0309 
0310     /// \brief Apply keystream to data

0311     /// \param outString a buffer to write the transformed data

0312     /// \param inString a buffer to read the data

0313     /// \param length the size of the buffers, in bytes

0314     /// \details This is the primary method to operate a stream cipher. For example:

0315     /// <pre>

0316     ///     size_t size = 30;

0317     ///     byte plain[size] = "Do or do not; there is no try";

0318     ///     byte cipher[size];

0319     ///     ...

0320     ///     ChaCha20 chacha(key, keySize);

0321     ///     chacha.ProcessData(cipher, plain, size);

0322     /// </pre>

0323     /// \details You should use distinct buffers for inString and outString. If the buffers

0324     ///  are the same, then the data will be copied to an internal buffer to avoid GCC alias

0325     ///  violations. The internal copy will impact performance.

0326     /// \sa <A HREF="https://github.com/weidai11/cryptopp/issues/1088">Issue 1088, 36% loss

0327     ///  of performance with AES</A>, <A HREF="https://github.com/weidai11/cryptopp/issues/1010">Issue

0328     ///  1010, HIGHT cipher troubles with FileSource</A>

0329     void ProcessData(byte *outString, const byte *inString, size_t length);
0330 
0331     /// \brief Resynchronize the cipher

0332     /// \param iv a byte array used to resynchronize the cipher

0333     /// \param length the size of the IV array

0334     void Resynchronize(const byte *iv, int length=-1);
0335 
0336     /// \brief Provides number of ideal bytes to process

0337     /// \return the ideal number of bytes to process

0338     /// \details Internally, the default implementation returns GetBytesPerIteration()

0339     /// \sa GetBytesPerIteration() and GetOptimalNextBlockSize()

0340     unsigned int OptimalBlockSize() const {return this->GetPolicy().GetOptimalBlockSize();}
0341 
0342     /// \brief Provides number of ideal bytes to process

0343     /// \return the ideal number of bytes to process

0344     /// \details Internally, the default implementation returns remaining unprocessed bytes

0345     /// \sa GetBytesPerIteration() and OptimalBlockSize()

0346     unsigned int GetOptimalNextBlockSize() const {return (unsigned int)this->m_leftOver;}
0347 
0348     /// \brief Provides number of ideal data alignment

0349     /// \return the ideal data alignment, in bytes

0350     /// \sa GetAlignment() and OptimalBlockSize()

0351     unsigned int OptimalDataAlignment() const {return this->GetPolicy().GetAlignment();}
0352 
0353     /// \brief Determines if the cipher is self inverting

0354     /// \return true if the stream cipher is self inverting, false otherwise

0355     bool IsSelfInverting() const {return true;}
0356 
0357     /// \brief Determines if the cipher is a forward transformation

0358     /// \return true if the stream cipher is a forward transformation, false otherwise

0359     bool IsForwardTransformation() const {return true;}
0360 
0361     /// \brief Flag indicating random access

0362     /// \return true if the cipher is seekable, false otherwise

0363     /// \sa Seek()

0364     bool IsRandomAccess() const {return this->GetPolicy().CipherIsRandomAccess();}
0365 
0366     /// \brief Seeks to a random position in the stream

0367     /// \param position the absolute position in the stream

0368     /// \sa IsRandomAccess()

0369     void Seek(lword position);
0370 
0371     /// \brief Retrieve the provider of this algorithm

0372     /// \return the algorithm provider

0373     /// \details The algorithm provider can be a name like "C++", "SSE", "NEON", "AESNI",

0374     ///  "ARMv8" and "Power8". C++ is standard C++ code. Other labels, like SSE,

0375     ///  usually indicate a specialized implementation using instructions from a higher

0376     ///  instruction set architecture (ISA). Future labels may include external hardware

0377     ///  like a hardware security module (HSM).

0378     /// \details Generally speaking Wei Dai's original IA-32 ASM code falls under "SSE2".

0379     ///  Labels like "SSSE3" and "SSE4.1" follow after Wei's code and use intrinsics

0380     ///  instead of ASM.

0381     /// \details Algorithms which combine different instructions or ISAs provide the

0382     ///  dominant one. For example on x86 <tt>AES/GCM</tt> returns "AESNI" rather than

0383     ///  "CLMUL" or "AES+SSE4.1" or "AES+CLMUL" or "AES+SSE4.1+CLMUL".

0384     /// \note Provider is not universally implemented yet.

0385     std::string AlgorithmProvider() const { return this->GetPolicy().AlgorithmProvider(); }
0386 
0387     typedef typename BASE::PolicyInterface PolicyInterface;
0388 
0389 protected:
0390     void UncheckedSetKey(const byte *key, unsigned int length, const NameValuePairs &params);
0391 
0392     unsigned int GetBufferByteSize(const PolicyInterface &policy) const {return policy.GetBytesPerIteration() * policy.GetIterationsToBuffer();}
0393 
0394     inline byte * KeystreamBufferBegin() {return this->m_buffer.data();}
0395     inline byte * KeystreamBufferEnd() {return (PtrAdd(this->m_buffer.data(), this->m_buffer.size()));}
0396 
0397     AlignedSecByteBlock m_buffer;
0398     size_t m_leftOver;
0399 };
0400 
0401 /// \brief Policy object for feedback based stream ciphers

0402 class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE CFB_CipherAbstractPolicy
0403 {
0404 public:
0405     virtual ~CFB_CipherAbstractPolicy() {}
0406 
0407     /// \brief Provides data alignment requirements

0408     /// \return data alignment requirements, in bytes

0409     /// \details Internally, the default implementation returns 1. If the stream cipher is implemented

0410     ///  using an SSE2 ASM or intrinsics, then the value returned is usually 16.

0411     virtual unsigned int GetAlignment() const =0;
0412 
0413     /// \brief Provides number of bytes operated upon during an iteration

0414     /// \return bytes operated upon during an iteration, in bytes

0415     /// \sa GetOptimalBlockSize()

0416     virtual unsigned int GetBytesPerIteration() const =0;
0417 
0418     /// \brief Access the feedback register

0419     /// \return pointer to the first byte of the feedback register

0420     virtual byte * GetRegisterBegin() =0;
0421 
0422     /// \brief TODO

0423     virtual void TransformRegister() =0;
0424 
0425     /// \brief Flag indicating iteration support

0426     /// \return true if the cipher supports iteration, false otherwise

0427     virtual bool CanIterate() const {return false;}
0428 
0429     /// \brief Iterate the cipher

0430     /// \param output the output buffer

0431     /// \param input the input buffer

0432     /// \param dir the direction of the cipher

0433     /// \param iterationCount the number of iterations to perform on the input

0434     /// \sa IsSelfInverting() and IsForwardTransformation()

0435     virtual void Iterate(byte *output, const byte *input, CipherDir dir, size_t iterationCount)
0436         {CRYPTOPP_UNUSED(output); CRYPTOPP_UNUSED(input); CRYPTOPP_UNUSED(dir);
0437         CRYPTOPP_UNUSED(iterationCount); CRYPTOPP_ASSERT(false);
0438         throw Exception(Exception::OTHER_ERROR, "SimpleKeyingInterface: unexpected error");}
0439 
0440     /// \brief Key the cipher

0441     /// \param params set of NameValuePairs use to initialize this object

0442     /// \param key a byte array used to key the cipher

0443     /// \param length the size of the key array

0444     virtual void CipherSetKey(const NameValuePairs &params, const byte *key, size_t length) =0;
0445 
0446     /// \brief Resynchronize the cipher

0447     /// \param iv a byte array used to resynchronize the cipher

0448     /// \param length the size of the IV array

0449     virtual void CipherResynchronize(const byte *iv, size_t length)
0450         {CRYPTOPP_UNUSED(iv); CRYPTOPP_UNUSED(length);
0451         throw NotImplemented("SimpleKeyingInterface: this object doesn't support resynchronization");}
0452 
0453     /// \brief Retrieve the provider of this algorithm

0454     /// \return the algorithm provider

0455     /// \details The algorithm provider can be a name like "C++", "SSE", "NEON", "AESNI",

0456     ///  "ARMv8" and "Power8". C++ is standard C++ code. Other labels, like SSE,

0457     ///  usually indicate a specialized implementation using instructions from a higher

0458     ///  instruction set architecture (ISA). Future labels may include external hardware

0459     ///  like a hardware security module (HSM).

0460     /// \details Generally speaking Wei Dai's original IA-32 ASM code falls under "SSE2".

0461     ///  Labels like "SSSE3" and "SSE4.1" follow after Wei's code and use intrinsics

0462     ///  instead of ASM.

0463     /// \details Algorithms which combine different instructions or ISAs provide the

0464     ///  dominant one. For example on x86 <tt>AES/GCM</tt> returns "AESNI" rather than

0465     ///  "CLMUL" or "AES+SSE4.1" or "AES+CLMUL" or "AES+SSE4.1+CLMUL".

0466     /// \note Provider is not universally implemented yet.

0467     virtual std::string AlgorithmProvider() const { return "C++"; }
0468 };
0469 
0470 /// \brief Base class for feedback based stream ciphers

0471 /// \tparam WT word type

0472 /// \tparam W count of words

0473 /// \tparam BASE CFB_CipherAbstractPolicy derived base class

0474 template <typename WT, unsigned int W, class BASE = CFB_CipherAbstractPolicy>
0475 struct CRYPTOPP_NO_VTABLE CFB_CipherConcretePolicy : public BASE
0476 {
0477     typedef WT WordType;
0478 
0479     virtual ~CFB_CipherConcretePolicy() {}
0480 
0481     /// \brief Provides data alignment requirements

0482     /// \return data alignment requirements, in bytes

0483     /// \details Internally, the default implementation returns 1. If the stream cipher is implemented

0484     ///   using an SSE2 ASM or intrinsics, then the value returned is usually 16.

0485     unsigned int GetAlignment() const {return sizeof(WordType);}
0486 
0487     /// \brief Provides number of bytes operated upon during an iteration

0488     /// \return bytes operated upon during an iteration, in bytes

0489     /// \sa GetOptimalBlockSize()

0490     unsigned int GetBytesPerIteration() const {return sizeof(WordType) * W;}
0491 
0492     /// \brief Flag indicating iteration support

0493     /// \return true if the cipher supports iteration, false otherwise

0494     bool CanIterate() const {return true;}
0495 
0496     /// \brief Perform one iteration in the forward direction

0497     void TransformRegister() {this->Iterate(NULLPTR, NULLPTR, ENCRYPTION, 1);}
0498 
0499     /// \brief Provides alternate access to a feedback register

0500     /// \tparam B enumeration indicating endianness

0501     /// \details RegisterOutput() provides alternate access to the feedback register. The

0502     ///   enumeration B is BigEndian or LittleEndian. Repeatedly applying operator()

0503     ///   results in advancing in the register.

0504     template <class B>
0505     struct RegisterOutput
0506     {
0507         RegisterOutput(byte *output, const byte *input, CipherDir dir)
0508             : m_output(output), m_input(input), m_dir(dir) {}
0509 
0510         /// \brief XOR feedback register with data

0511         /// \param registerWord data represented as a word type

0512         /// \return reference to the next feedback register word

0513         inline RegisterOutput& operator()(WordType &registerWord)
0514         {
0515             //CRYPTOPP_ASSERT(IsAligned<WordType>(m_output));

0516             //CRYPTOPP_ASSERT(IsAligned<WordType>(m_input));

0517 
0518             if (!NativeByteOrderIs(B::ToEnum()))
0519                 registerWord = ByteReverse(registerWord);
0520 
0521             if (m_dir == ENCRYPTION)
0522             {
0523                 if (m_input == NULLPTR)
0524                 {
0525                     CRYPTOPP_ASSERT(m_output == NULLPTR);
0526                 }
0527                 else
0528                 {
0529                     // WordType ct = *(const WordType *)m_input ^ registerWord;

0530                     WordType ct = GetWord<WordType>(false, NativeByteOrder::ToEnum(), m_input) ^ registerWord;
0531                     registerWord = ct;
0532 
0533                     // *(WordType*)m_output = ct;

0534                     PutWord<WordType>(false, NativeByteOrder::ToEnum(), m_output, ct);
0535 
0536                     m_input += sizeof(WordType);
0537                     m_output += sizeof(WordType);
0538                 }
0539             }
0540             else
0541             {
0542                 // WordType ct = *(const WordType *)m_input;

0543                 WordType ct = GetWord<WordType>(false, NativeByteOrder::ToEnum(), m_input);
0544 
0545                 // *(WordType*)m_output = registerWord ^ ct;

0546                 PutWord<WordType>(false, NativeByteOrder::ToEnum(), m_output, registerWord ^ ct);
0547                 registerWord = ct;
0548 
0549                 m_input += sizeof(WordType);
0550                 m_output += sizeof(WordType);
0551             }
0552 
0553             // registerWord is left unreversed so it can be xor-ed with further input

0554 
0555             return *this;
0556         }
0557 
0558         byte *m_output;
0559         const byte *m_input;
0560         CipherDir m_dir;
0561     };
0562 };
0563 
0564 /// \brief Base class for feedback based stream ciphers with SymmetricCipher interface

0565 /// \tparam BASE AbstractPolicyHolder base class

0566 template <class BASE>
0567 class CRYPTOPP_NO_VTABLE CFB_CipherTemplate : public BASE
0568 {
0569 public:
0570     virtual ~CFB_CipherTemplate() {}
0571     CFB_CipherTemplate() : m_leftOver(0) {}
0572 
0573     /// \brief Apply keystream to data

0574     /// \param outString a buffer to write the transformed data

0575     /// \param inString a buffer to read the data

0576     /// \param length the size of the buffers, in bytes

0577     /// \details This is the primary method to operate a stream cipher. For example:

0578     /// <pre>

0579     ///     size_t size = 30;

0580     ///     byte plain[size] = "Do or do not; there is no try";

0581     ///     byte cipher[size];

0582     ///     ...

0583     ///     ChaCha20 chacha(key, keySize);

0584     ///     chacha.ProcessData(cipher, plain, size);

0585     /// </pre>

0586     /// \details You should use distinct buffers for inString and outString. If the buffers

0587     ///  are the same, then the data will be copied to an internal buffer to avoid GCC alias

0588     ///  violations. The internal copy will impact performance.

0589     /// \sa <A HREF="https://github.com/weidai11/cryptopp/issues/1088">Issue 1088, 36% loss

0590     ///  of performance with AES</A>, <A HREF="https://github.com/weidai11/cryptopp/issues/1010">Issue

0591     ///  1010, HIGHT cipher troubles with FileSource</A>

0592     void ProcessData(byte *outString, const byte *inString, size_t length);
0593 
0594     /// \brief Resynchronize the cipher

0595     /// \param iv a byte array used to resynchronize the cipher

0596     /// \param length the size of the IV array

0597     void Resynchronize(const byte *iv, int length=-1);
0598 
0599     /// \brief Provides number of ideal bytes to process

0600     /// \return the ideal number of bytes to process

0601     /// \details Internally, the default implementation returns GetBytesPerIteration()

0602     /// \sa GetBytesPerIteration() and GetOptimalNextBlockSize()

0603     unsigned int OptimalBlockSize() const {return this->GetPolicy().GetBytesPerIteration();}
0604 
0605     /// \brief Provides number of ideal bytes to process

0606     /// \return the ideal number of bytes to process

0607     /// \details Internally, the default implementation returns remaining unprocessed bytes

0608     /// \sa GetBytesPerIteration() and OptimalBlockSize()

0609     unsigned int GetOptimalNextBlockSize() const {return (unsigned int)m_leftOver;}
0610 
0611     /// \brief Provides number of ideal data alignment

0612     /// \return the ideal data alignment, in bytes

0613     /// \sa GetAlignment() and OptimalBlockSize()

0614     unsigned int OptimalDataAlignment() const {return this->GetPolicy().GetAlignment();}
0615 
0616     /// \brief Flag indicating random access

0617     /// \return true if the cipher is seekable, false otherwise

0618     /// \sa Seek()

0619     bool IsRandomAccess() const {return false;}
0620 
0621     /// \brief Determines if the cipher is self inverting

0622     /// \return true if the stream cipher is self inverting, false otherwise

0623     bool IsSelfInverting() const {return false;}
0624 
0625     /// \brief Retrieve the provider of this algorithm

0626     /// \return the algorithm provider

0627     /// \details The algorithm provider can be a name like "C++", "SSE", "NEON", "AESNI",

0628     ///  "ARMv8" and "Power8". C++ is standard C++ code. Other labels, like SSE,

0629     ///  usually indicate a specialized implementation using instructions from a higher

0630     ///  instruction set architecture (ISA). Future labels may include external hardware

0631     ///  like a hardware security module (HSM).

0632     /// \details Generally speaking Wei Dai's original IA-32 ASM code falls under "SSE2".

0633     ///  Labels like "SSSE3" and "SSE4.1" follow after Wei's code and use intrinsics

0634     ///  instead of ASM.

0635     /// \details Algorithms which combine different instructions or ISAs provide the

0636     ///  dominant one. For example on x86 <tt>AES/GCM</tt> returns "AESNI" rather than

0637     ///  "CLMUL" or "AES+SSE4.1" or "AES+CLMUL" or "AES+SSE4.1+CLMUL".

0638     /// \note Provider is not universally implemented yet.

0639     std::string AlgorithmProvider() const { return this->GetPolicy().AlgorithmProvider(); }
0640 
0641     typedef typename BASE::PolicyInterface PolicyInterface;
0642 
0643 protected:
0644     virtual void CombineMessageAndShiftRegister(byte *output, byte *reg, const byte *message, size_t length) =0;
0645 
0646     void UncheckedSetKey(const byte *key, unsigned int length, const NameValuePairs &params);
0647 
0648     size_t m_leftOver;
0649 };
0650 
0651 /// \brief Base class for feedback based stream ciphers in the forward direction with SymmetricCipher interface

0652 /// \tparam BASE AbstractPolicyHolder base class

0653 template <class BASE = AbstractPolicyHolder<CFB_CipherAbstractPolicy, SymmetricCipher> >
0654 class CRYPTOPP_NO_VTABLE CFB_EncryptionTemplate : public CFB_CipherTemplate<BASE>
0655 {
0656     bool IsForwardTransformation() const {return true;}
0657     void CombineMessageAndShiftRegister(byte *output, byte *reg, const byte *message, size_t length);
0658 };
0659 
0660 /// \brief Base class for feedback based stream ciphers in the reverse direction with SymmetricCipher interface

0661 /// \tparam BASE AbstractPolicyHolder base class

0662 template <class BASE = AbstractPolicyHolder<CFB_CipherAbstractPolicy, SymmetricCipher> >
0663 class CRYPTOPP_NO_VTABLE CFB_DecryptionTemplate : public CFB_CipherTemplate<BASE>
0664 {
0665     bool IsForwardTransformation() const {return false;}
0666     void CombineMessageAndShiftRegister(byte *output, byte *reg, const byte *message, size_t length);
0667 };
0668 
0669 /// \brief Base class for feedback based stream ciphers with a mandatory block size

0670 /// \tparam BASE CFB_EncryptionTemplate or CFB_DecryptionTemplate base class

0671 template <class BASE>
0672 class CFB_RequireFullDataBlocks : public BASE
0673 {
0674 public:
0675     unsigned int MandatoryBlockSize() const {return this->OptimalBlockSize();}
0676 };
0677 
0678 /// \brief SymmetricCipher implementation

0679 /// \tparam BASE AbstractPolicyHolder derived base class

0680 /// \tparam INFO AbstractPolicyHolder derived information class

0681 /// \sa Weak::ARC4, ChaCha8, ChaCha12, ChaCha20, Salsa20, SEAL, Sosemanuk, WAKE

0682 template <class BASE, class INFO = BASE>
0683 class SymmetricCipherFinal : public AlgorithmImpl<SimpleKeyingInterfaceImpl<BASE, INFO>, INFO>
0684 {
0685 public:
0686     virtual ~SymmetricCipherFinal() {}
0687 
0688     /// \brief Construct a stream cipher

0689     SymmetricCipherFinal() {}
0690 
0691     /// \brief Construct a stream cipher

0692     /// \param key a byte array used to key the cipher

0693     /// \details This overload uses DEFAULT_KEYLENGTH

0694     SymmetricCipherFinal(const byte *key)
0695         {this->SetKey(key, this->DEFAULT_KEYLENGTH);}
0696 
0697     /// \brief Construct a stream cipher

0698     /// \param key a byte array used to key the cipher

0699     /// \param length the size of the key array

0700     SymmetricCipherFinal(const byte *key, size_t length)
0701         {this->SetKey(key, length);}
0702 
0703     /// \brief Construct a stream cipher

0704     /// \param key a byte array used to key the cipher

0705     /// \param length the size of the key array

0706     /// \param iv a byte array used as an initialization vector

0707     SymmetricCipherFinal(const byte *key, size_t length, const byte *iv)
0708         {this->SetKeyWithIV(key, length, iv);}
0709 
0710     /// \brief Clone a SymmetricCipher

0711     /// \return a new SymmetricCipher based on this object

0712     Clonable * Clone() const {return static_cast<SymmetricCipher *>(new SymmetricCipherFinal<BASE, INFO>(*this));}
0713 };
0714 
0715 NAMESPACE_END
0716 
0717 // Used by dll.cpp to ensure objects are in dll.o, and not strciphr.o.

0718 #ifdef CRYPTOPP_MANUALLY_INSTANTIATE_TEMPLATES
0719 # include "strciphr.cpp"
0720 #endif
0721 
0722 NAMESPACE_BEGIN(CryptoPP)
0723 
0724 CRYPTOPP_DLL_TEMPLATE_CLASS AbstractPolicyHolder<AdditiveCipherAbstractPolicy, SymmetricCipher>;
0725 CRYPTOPP_DLL_TEMPLATE_CLASS AdditiveCipherTemplate<AbstractPolicyHolder<AdditiveCipherAbstractPolicy, SymmetricCipher> >;
0726 
0727 CRYPTOPP_DLL_TEMPLATE_CLASS CFB_CipherTemplate<AbstractPolicyHolder<CFB_CipherAbstractPolicy, SymmetricCipher> >;
0728 CRYPTOPP_DLL_TEMPLATE_CLASS CFB_EncryptionTemplate<AbstractPolicyHolder<CFB_CipherAbstractPolicy, SymmetricCipher> >;
0729 CRYPTOPP_DLL_TEMPLATE_CLASS CFB_DecryptionTemplate<AbstractPolicyHolder<CFB_CipherAbstractPolicy, SymmetricCipher> >;
0730 
0731 NAMESPACE_END
0732 
0733 #if CRYPTOPP_MSC_VERSION
0734 # pragma warning(pop)
0735 #endif
0736 
0737 #endif