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 ¶ms, 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 ¶ms); |
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 ¶ms, 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 ®isterWord) |
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 ¶ms); |
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 |