Coverage Report

Created: 2024-11-21 07:03

/src/cryptopp/strciphr.h
Line
Count
Source (jump to first uncovered line)
1
// strciphr.h - originally written and placed in the public domain by Wei Dai
2
3
/// \file strciphr.h
4
/// \brief Classes for implementing stream ciphers
5
/// \details This file contains helper classes for implementing stream ciphers.
6
///  All this infrastructure may look very complex compared to what's in Crypto++ 4.x,
7
///  but stream ciphers implementations now support a lot of new functionality,
8
///  including better performance (minimizing copying), resetting of keys and IVs, and
9
///  methods to query which features are supported by a cipher.
10
/// \details Here's an explanation of these classes. The word "policy" is used here to
11
///  mean a class with a set of methods that must be implemented by individual stream
12
///  cipher implementations. This is usually much simpler than the full stream cipher
13
///  API, which is implemented by either AdditiveCipherTemplate or CFB_CipherTemplate
14
///  using the policy. So for example, an implementation of SEAL only needs to implement
15
///  the AdditiveCipherAbstractPolicy interface (since it's an additive cipher, i.e., it
16
///  xors a keystream into the plaintext). See this line in seal.h:
17
/// <pre>
18
///     typedef SymmetricCipherFinal\<ConcretePolicyHolder\<SEAL_Policy\<B\>, AdditiveCipherTemplate\<\> \> \> Encryption;
19
/// </pre>
20
/// \details AdditiveCipherTemplate and CFB_CipherTemplate are designed so that they don't
21
///  need to take a policy class as a template parameter (although this is allowed), so
22
///  that their code is not duplicated for each new cipher. Instead they each get a
23
///  reference to an abstract policy interface by calling AccessPolicy() on itself, so
24
///  AccessPolicy() must be overridden to return the actual policy reference. This is done
25
///  by the ConcretePolicyHolder class. Finally, SymmetricCipherFinal implements the
26
///  constructors and other functions that must be implemented by the most derived class.
27
28
#ifndef CRYPTOPP_STRCIPHR_H
29
#define CRYPTOPP_STRCIPHR_H
30
31
#include "config.h"
32
33
#if CRYPTOPP_MSC_VERSION
34
# pragma warning(push)
35
# pragma warning(disable: 4127 4189 4231 4275)
36
#endif
37
38
#include "cryptlib.h"
39
#include "seckey.h"
40
#include "secblock.h"
41
#include "argnames.h"
42
43
NAMESPACE_BEGIN(CryptoPP)
44
45
/// \brief Access a stream cipher policy object
46
/// \tparam POLICY_INTERFACE class implementing AbstractPolicyHolder
47
/// \tparam BASE class or type to use as a base class
48
template <class POLICY_INTERFACE, class BASE = Empty>
49
class CRYPTOPP_NO_VTABLE AbstractPolicyHolder : public BASE
50
{
51
public:
52
  typedef POLICY_INTERFACE PolicyInterface;
53
40
  virtual ~AbstractPolicyHolder() {}
54
55
protected:
56
  virtual const POLICY_INTERFACE & GetPolicy() const =0;
57
  virtual POLICY_INTERFACE & AccessPolicy() =0;
58
};
59
60
/// \brief Stream cipher policy object
61
/// \tparam POLICY class implementing AbstractPolicyHolder
62
/// \tparam BASE class or type to use as a base class
63
template <class POLICY, class BASE, class POLICY_INTERFACE = typename BASE::PolicyInterface>
64
class ConcretePolicyHolder : public BASE, protected POLICY
65
{
66
public:
67
40
  virtual ~ConcretePolicyHolder() {}
CryptoPP::ConcretePolicyHolder<CryptoPP::ChaChaTLS_Policy, CryptoPP::AdditiveCipherTemplate<CryptoPP::AbstractPolicyHolder<CryptoPP::AdditiveCipherAbstractPolicy, CryptoPP::SymmetricCipher> >, CryptoPP::AdditiveCipherAbstractPolicy>::~ConcretePolicyHolder()
Line
Count
Source
67
27
  virtual ~ConcretePolicyHolder() {}
CryptoPP::ConcretePolicyHolder<CryptoPP::XChaCha20_Policy, CryptoPP::AdditiveCipherTemplate<CryptoPP::AbstractPolicyHolder<CryptoPP::AdditiveCipherAbstractPolicy, CryptoPP::SymmetricCipher> >, CryptoPP::AdditiveCipherAbstractPolicy>::~ConcretePolicyHolder()
Line
Count
Source
67
13
  virtual ~ConcretePolicyHolder() {}
68
protected:
69
198
  const POLICY_INTERFACE & GetPolicy() const {return *this;}
Unexecuted instantiation: CryptoPP::ConcretePolicyHolder<CryptoPP::Empty, CryptoPP::AdditiveCipherTemplate<CryptoPP::AbstractPolicyHolder<CryptoPP::AdditiveCipherAbstractPolicy, CryptoPP::CTR_ModePolicy> >, CryptoPP::AdditiveCipherAbstractPolicy>::GetPolicy() const
Unexecuted instantiation: CryptoPP::ConcretePolicyHolder<CryptoPP::ChaChaTLS_Policy, CryptoPP::AdditiveCipherTemplate<CryptoPP::AbstractPolicyHolder<CryptoPP::AdditiveCipherAbstractPolicy, CryptoPP::SymmetricCipher> >, CryptoPP::AdditiveCipherAbstractPolicy>::GetPolicy() const
Unexecuted instantiation: CryptoPP::ConcretePolicyHolder<CryptoPP::XChaCha20_Policy, CryptoPP::AdditiveCipherTemplate<CryptoPP::AbstractPolicyHolder<CryptoPP::AdditiveCipherAbstractPolicy, CryptoPP::SymmetricCipher> >, CryptoPP::AdditiveCipherAbstractPolicy>::GetPolicy() const
CryptoPP::ConcretePolicyHolder<CryptoPP::Empty, CryptoPP::CFB_EncryptionTemplate<CryptoPP::AbstractPolicyHolder<CryptoPP::CFB_CipherAbstractPolicy, CryptoPP::CFB_ModePolicy> >, CryptoPP::CFB_CipherAbstractPolicy>::GetPolicy() const
Line
Count
Source
69
98
  const POLICY_INTERFACE & GetPolicy() const {return *this;}
CryptoPP::ConcretePolicyHolder<CryptoPP::Empty, CryptoPP::AdditiveCipherTemplate<CryptoPP::AbstractPolicyHolder<CryptoPP::AdditiveCipherAbstractPolicy, CryptoPP::OFB_ModePolicy> >, CryptoPP::AdditiveCipherAbstractPolicy>::GetPolicy() const
Line
Count
Source
69
41
  const POLICY_INTERFACE & GetPolicy() const {return *this;}
CryptoPP::ConcretePolicyHolder<CryptoPP::Empty, CryptoPP::CFB_DecryptionTemplate<CryptoPP::AbstractPolicyHolder<CryptoPP::CFB_CipherAbstractPolicy, CryptoPP::CFB_ModePolicy> >, CryptoPP::CFB_CipherAbstractPolicy>::GetPolicy() const
Line
Count
Source
69
59
  const POLICY_INTERFACE & GetPolicy() const {return *this;}
70
1.53k
  POLICY_INTERFACE & AccessPolicy() {return *this;}
CryptoPP::ConcretePolicyHolder<CryptoPP::Empty, CryptoPP::AdditiveCipherTemplate<CryptoPP::AbstractPolicyHolder<CryptoPP::AdditiveCipherAbstractPolicy, CryptoPP::CTR_ModePolicy> >, CryptoPP::AdditiveCipherAbstractPolicy>::AccessPolicy()
Line
Count
Source
70
392
  POLICY_INTERFACE & AccessPolicy() {return *this;}
CryptoPP::ConcretePolicyHolder<CryptoPP::ChaChaTLS_Policy, CryptoPP::AdditiveCipherTemplate<CryptoPP::AbstractPolicyHolder<CryptoPP::AdditiveCipherAbstractPolicy, CryptoPP::SymmetricCipher> >, CryptoPP::AdditiveCipherAbstractPolicy>::AccessPolicy()
Line
Count
Source
70
126
  POLICY_INTERFACE & AccessPolicy() {return *this;}
Unexecuted instantiation: CryptoPP::ConcretePolicyHolder<CryptoPP::XChaCha20_Policy, CryptoPP::AdditiveCipherTemplate<CryptoPP::AbstractPolicyHolder<CryptoPP::AdditiveCipherAbstractPolicy, CryptoPP::SymmetricCipher> >, CryptoPP::AdditiveCipherAbstractPolicy>::AccessPolicy()
CryptoPP::ConcretePolicyHolder<CryptoPP::Empty, CryptoPP::CFB_EncryptionTemplate<CryptoPP::AbstractPolicyHolder<CryptoPP::CFB_CipherAbstractPolicy, CryptoPP::CFB_ModePolicy> >, CryptoPP::CFB_CipherAbstractPolicy>::AccessPolicy()
Line
Count
Source
70
652
  POLICY_INTERFACE & AccessPolicy() {return *this;}
CryptoPP::ConcretePolicyHolder<CryptoPP::Empty, CryptoPP::AdditiveCipherTemplate<CryptoPP::AbstractPolicyHolder<CryptoPP::AdditiveCipherAbstractPolicy, CryptoPP::OFB_ModePolicy> >, CryptoPP::AdditiveCipherAbstractPolicy>::AccessPolicy()
Line
Count
Source
70
188
  POLICY_INTERFACE & AccessPolicy() {return *this;}
CryptoPP::ConcretePolicyHolder<CryptoPP::Empty, CryptoPP::CFB_DecryptionTemplate<CryptoPP::AbstractPolicyHolder<CryptoPP::CFB_CipherAbstractPolicy, CryptoPP::CFB_ModePolicy> >, CryptoPP::CFB_CipherAbstractPolicy>::AccessPolicy()
Line
Count
Source
70
175
  POLICY_INTERFACE & AccessPolicy() {return *this;}
71
};
72
73
/// \brief Keystream operation flags
74
/// \sa AdditiveCipherAbstractPolicy::GetBytesPerIteration(), AdditiveCipherAbstractPolicy::GetOptimalBlockSize()
75
///  and AdditiveCipherAbstractPolicy::GetAlignment()
76
enum KeystreamOperationFlags {
77
  /// \brief Output buffer is aligned
78
  OUTPUT_ALIGNED=1,
79
  /// \brief Input buffer is aligned
80
  INPUT_ALIGNED=2,
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()
88
enum KeystreamOperation {
89
  /// \brief Write the keystream to the output buffer, input is NULL
90
  WRITE_KEYSTREAM       = INPUT_NULL,
91
  /// \brief Write the keystream to the aligned output buffer, input is NULL
92
  WRITE_KEYSTREAM_ALIGNED   = INPUT_NULL | OUTPUT_ALIGNED,
93
  /// \brief XOR the input buffer and keystream, write to the output buffer
94
  XOR_KEYSTREAM       = 0,
95
  /// \brief XOR the aligned input buffer and keystream, write to the output buffer
96
  XOR_KEYSTREAM_INPUT_ALIGNED = INPUT_ALIGNED,
97
  /// \brief XOR the input buffer and keystream, write to the aligned output buffer
98
  XOR_KEYSTREAM_OUTPUT_ALIGNED= OUTPUT_ALIGNED,
99
  /// \brief XOR the aligned input buffer and keystream, write to the aligned output buffer
100
  XOR_KEYSTREAM_BOTH_ALIGNED  = OUTPUT_ALIGNED | INPUT_ALIGNED
101
};
102
103
/// \brief Policy object for additive stream ciphers
104
struct CRYPTOPP_DLL CRYPTOPP_NO_VTABLE AdditiveCipherAbstractPolicy
105
{
106
724
  virtual ~AdditiveCipherAbstractPolicy() {}
107
108
  /// \brief Provides data alignment requirements
109
  /// \return data alignment requirements, in bytes
110
  /// \details Internally, the default implementation returns 1. If the stream cipher is implemented
111
  ///  using an SSE2 ASM or intrinsics, then the value returned is usually 16.
112
0
  virtual unsigned int GetAlignment() const {return 1;}
113
114
  /// \brief Provides number of bytes operated upon during an iteration
115
  /// \return bytes operated upon during an iteration, in bytes
116
  /// \sa GetOptimalBlockSize()
117
  virtual unsigned int GetBytesPerIteration() const =0;
118
119
  /// \brief Provides number of ideal bytes to process
120
  /// \return the ideal number of bytes to process
121
  /// \details Internally, the default implementation returns GetBytesPerIteration()
122
  /// \sa GetBytesPerIteration()
123
41
  virtual unsigned int GetOptimalBlockSize() const {return GetBytesPerIteration();}
124
125
  /// \brief Provides buffer size based on iterations
126
  /// \return the buffer size based on iterations, in bytes
127
  virtual unsigned int GetIterationsToBuffer() const =0;
128
129
  /// \brief Generate the keystream
130
  /// \param keystream the key stream
131
  /// \param iterationCount the number of iterations to generate the key stream
132
  /// \sa CanOperateKeystream(), OperateKeystream(), WriteKeystream()
133
  virtual void WriteKeystream(byte *keystream, size_t iterationCount)
134
49
    {OperateKeystream(KeystreamOperation(INPUT_NULL | static_cast<KeystreamOperationFlags>(IsAlignedOn(keystream, GetAlignment()))), keystream, NULLPTR, iterationCount);}
135
136
  /// \brief Flag indicating
137
  /// \return true if the stream can be generated independent of the transformation input, false otherwise
138
  /// \sa CanOperateKeystream(), OperateKeystream(), WriteKeystream()
139
115
  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
0
    {CRYPTOPP_UNUSED(operation); CRYPTOPP_UNUSED(output); CRYPTOPP_UNUSED(input);
151
0
    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
0
    {CRYPTOPP_UNUSED(keystreamBuffer); CRYPTOPP_UNUSED(iv); CRYPTOPP_UNUSED(length);
165
0
    throw NotImplemented("SimpleKeyingInterface: this object doesn't support resynchronization");}
166
167
  /// \brief Flag indicating random access
168
  /// \return true if the cipher is seekable, false otherwise
169
  /// \sa SeekToIteration()
170
  virtual bool CipherIsRandomAccess() const =0;
171
172
  /// \brief Seeks to a random position in the stream
173
  /// \sa CipherIsRandomAccess()
174
  virtual void SeekToIteration(lword iterationCount)
175
0
    {CRYPTOPP_UNUSED(iterationCount); CRYPTOPP_ASSERT(!CipherIsRandomAccess());
176
0
    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
0
  virtual std::string AlgorithmProvider() const { return "C++"; }
193
};
194
195
/// \brief Base class for additive stream ciphers
196
/// \tparam WT word type
197
/// \tparam W count of words
198
/// \tparam X bytes per iteration count
199
/// \tparam BASE AdditiveCipherAbstractPolicy derived base class
200
template <typename WT, unsigned int W, unsigned int X = 1, class BASE = AdditiveCipherAbstractPolicy>
201
struct CRYPTOPP_NO_VTABLE AdditiveCipherConcretePolicy : public BASE
202
{
203
  /// \brief Word type for the cipher
204
  typedef WT WordType;
205
206
  /// \brief Number of bytes for an iteration
207
  /// \details BYTES_PER_ITERATION is the product <tt>sizeof(WordType) * W</tt>.
208
  ///  For example, ChaCha uses 16 each <tt>word32</tt>, and the value of
209
  ///  BYTES_PER_ITERATION is 64. Each invocation of the ChaCha block function
210
  ///  produces 64 bytes of keystream.
211
  CRYPTOPP_CONSTANT(BYTES_PER_ITERATION = sizeof(WordType) * W);
212
213
  virtual ~AdditiveCipherConcretePolicy() {}
214
215
  /// \brief Provides data alignment requirements
216
  /// \return data alignment requirements, in bytes
217
  /// \details Internally, the default implementation returns 1. If the stream
218
  ///  cipher is implemented using an SSE2 ASM or intrinsics, then the value
219
  ///  returned is usually 16.
220
0
  unsigned int GetAlignment() const {return GetAlignmentOf<WordType>();}
221
222
  /// \brief Provides number of bytes operated upon during an iteration
223
  /// \return bytes operated upon during an iteration, in bytes
224
  /// \sa GetOptimalBlockSize()
225
126
  unsigned int GetBytesPerIteration() const {return BYTES_PER_ITERATION;}
226
227
  /// \brief Provides buffer size based on iterations
228
  /// \return the buffer size based on iterations, in bytes
229
72
  unsigned int GetIterationsToBuffer() const {return X;}
230
231
  /// \brief Flag indicating
232
  /// \return true if the stream can be generated independent of the
233
  ///  transformation input, false otherwise
234
  /// \sa CanOperateKeystream(), OperateKeystream(), WriteKeystream()
235
121
  bool CanOperateKeystream() const {return true;}
236
237
  /// \brief Operates the keystream
238
  /// \param operation the operation with additional flags
239
  /// \param output the output buffer
240
  /// \param input the input buffer
241
  /// \param iterationCount the number of iterations to perform on the input
242
  /// \details OperateKeystream() will attempt to operate upon GetOptimalBlockSize() buffer,
243
  ///  which will be derived from GetBytesPerIteration().
244
  /// \sa CanOperateKeystream(), OperateKeystream(), WriteKeystream(), KeystreamOperation()
245
  virtual void OperateKeystream(KeystreamOperation operation, byte *output, const byte *input, size_t iterationCount) =0;
246
};
247
248
/// \brief Helper macro to implement OperateKeystream
249
/// \param x KeystreamOperation mask
250
/// \param b Endian order
251
/// \param i index in output buffer
252
/// \param a value to output
253
#define CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, b, i, a)  \
254
784
  PutWord(((x & OUTPUT_ALIGNED) != 0), b, output+i*sizeof(WordType), (x & INPUT_NULL) ? (a) : (a) ^ GetWord<WordType>(((x & INPUT_ALIGNED) != 0), b, input+i*sizeof(WordType)));
255
256
/// \brief Helper macro to implement OperateKeystream
257
/// \param x KeystreamOperation mask
258
/// \param i index in output buffer
259
/// \param a value to output
260
#define CRYPTOPP_KEYSTREAM_OUTPUT_XMM(x, i, a)  {\
261
  __m128i t = (x & INPUT_NULL) ? a : _mm_xor_si128(a, (x & INPUT_ALIGNED) ? _mm_load_si128((__m128i *)input+i) : _mm_loadu_si128((__m128i *)input+i));\
262
  if (x & OUTPUT_ALIGNED) _mm_store_si128((__m128i *)output+i, t);\
263
  else _mm_storeu_si128((__m128i *)output+i, t);}
264
265
/// \brief Helper macro to implement OperateKeystream
266
#define CRYPTOPP_KEYSTREAM_OUTPUT_SWITCH(x, y)    \
267
49
  switch (operation)                \
268
49
  {                       \
269
0
    case WRITE_KEYSTREAM:           \
270
0
      x(EnumToInt(WRITE_KEYSTREAM))  \
271
0
      break;                  \
272
0
    case XOR_KEYSTREAM:             \
273
0
      x(EnumToInt(XOR_KEYSTREAM))    \
274
0
      input += y;               \
275
0
      break;                  \
276
0
    case XOR_KEYSTREAM_INPUT_ALIGNED:     \
277
0
      x(EnumToInt(XOR_KEYSTREAM_INPUT_ALIGNED))    \
278
0
      input += y;               \
279
0
      break;                  \
280
0
    case XOR_KEYSTREAM_OUTPUT_ALIGNED:      \
281
0
      x(EnumToInt(XOR_KEYSTREAM_OUTPUT_ALIGNED))   \
282
0
      input += y;               \
283
0
      break;                  \
284
49
    case WRITE_KEYSTREAM_ALIGNED:       \
285
49
      x(EnumToInt(WRITE_KEYSTREAM_ALIGNED))      \
286
49
      break;                 \
287
0
    case XOR_KEYSTREAM_BOTH_ALIGNED:      \
288
0
      x(EnumToInt(XOR_KEYSTREAM_BOTH_ALIGNED))   \
289
0
      input += y;               \
290
0
      break;                 \
291
49
  }                       \
292
49
  output += y;
293
294
/// \brief Base class for additive stream ciphers with SymmetricCipher interface
295
/// \tparam BASE AbstractPolicyHolder base class
296
template <class BASE = AbstractPolicyHolder<AdditiveCipherAbstractPolicy, SymmetricCipher> >
297
class CRYPTOPP_NO_VTABLE AdditiveCipherTemplate : public BASE, public RandomNumberGenerator
298
{
299
public:
300
724
  virtual ~AdditiveCipherTemplate() {}
CryptoPP::AdditiveCipherTemplate<CryptoPP::AbstractPolicyHolder<CryptoPP::AdditiveCipherAbstractPolicy, CryptoPP::CTR_ModePolicy> >::~AdditiveCipherTemplate()
Line
Count
Source
300
378
  virtual ~AdditiveCipherTemplate() {}
CryptoPP::AdditiveCipherTemplate<CryptoPP::AbstractPolicyHolder<CryptoPP::AdditiveCipherAbstractPolicy, CryptoPP::SymmetricCipher> >::~AdditiveCipherTemplate()
Line
Count
Source
300
40
  virtual ~AdditiveCipherTemplate() {}
CryptoPP::AdditiveCipherTemplate<CryptoPP::AbstractPolicyHolder<CryptoPP::AdditiveCipherAbstractPolicy, CryptoPP::OFB_ModePolicy> >::~AdditiveCipherTemplate()
Line
Count
Source
300
306
  virtual ~AdditiveCipherTemplate() {}
301
724
  AdditiveCipherTemplate() : m_leftOver(0) {}
CryptoPP::AdditiveCipherTemplate<CryptoPP::AbstractPolicyHolder<CryptoPP::AdditiveCipherAbstractPolicy, CryptoPP::CTR_ModePolicy> >::AdditiveCipherTemplate()
Line
Count
Source
301
378
  AdditiveCipherTemplate() : m_leftOver(0) {}
CryptoPP::AdditiveCipherTemplate<CryptoPP::AbstractPolicyHolder<CryptoPP::AdditiveCipherAbstractPolicy, CryptoPP::SymmetricCipher> >::AdditiveCipherTemplate()
Line
Count
Source
301
40
  AdditiveCipherTemplate() : m_leftOver(0) {}
CryptoPP::AdditiveCipherTemplate<CryptoPP::AbstractPolicyHolder<CryptoPP::AdditiveCipherAbstractPolicy, CryptoPP::OFB_ModePolicy> >::AdditiveCipherTemplate()
Line
Count
Source
301
306
  AdditiveCipherTemplate() : m_leftOver(0) {}
302
303
  /// \brief Generate random array of bytes
304
  /// \param output the byte buffer
305
  /// \param size the length of the buffer, in bytes
306
  /// \details All generated values are uniformly distributed over the range specified
307
  ///  within the constraints of a particular generator.
308
  void GenerateBlock(byte *output, size_t size);
309
310
  /// \brief Apply keystream to data
311
  /// \param outString a buffer to write the transformed data
312
  /// \param inString a buffer to read the data
313
  /// \param length the size of the buffers, in bytes
314
  /// \details This is the primary method to operate a stream cipher. For example:
315
  /// <pre>
316
  ///     size_t size = 30;
317
  ///     byte plain[size] = "Do or do not; there is no try";
318
  ///     byte cipher[size];
319
  ///     ...
320
  ///     ChaCha20 chacha(key, keySize);
321
  ///     chacha.ProcessData(cipher, plain, size);
322
  /// </pre>
323
  /// \details You should use distinct buffers for inString and outString. If the buffers
324
  ///  are the same, then the data will be copied to an internal buffer to avoid GCC alias
325
  ///  violations. The internal copy will impact performance.
326
  /// \sa <A HREF="https://github.com/weidai11/cryptopp/issues/1088">Issue 1088, 36% loss
327
  ///  of performance with AES</A>, <A HREF="https://github.com/weidai11/cryptopp/issues/1010">Issue
328
  ///  1010, HIGHT cipher troubles with FileSource</A>
329
  void ProcessData(byte *outString, const byte *inString, size_t length);
330
331
  /// \brief Resynchronize the cipher
332
  /// \param iv a byte array used to resynchronize the cipher
333
  /// \param length the size of the IV array
334
  void Resynchronize(const byte *iv, int length=-1);
335
336
  /// \brief Provides number of ideal bytes to process
337
  /// \return the ideal number of bytes to process
338
  /// \details Internally, the default implementation returns GetBytesPerIteration()
339
  /// \sa GetBytesPerIteration() and GetOptimalNextBlockSize()
340
41
  unsigned int OptimalBlockSize() const {return this->GetPolicy().GetOptimalBlockSize();}
Unexecuted instantiation: CryptoPP::AdditiveCipherTemplate<CryptoPP::AbstractPolicyHolder<CryptoPP::AdditiveCipherAbstractPolicy, CryptoPP::CTR_ModePolicy> >::OptimalBlockSize() const
Unexecuted instantiation: CryptoPP::AdditiveCipherTemplate<CryptoPP::AbstractPolicyHolder<CryptoPP::AdditiveCipherAbstractPolicy, CryptoPP::SymmetricCipher> >::OptimalBlockSize() const
CryptoPP::AdditiveCipherTemplate<CryptoPP::AbstractPolicyHolder<CryptoPP::AdditiveCipherAbstractPolicy, CryptoPP::OFB_ModePolicy> >::OptimalBlockSize() const
Line
Count
Source
340
41
  unsigned int OptimalBlockSize() const {return this->GetPolicy().GetOptimalBlockSize();}
341
342
  /// \brief Provides number of ideal bytes to process
343
  /// \return the ideal number of bytes to process
344
  /// \details Internally, the default implementation returns remaining unprocessed bytes
345
  /// \sa GetBytesPerIteration() and OptimalBlockSize()
346
0
  unsigned int GetOptimalNextBlockSize() const {return (unsigned int)this->m_leftOver;}
Unexecuted instantiation: CryptoPP::AdditiveCipherTemplate<CryptoPP::AbstractPolicyHolder<CryptoPP::AdditiveCipherAbstractPolicy, CryptoPP::SymmetricCipher> >::GetOptimalNextBlockSize() const
Unexecuted instantiation: CryptoPP::AdditiveCipherTemplate<CryptoPP::AbstractPolicyHolder<CryptoPP::AdditiveCipherAbstractPolicy, CryptoPP::OFB_ModePolicy> >::GetOptimalNextBlockSize() const
Unexecuted instantiation: CryptoPP::AdditiveCipherTemplate<CryptoPP::AbstractPolicyHolder<CryptoPP::AdditiveCipherAbstractPolicy, CryptoPP::CTR_ModePolicy> >::GetOptimalNextBlockSize() const
347
348
  /// \brief Provides number of ideal data alignment
349
  /// \return the ideal data alignment, in bytes
350
  /// \sa GetAlignment() and OptimalBlockSize()
351
0
  unsigned int OptimalDataAlignment() const {return this->GetPolicy().GetAlignment();}
Unexecuted instantiation: CryptoPP::AdditiveCipherTemplate<CryptoPP::AbstractPolicyHolder<CryptoPP::AdditiveCipherAbstractPolicy, CryptoPP::CTR_ModePolicy> >::OptimalDataAlignment() const
Unexecuted instantiation: CryptoPP::AdditiveCipherTemplate<CryptoPP::AbstractPolicyHolder<CryptoPP::AdditiveCipherAbstractPolicy, CryptoPP::SymmetricCipher> >::OptimalDataAlignment() const
Unexecuted instantiation: CryptoPP::AdditiveCipherTemplate<CryptoPP::AbstractPolicyHolder<CryptoPP::AdditiveCipherAbstractPolicy, CryptoPP::OFB_ModePolicy> >::OptimalDataAlignment() const
352
353
  /// \brief Determines if the cipher is self inverting
354
  /// \return true if the stream cipher is self inverting, false otherwise
355
0
  bool IsSelfInverting() const {return true;}
Unexecuted instantiation: CryptoPP::AdditiveCipherTemplate<CryptoPP::AbstractPolicyHolder<CryptoPP::AdditiveCipherAbstractPolicy, CryptoPP::CTR_ModePolicy> >::IsSelfInverting() const
Unexecuted instantiation: CryptoPP::AdditiveCipherTemplate<CryptoPP::AbstractPolicyHolder<CryptoPP::AdditiveCipherAbstractPolicy, CryptoPP::SymmetricCipher> >::IsSelfInverting() const
Unexecuted instantiation: CryptoPP::AdditiveCipherTemplate<CryptoPP::AbstractPolicyHolder<CryptoPP::AdditiveCipherAbstractPolicy, CryptoPP::OFB_ModePolicy> >::IsSelfInverting() const
356
357
  /// \brief Determines if the cipher is a forward transformation
358
  /// \return true if the stream cipher is a forward transformation, false otherwise
359
0
  bool IsForwardTransformation() const {return true;}
Unexecuted instantiation: CryptoPP::AdditiveCipherTemplate<CryptoPP::AbstractPolicyHolder<CryptoPP::AdditiveCipherAbstractPolicy, CryptoPP::CTR_ModePolicy> >::IsForwardTransformation() const
Unexecuted instantiation: CryptoPP::AdditiveCipherTemplate<CryptoPP::AbstractPolicyHolder<CryptoPP::AdditiveCipherAbstractPolicy, CryptoPP::SymmetricCipher> >::IsForwardTransformation() const
Unexecuted instantiation: CryptoPP::AdditiveCipherTemplate<CryptoPP::AbstractPolicyHolder<CryptoPP::AdditiveCipherAbstractPolicy, CryptoPP::OFB_ModePolicy> >::IsForwardTransformation() const
360
361
  /// \brief Flag indicating random access
362
  /// \return true if the cipher is seekable, false otherwise
363
  /// \sa Seek()
364
0
  bool IsRandomAccess() const {return this->GetPolicy().CipherIsRandomAccess();}
Unexecuted instantiation: CryptoPP::AdditiveCipherTemplate<CryptoPP::AbstractPolicyHolder<CryptoPP::AdditiveCipherAbstractPolicy, CryptoPP::CTR_ModePolicy> >::IsRandomAccess() const
Unexecuted instantiation: CryptoPP::AdditiveCipherTemplate<CryptoPP::AbstractPolicyHolder<CryptoPP::AdditiveCipherAbstractPolicy, CryptoPP::SymmetricCipher> >::IsRandomAccess() const
Unexecuted instantiation: CryptoPP::AdditiveCipherTemplate<CryptoPP::AbstractPolicyHolder<CryptoPP::AdditiveCipherAbstractPolicy, CryptoPP::OFB_ModePolicy> >::IsRandomAccess() const
365
366
  /// \brief Seeks to a random position in the stream
367
  /// \param position the absolute position in the stream
368
  /// \sa IsRandomAccess()
369
  void Seek(lword position);
370
371
  /// \brief Retrieve the provider of this algorithm
372
  /// \return the algorithm provider
373
  /// \details The algorithm provider can be a name like "C++", "SSE", "NEON", "AESNI",
374
  ///  "ARMv8" and "Power8". C++ is standard C++ code. Other labels, like SSE,
375
  ///  usually indicate a specialized implementation using instructions from a higher
376
  ///  instruction set architecture (ISA). Future labels may include external hardware
377
  ///  like a hardware security module (HSM).
378
  /// \details Generally speaking Wei Dai's original IA-32 ASM code falls under "SSE2".
379
  ///  Labels like "SSSE3" and "SSE4.1" follow after Wei's code and use intrinsics
380
  ///  instead of ASM.
381
  /// \details Algorithms which combine different instructions or ISAs provide the
382
  ///  dominant one. For example on x86 <tt>AES/GCM</tt> returns "AESNI" rather than
383
  ///  "CLMUL" or "AES+SSE4.1" or "AES+CLMUL" or "AES+SSE4.1+CLMUL".
384
  /// \note Provider is not universally implemented yet.
385
0
  std::string AlgorithmProvider() const { return this->GetPolicy().AlgorithmProvider(); }
Unexecuted instantiation: CryptoPP::AdditiveCipherTemplate<CryptoPP::AbstractPolicyHolder<CryptoPP::AdditiveCipherAbstractPolicy, CryptoPP::CTR_ModePolicy> >::AlgorithmProvider() const
Unexecuted instantiation: CryptoPP::AdditiveCipherTemplate<CryptoPP::AbstractPolicyHolder<CryptoPP::AdditiveCipherAbstractPolicy, CryptoPP::SymmetricCipher> >::AlgorithmProvider() const
Unexecuted instantiation: CryptoPP::AdditiveCipherTemplate<CryptoPP::AbstractPolicyHolder<CryptoPP::AdditiveCipherAbstractPolicy, CryptoPP::OFB_ModePolicy> >::AlgorithmProvider() const
386
387
  typedef typename BASE::PolicyInterface PolicyInterface;
388
389
protected:
390
  void UncheckedSetKey(const byte *key, unsigned int length, const NameValuePairs &params);
391
392
244
  unsigned int GetBufferByteSize(const PolicyInterface &policy) const {return policy.GetBytesPerIteration() * policy.GetIterationsToBuffer();}
CryptoPP::AdditiveCipherTemplate<CryptoPP::AbstractPolicyHolder<CryptoPP::AdditiveCipherAbstractPolicy, CryptoPP::SymmetricCipher> >::GetBufferByteSize(CryptoPP::AdditiveCipherAbstractPolicy const&) const
Line
Count
Source
392
72
  unsigned int GetBufferByteSize(const PolicyInterface &policy) const {return policy.GetBytesPerIteration() * policy.GetIterationsToBuffer();}
CryptoPP::AdditiveCipherTemplate<CryptoPP::AbstractPolicyHolder<CryptoPP::AdditiveCipherAbstractPolicy, CryptoPP::OFB_ModePolicy> >::GetBufferByteSize(CryptoPP::AdditiveCipherAbstractPolicy const&) const
Line
Count
Source
392
41
  unsigned int GetBufferByteSize(const PolicyInterface &policy) const {return policy.GetBytesPerIteration() * policy.GetIterationsToBuffer();}
CryptoPP::AdditiveCipherTemplate<CryptoPP::AbstractPolicyHolder<CryptoPP::AdditiveCipherAbstractPolicy, CryptoPP::CTR_ModePolicy> >::GetBufferByteSize(CryptoPP::AdditiveCipherAbstractPolicy const&) const
Line
Count
Source
392
131
  unsigned int GetBufferByteSize(const PolicyInterface &policy) const {return policy.GetBytesPerIteration() * policy.GetIterationsToBuffer();}
393
394
24
  inline byte * KeystreamBufferBegin() {return this->m_buffer.data();}
Unexecuted instantiation: CryptoPP::AdditiveCipherTemplate<CryptoPP::AbstractPolicyHolder<CryptoPP::AdditiveCipherAbstractPolicy, CryptoPP::SymmetricCipher> >::KeystreamBufferBegin()
CryptoPP::AdditiveCipherTemplate<CryptoPP::AbstractPolicyHolder<CryptoPP::AdditiveCipherAbstractPolicy, CryptoPP::OFB_ModePolicy> >::KeystreamBufferBegin()
Line
Count
Source
394
24
  inline byte * KeystreamBufferBegin() {return this->m_buffer.data();}
Unexecuted instantiation: CryptoPP::AdditiveCipherTemplate<CryptoPP::AbstractPolicyHolder<CryptoPP::AdditiveCipherAbstractPolicy, CryptoPP::CTR_ModePolicy> >::KeystreamBufferBegin()
395
493
  inline byte * KeystreamBufferEnd() {return (PtrAdd(this->m_buffer.data(), this->m_buffer.size()));}
CryptoPP::AdditiveCipherTemplate<CryptoPP::AbstractPolicyHolder<CryptoPP::AdditiveCipherAbstractPolicy, CryptoPP::SymmetricCipher> >::KeystreamBufferEnd()
Line
Count
Source
395
98
  inline byte * KeystreamBufferEnd() {return (PtrAdd(this->m_buffer.data(), this->m_buffer.size()));}
CryptoPP::AdditiveCipherTemplate<CryptoPP::AbstractPolicyHolder<CryptoPP::AdditiveCipherAbstractPolicy, CryptoPP::OFB_ModePolicy> >::KeystreamBufferEnd()
Line
Count
Source
395
231
  inline byte * KeystreamBufferEnd() {return (PtrAdd(this->m_buffer.data(), this->m_buffer.size()));}
CryptoPP::AdditiveCipherTemplate<CryptoPP::AbstractPolicyHolder<CryptoPP::AdditiveCipherAbstractPolicy, CryptoPP::CTR_ModePolicy> >::KeystreamBufferEnd()
Line
Count
Source
395
164
  inline byte * KeystreamBufferEnd() {return (PtrAdd(this->m_buffer.data(), this->m_buffer.size()));}
396
397
  AlignedSecByteBlock m_buffer;
398
  size_t m_leftOver;
399
};
400
401
/// \brief Policy object for feedback based stream ciphers
402
class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE CFB_CipherAbstractPolicy
403
{
404
public:
405
686
  virtual ~CFB_CipherAbstractPolicy() {}
406
407
  /// \brief Provides data alignment requirements
408
  /// \return data alignment requirements, in bytes
409
  /// \details Internally, the default implementation returns 1. If the stream cipher is implemented
410
  ///  using an SSE2 ASM or intrinsics, then the value returned is usually 16.
411
  virtual unsigned int GetAlignment() const =0;
412
413
  /// \brief Provides number of bytes operated upon during an iteration
414
  /// \return bytes operated upon during an iteration, in bytes
415
  /// \sa GetOptimalBlockSize()
416
  virtual unsigned int GetBytesPerIteration() const =0;
417
418
  /// \brief Access the feedback register
419
  /// \return pointer to the first byte of the feedback register
420
  virtual byte * GetRegisterBegin() =0;
421
422
  /// \brief TODO
423
  virtual void TransformRegister() =0;
424
425
  /// \brief Flag indicating iteration support
426
  /// \return true if the cipher supports iteration, false otherwise
427
0
  virtual bool CanIterate() const {return false;}
428
429
  /// \brief Iterate the cipher
430
  /// \param output the output buffer
431
  /// \param input the input buffer
432
  /// \param dir the direction of the cipher
433
  /// \param iterationCount the number of iterations to perform on the input
434
  /// \sa IsSelfInverting() and IsForwardTransformation()
435
  virtual void Iterate(byte *output, const byte *input, CipherDir dir, size_t iterationCount)
436
0
    {CRYPTOPP_UNUSED(output); CRYPTOPP_UNUSED(input); CRYPTOPP_UNUSED(dir);
437
0
    CRYPTOPP_UNUSED(iterationCount); CRYPTOPP_ASSERT(false);
438
0
    throw Exception(Exception::OTHER_ERROR, "SimpleKeyingInterface: unexpected error");}
439
440
  /// \brief Key the cipher
441
  /// \param params set of NameValuePairs use to initialize this object
442
  /// \param key a byte array used to key the cipher
443
  /// \param length the size of the key array
444
  virtual void CipherSetKey(const NameValuePairs &params, const byte *key, size_t length) =0;
445
446
  /// \brief Resynchronize the cipher
447
  /// \param iv a byte array used to resynchronize the cipher
448
  /// \param length the size of the IV array
449
  virtual void CipherResynchronize(const byte *iv, size_t length)
450
0
    {CRYPTOPP_UNUSED(iv); CRYPTOPP_UNUSED(length);
451
0
    throw NotImplemented("SimpleKeyingInterface: this object doesn't support resynchronization");}
452
453
  /// \brief Retrieve the provider of this algorithm
454
  /// \return the algorithm provider
455
  /// \details The algorithm provider can be a name like "C++", "SSE", "NEON", "AESNI",
456
  ///  "ARMv8" and "Power8". C++ is standard C++ code. Other labels, like SSE,
457
  ///  usually indicate a specialized implementation using instructions from a higher
458
  ///  instruction set architecture (ISA). Future labels may include external hardware
459
  ///  like a hardware security module (HSM).
460
  /// \details Generally speaking Wei Dai's original IA-32 ASM code falls under "SSE2".
461
  ///  Labels like "SSSE3" and "SSE4.1" follow after Wei's code and use intrinsics
462
  ///  instead of ASM.
463
  /// \details Algorithms which combine different instructions or ISAs provide the
464
  ///  dominant one. For example on x86 <tt>AES/GCM</tt> returns "AESNI" rather than
465
  ///  "CLMUL" or "AES+SSE4.1" or "AES+CLMUL" or "AES+SSE4.1+CLMUL".
466
  /// \note Provider is not universally implemented yet.
467
0
  virtual std::string AlgorithmProvider() const { return "C++"; }
468
};
469
470
/// \brief Base class for feedback based stream ciphers
471
/// \tparam WT word type
472
/// \tparam W count of words
473
/// \tparam BASE CFB_CipherAbstractPolicy derived base class
474
template <typename WT, unsigned int W, class BASE = CFB_CipherAbstractPolicy>
475
struct CRYPTOPP_NO_VTABLE CFB_CipherConcretePolicy : public BASE
476
{
477
  typedef WT WordType;
478
479
  virtual ~CFB_CipherConcretePolicy() {}
480
481
  /// \brief Provides data alignment requirements
482
  /// \return data alignment requirements, in bytes
483
  /// \details Internally, the default implementation returns 1. If the stream cipher is implemented
484
  ///   using an SSE2 ASM or intrinsics, then the value returned is usually 16.
485
  unsigned int GetAlignment() const {return sizeof(WordType);}
486
487
  /// \brief Provides number of bytes operated upon during an iteration
488
  /// \return bytes operated upon during an iteration, in bytes
489
  /// \sa GetOptimalBlockSize()
490
  unsigned int GetBytesPerIteration() const {return sizeof(WordType) * W;}
491
492
  /// \brief Flag indicating iteration support
493
  /// \return true if the cipher supports iteration, false otherwise
494
  bool CanIterate() const {return true;}
495
496
  /// \brief Perform one iteration in the forward direction
497
  void TransformRegister() {this->Iterate(NULLPTR, NULLPTR, ENCRYPTION, 1);}
498
499
  /// \brief Provides alternate access to a feedback register
500
  /// \tparam B enumeration indicating endianness
501
  /// \details RegisterOutput() provides alternate access to the feedback register. The
502
  ///   enumeration B is BigEndian or LittleEndian. Repeatedly applying operator()
503
  ///   results in advancing in the register.
504
  template <class B>
505
  struct RegisterOutput
506
  {
507
    RegisterOutput(byte *output, const byte *input, CipherDir dir)
508
      : m_output(output), m_input(input), m_dir(dir) {}
509
510
    /// \brief XOR feedback register with data
511
    /// \param registerWord data represented as a word type
512
    /// \return reference to the next feedback register word
513
    inline RegisterOutput& operator()(WordType &registerWord)
514
    {
515
      //CRYPTOPP_ASSERT(IsAligned<WordType>(m_output));
516
      //CRYPTOPP_ASSERT(IsAligned<WordType>(m_input));
517
518
      if (!NativeByteOrderIs(B::ToEnum()))
519
        registerWord = ByteReverse(registerWord);
520
521
      if (m_dir == ENCRYPTION)
522
      {
523
        if (m_input == NULLPTR)
524
        {
525
          CRYPTOPP_ASSERT(m_output == NULLPTR);
526
        }
527
        else
528
        {
529
          // WordType ct = *(const WordType *)m_input ^ registerWord;
530
          WordType ct = GetWord<WordType>(false, NativeByteOrder::ToEnum(), m_input) ^ registerWord;
531
          registerWord = ct;
532
533
          // *(WordType*)m_output = ct;
534
          PutWord<WordType>(false, NativeByteOrder::ToEnum(), m_output, ct);
535
536
          m_input += sizeof(WordType);
537
          m_output += sizeof(WordType);
538
        }
539
      }
540
      else
541
      {
542
        // WordType ct = *(const WordType *)m_input;
543
        WordType ct = GetWord<WordType>(false, NativeByteOrder::ToEnum(), m_input);
544
545
        // *(WordType*)m_output = registerWord ^ ct;
546
        PutWord<WordType>(false, NativeByteOrder::ToEnum(), m_output, registerWord ^ ct);
547
        registerWord = ct;
548
549
        m_input += sizeof(WordType);
550
        m_output += sizeof(WordType);
551
      }
552
553
      // registerWord is left unreversed so it can be xor-ed with further input
554
555
      return *this;
556
    }
557
558
    byte *m_output;
559
    const byte *m_input;
560
    CipherDir m_dir;
561
  };
562
};
563
564
/// \brief Base class for feedback based stream ciphers with SymmetricCipher interface
565
/// \tparam BASE AbstractPolicyHolder base class
566
template <class BASE>
567
class CRYPTOPP_NO_VTABLE CFB_CipherTemplate : public BASE
568
{
569
public:
570
686
  virtual ~CFB_CipherTemplate() {}
CryptoPP::CFB_CipherTemplate<CryptoPP::AbstractPolicyHolder<CryptoPP::CFB_CipherAbstractPolicy, CryptoPP::CFB_ModePolicy> >::~CFB_CipherTemplate()
Line
Count
Source
570
686
  virtual ~CFB_CipherTemplate() {}
Unexecuted instantiation: CryptoPP::CFB_CipherTemplate<CryptoPP::AbstractPolicyHolder<CryptoPP::CFB_CipherAbstractPolicy, CryptoPP::SymmetricCipher> >::~CFB_CipherTemplate()
571
686
  CFB_CipherTemplate() : m_leftOver(0) {}
CryptoPP::CFB_CipherTemplate<CryptoPP::AbstractPolicyHolder<CryptoPP::CFB_CipherAbstractPolicy, CryptoPP::CFB_ModePolicy> >::CFB_CipherTemplate()
Line
Count
Source
571
686
  CFB_CipherTemplate() : m_leftOver(0) {}
Unexecuted instantiation: CryptoPP::CFB_CipherTemplate<CryptoPP::AbstractPolicyHolder<CryptoPP::CFB_CipherAbstractPolicy, CryptoPP::SymmetricCipher> >::CFB_CipherTemplate()
572
573
  /// \brief Apply keystream to data
574
  /// \param outString a buffer to write the transformed data
575
  /// \param inString a buffer to read the data
576
  /// \param length the size of the buffers, in bytes
577
  /// \details This is the primary method to operate a stream cipher. For example:
578
  /// <pre>
579
  ///     size_t size = 30;
580
  ///     byte plain[size] = "Do or do not; there is no try";
581
  ///     byte cipher[size];
582
  ///     ...
583
  ///     ChaCha20 chacha(key, keySize);
584
  ///     chacha.ProcessData(cipher, plain, size);
585
  /// </pre>
586
  /// \details You should use distinct buffers for inString and outString. If the buffers
587
  ///  are the same, then the data will be copied to an internal buffer to avoid GCC alias
588
  ///  violations. The internal copy will impact performance.
589
  /// \sa <A HREF="https://github.com/weidai11/cryptopp/issues/1088">Issue 1088, 36% loss
590
  ///  of performance with AES</A>, <A HREF="https://github.com/weidai11/cryptopp/issues/1010">Issue
591
  ///  1010, HIGHT cipher troubles with FileSource</A>
592
  void ProcessData(byte *outString, const byte *inString, size_t length);
593
594
  /// \brief Resynchronize the cipher
595
  /// \param iv a byte array used to resynchronize the cipher
596
  /// \param length the size of the IV array
597
  void Resynchronize(const byte *iv, int length=-1);
598
599
  /// \brief Provides number of ideal bytes to process
600
  /// \return the ideal number of bytes to process
601
  /// \details Internally, the default implementation returns GetBytesPerIteration()
602
  /// \sa GetBytesPerIteration() and GetOptimalNextBlockSize()
603
157
  unsigned int OptimalBlockSize() const {return this->GetPolicy().GetBytesPerIteration();}
CryptoPP::CFB_CipherTemplate<CryptoPP::AbstractPolicyHolder<CryptoPP::CFB_CipherAbstractPolicy, CryptoPP::CFB_ModePolicy> >::OptimalBlockSize() const
Line
Count
Source
603
157
  unsigned int OptimalBlockSize() const {return this->GetPolicy().GetBytesPerIteration();}
Unexecuted instantiation: CryptoPP::CFB_CipherTemplate<CryptoPP::AbstractPolicyHolder<CryptoPP::CFB_CipherAbstractPolicy, CryptoPP::SymmetricCipher> >::OptimalBlockSize() const
604
605
  /// \brief Provides number of ideal bytes to process
606
  /// \return the ideal number of bytes to process
607
  /// \details Internally, the default implementation returns remaining unprocessed bytes
608
  /// \sa GetBytesPerIteration() and OptimalBlockSize()
609
0
  unsigned int GetOptimalNextBlockSize() const {return (unsigned int)m_leftOver;}
Unexecuted instantiation: CryptoPP::CFB_CipherTemplate<CryptoPP::AbstractPolicyHolder<CryptoPP::CFB_CipherAbstractPolicy, CryptoPP::SymmetricCipher> >::GetOptimalNextBlockSize() const
Unexecuted instantiation: CryptoPP::CFB_CipherTemplate<CryptoPP::AbstractPolicyHolder<CryptoPP::CFB_CipherAbstractPolicy, CryptoPP::CFB_ModePolicy> >::GetOptimalNextBlockSize() const
610
611
  /// \brief Provides number of ideal data alignment
612
  /// \return the ideal data alignment, in bytes
613
  /// \sa GetAlignment() and OptimalBlockSize()
614
0
  unsigned int OptimalDataAlignment() const {return this->GetPolicy().GetAlignment();}
Unexecuted instantiation: CryptoPP::CFB_CipherTemplate<CryptoPP::AbstractPolicyHolder<CryptoPP::CFB_CipherAbstractPolicy, CryptoPP::CFB_ModePolicy> >::OptimalDataAlignment() const
Unexecuted instantiation: CryptoPP::CFB_CipherTemplate<CryptoPP::AbstractPolicyHolder<CryptoPP::CFB_CipherAbstractPolicy, CryptoPP::SymmetricCipher> >::OptimalDataAlignment() const
615
616
  /// \brief Flag indicating random access
617
  /// \return true if the cipher is seekable, false otherwise
618
  /// \sa Seek()
619
0
  bool IsRandomAccess() const {return false;}
Unexecuted instantiation: CryptoPP::CFB_CipherTemplate<CryptoPP::AbstractPolicyHolder<CryptoPP::CFB_CipherAbstractPolicy, CryptoPP::CFB_ModePolicy> >::IsRandomAccess() const
Unexecuted instantiation: CryptoPP::CFB_CipherTemplate<CryptoPP::AbstractPolicyHolder<CryptoPP::CFB_CipherAbstractPolicy, CryptoPP::SymmetricCipher> >::IsRandomAccess() const
620
621
  /// \brief Determines if the cipher is self inverting
622
  /// \return true if the stream cipher is self inverting, false otherwise
623
0
  bool IsSelfInverting() const {return false;}
Unexecuted instantiation: CryptoPP::CFB_CipherTemplate<CryptoPP::AbstractPolicyHolder<CryptoPP::CFB_CipherAbstractPolicy, CryptoPP::CFB_ModePolicy> >::IsSelfInverting() const
Unexecuted instantiation: CryptoPP::CFB_CipherTemplate<CryptoPP::AbstractPolicyHolder<CryptoPP::CFB_CipherAbstractPolicy, CryptoPP::SymmetricCipher> >::IsSelfInverting() const
624
625
  /// \brief Retrieve the provider of this algorithm
626
  /// \return the algorithm provider
627
  /// \details The algorithm provider can be a name like "C++", "SSE", "NEON", "AESNI",
628
  ///  "ARMv8" and "Power8". C++ is standard C++ code. Other labels, like SSE,
629
  ///  usually indicate a specialized implementation using instructions from a higher
630
  ///  instruction set architecture (ISA). Future labels may include external hardware
631
  ///  like a hardware security module (HSM).
632
  /// \details Generally speaking Wei Dai's original IA-32 ASM code falls under "SSE2".
633
  ///  Labels like "SSSE3" and "SSE4.1" follow after Wei's code and use intrinsics
634
  ///  instead of ASM.
635
  /// \details Algorithms which combine different instructions or ISAs provide the
636
  ///  dominant one. For example on x86 <tt>AES/GCM</tt> returns "AESNI" rather than
637
  ///  "CLMUL" or "AES+SSE4.1" or "AES+CLMUL" or "AES+SSE4.1+CLMUL".
638
  /// \note Provider is not universally implemented yet.
639
0
  std::string AlgorithmProvider() const { return this->GetPolicy().AlgorithmProvider(); }
Unexecuted instantiation: CryptoPP::CFB_CipherTemplate<CryptoPP::AbstractPolicyHolder<CryptoPP::CFB_CipherAbstractPolicy, CryptoPP::CFB_ModePolicy> >::AlgorithmProvider() const
Unexecuted instantiation: CryptoPP::CFB_CipherTemplate<CryptoPP::AbstractPolicyHolder<CryptoPP::CFB_CipherAbstractPolicy, CryptoPP::SymmetricCipher> >::AlgorithmProvider() const
640
641
  typedef typename BASE::PolicyInterface PolicyInterface;
642
643
protected:
644
  virtual void CombineMessageAndShiftRegister(byte *output, byte *reg, const byte *message, size_t length) =0;
645
646
  void UncheckedSetKey(const byte *key, unsigned int length, const NameValuePairs &params);
647
648
  size_t m_leftOver;
649
};
650
651
/// \brief Base class for feedback based stream ciphers in the forward direction with SymmetricCipher interface
652
/// \tparam BASE AbstractPolicyHolder base class
653
template <class BASE = AbstractPolicyHolder<CFB_CipherAbstractPolicy, SymmetricCipher> >
654
class CRYPTOPP_NO_VTABLE CFB_EncryptionTemplate : public CFB_CipherTemplate<BASE>
655
{
656
200
  bool IsForwardTransformation() const {return true;}
CryptoPP::CFB_EncryptionTemplate<CryptoPP::AbstractPolicyHolder<CryptoPP::CFB_CipherAbstractPolicy, CryptoPP::CFB_ModePolicy> >::IsForwardTransformation() const
Line
Count
Source
656
200
  bool IsForwardTransformation() const {return true;}
Unexecuted instantiation: CryptoPP::CFB_EncryptionTemplate<CryptoPP::AbstractPolicyHolder<CryptoPP::CFB_CipherAbstractPolicy, CryptoPP::SymmetricCipher> >::IsForwardTransformation() const
657
  void CombineMessageAndShiftRegister(byte *output, byte *reg, const byte *message, size_t length);
658
};
659
660
/// \brief Base class for feedback based stream ciphers in the reverse direction with SymmetricCipher interface
661
/// \tparam BASE AbstractPolicyHolder base class
662
template <class BASE = AbstractPolicyHolder<CFB_CipherAbstractPolicy, SymmetricCipher> >
663
class CRYPTOPP_NO_VTABLE CFB_DecryptionTemplate : public CFB_CipherTemplate<BASE>
664
{
665
46
  bool IsForwardTransformation() const {return false;}
CryptoPP::CFB_DecryptionTemplate<CryptoPP::AbstractPolicyHolder<CryptoPP::CFB_CipherAbstractPolicy, CryptoPP::CFB_ModePolicy> >::IsForwardTransformation() const
Line
Count
Source
665
46
  bool IsForwardTransformation() const {return false;}
Unexecuted instantiation: CryptoPP::CFB_DecryptionTemplate<CryptoPP::AbstractPolicyHolder<CryptoPP::CFB_CipherAbstractPolicy, CryptoPP::SymmetricCipher> >::IsForwardTransformation() const
666
  void CombineMessageAndShiftRegister(byte *output, byte *reg, const byte *message, size_t length);
667
};
668
669
/// \brief Base class for feedback based stream ciphers with a mandatory block size
670
/// \tparam BASE CFB_EncryptionTemplate or CFB_DecryptionTemplate base class
671
template <class BASE>
672
class CFB_RequireFullDataBlocks : public BASE
673
{
674
public:
675
  unsigned int MandatoryBlockSize() const {return this->OptimalBlockSize();}
676
};
677
678
/// \brief SymmetricCipher implementation
679
/// \tparam BASE AbstractPolicyHolder derived base class
680
/// \tparam INFO AbstractPolicyHolder derived information class
681
/// \sa Weak::ARC4, ChaCha8, ChaCha12, ChaCha20, Salsa20, SEAL, Sosemanuk, WAKE
682
template <class BASE, class INFO = BASE>
683
class SymmetricCipherFinal : public AlgorithmImpl<SimpleKeyingInterfaceImpl<BASE, INFO>, INFO>
684
{
685
public:
686
  virtual ~SymmetricCipherFinal() {}
687
688
  /// \brief Construct a stream cipher
689
40
  SymmetricCipherFinal() {}
CryptoPP::SymmetricCipherFinal<CryptoPP::ConcretePolicyHolder<CryptoPP::ChaChaTLS_Policy, CryptoPP::AdditiveCipherTemplate<CryptoPP::AbstractPolicyHolder<CryptoPP::AdditiveCipherAbstractPolicy, CryptoPP::SymmetricCipher> >, CryptoPP::AdditiveCipherAbstractPolicy>, CryptoPP::ChaChaTLS_Info>::SymmetricCipherFinal()
Line
Count
Source
689
27
  SymmetricCipherFinal() {}
CryptoPP::SymmetricCipherFinal<CryptoPP::ConcretePolicyHolder<CryptoPP::XChaCha20_Policy, CryptoPP::AdditiveCipherTemplate<CryptoPP::AbstractPolicyHolder<CryptoPP::AdditiveCipherAbstractPolicy, CryptoPP::SymmetricCipher> >, CryptoPP::AdditiveCipherAbstractPolicy>, CryptoPP::XChaCha20_Info>::SymmetricCipherFinal()
Line
Count
Source
689
13
  SymmetricCipherFinal() {}
690
691
  /// \brief Construct a stream cipher
692
  /// \param key a byte array used to key the cipher
693
  /// \details This overload uses DEFAULT_KEYLENGTH
694
  SymmetricCipherFinal(const byte *key)
695
    {this->SetKey(key, this->DEFAULT_KEYLENGTH);}
696
697
  /// \brief Construct a stream cipher
698
  /// \param key a byte array used to key the cipher
699
  /// \param length the size of the key array
700
  SymmetricCipherFinal(const byte *key, size_t length)
701
    {this->SetKey(key, length);}
702
703
  /// \brief Construct a stream cipher
704
  /// \param key a byte array used to key the cipher
705
  /// \param length the size of the key array
706
  /// \param iv a byte array used as an initialization vector
707
  SymmetricCipherFinal(const byte *key, size_t length, const byte *iv)
708
    {this->SetKeyWithIV(key, length, iv);}
709
710
  /// \brief Clone a SymmetricCipher
711
  /// \return a new SymmetricCipher based on this object
712
0
  Clonable * Clone() const {return static_cast<SymmetricCipher *>(new SymmetricCipherFinal<BASE, INFO>(*this));}
Unexecuted instantiation: CryptoPP::SymmetricCipherFinal<CryptoPP::ConcretePolicyHolder<CryptoPP::ChaChaTLS_Policy, CryptoPP::AdditiveCipherTemplate<CryptoPP::AbstractPolicyHolder<CryptoPP::AdditiveCipherAbstractPolicy, CryptoPP::SymmetricCipher> >, CryptoPP::AdditiveCipherAbstractPolicy>, CryptoPP::ChaChaTLS_Info>::Clone() const
Unexecuted instantiation: CryptoPP::SymmetricCipherFinal<CryptoPP::ConcretePolicyHolder<CryptoPP::XChaCha20_Policy, CryptoPP::AdditiveCipherTemplate<CryptoPP::AbstractPolicyHolder<CryptoPP::AdditiveCipherAbstractPolicy, CryptoPP::SymmetricCipher> >, CryptoPP::AdditiveCipherAbstractPolicy>, CryptoPP::XChaCha20_Info>::Clone() const
713
};
714
715
NAMESPACE_END
716
717
// Used by dll.cpp to ensure objects are in dll.o, and not strciphr.o.
718
#ifdef CRYPTOPP_MANUALLY_INSTANTIATE_TEMPLATES
719
# include "strciphr.cpp"
720
#endif
721
722
NAMESPACE_BEGIN(CryptoPP)
723
724
CRYPTOPP_DLL_TEMPLATE_CLASS AbstractPolicyHolder<AdditiveCipherAbstractPolicy, SymmetricCipher>;
725
CRYPTOPP_DLL_TEMPLATE_CLASS AdditiveCipherTemplate<AbstractPolicyHolder<AdditiveCipherAbstractPolicy, SymmetricCipher> >;
726
727
CRYPTOPP_DLL_TEMPLATE_CLASS CFB_CipherTemplate<AbstractPolicyHolder<CFB_CipherAbstractPolicy, SymmetricCipher> >;
728
CRYPTOPP_DLL_TEMPLATE_CLASS CFB_EncryptionTemplate<AbstractPolicyHolder<CFB_CipherAbstractPolicy, SymmetricCipher> >;
729
CRYPTOPP_DLL_TEMPLATE_CLASS CFB_DecryptionTemplate<AbstractPolicyHolder<CFB_CipherAbstractPolicy, SymmetricCipher> >;
730
731
NAMESPACE_END
732
733
#if CRYPTOPP_MSC_VERSION
734
# pragma warning(pop)
735
#endif
736
737
#endif