/src/cryptopp/cryptlib.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | // cryptlib.cpp - originally written and placed in the public domain by Wei Dai |
2 | | |
3 | | #include "pch.h" |
4 | | #include "config.h" |
5 | | |
6 | | #if CRYPTOPP_MSC_VERSION |
7 | | # pragma warning(disable: 4127 4189 4459) |
8 | | #endif |
9 | | |
10 | | #if CRYPTOPP_GCC_DIAGNOSTIC_AVAILABLE |
11 | | # pragma GCC diagnostic ignored "-Wunused-value" |
12 | | # pragma GCC diagnostic ignored "-Wunused-variable" |
13 | | # pragma GCC diagnostic ignored "-Wunused-parameter" |
14 | | #endif |
15 | | |
16 | | #ifndef CRYPTOPP_IMPORTS |
17 | | |
18 | | #include "cryptlib.h" |
19 | | #include "filters.h" |
20 | | #include "algparam.h" |
21 | | #include "fips140.h" |
22 | | #include "argnames.h" |
23 | | #include "fltrimpl.h" |
24 | | #include "osrng.h" |
25 | | #include "secblock.h" |
26 | | #include "smartptr.h" |
27 | | #include "stdcpp.h" |
28 | | #include "misc.h" |
29 | | |
30 | | NAMESPACE_BEGIN(CryptoPP) |
31 | | |
32 | | CRYPTOPP_COMPILE_ASSERT(sizeof(byte) == 1); |
33 | | CRYPTOPP_COMPILE_ASSERT(sizeof(word16) == 2); |
34 | | CRYPTOPP_COMPILE_ASSERT(sizeof(word32) == 4); |
35 | | CRYPTOPP_COMPILE_ASSERT(sizeof(word64) == 8); |
36 | | #ifdef CRYPTOPP_NATIVE_DWORD_AVAILABLE |
37 | | CRYPTOPP_COMPILE_ASSERT(sizeof(dword) == 2*sizeof(word)); |
38 | | #endif |
39 | | |
40 | | BufferedTransformation & TheBitBucket() |
41 | 5.65M | { |
42 | 5.65M | static BitBucket bitBucket; |
43 | 5.65M | return bitBucket; |
44 | 5.65M | } |
45 | | |
46 | | Algorithm::Algorithm(bool checkSelfTestStatus) |
47 | 305M | { |
48 | 305M | if (checkSelfTestStatus && FIPS_140_2_ComplianceEnabled()) |
49 | 0 | { |
50 | 0 | if (GetPowerUpSelfTestStatus() == POWER_UP_SELF_TEST_NOT_DONE && !PowerUpSelfTestInProgressOnThisThread()) |
51 | 0 | throw SelfTestFailure("Cryptographic algorithms are disabled before the power-up self tests are performed."); |
52 | | |
53 | 0 | if (GetPowerUpSelfTestStatus() == POWER_UP_SELF_TEST_FAILED) |
54 | 0 | throw SelfTestFailure("Cryptographic algorithms are disabled after a power-up self test failed."); |
55 | 0 | } |
56 | 305M | } |
57 | | |
58 | | void SimpleKeyingInterface::SetKey(const byte *key, size_t length, const NameValuePairs ¶ms) |
59 | 6.96k | { |
60 | 6.96k | this->ThrowIfInvalidKeyLength(length); |
61 | 6.96k | this->UncheckedSetKey(key, static_cast<unsigned int>(length), params); |
62 | 6.96k | } |
63 | | |
64 | | void SimpleKeyingInterface::SetKeyWithRounds(const byte *key, size_t length, int rounds) |
65 | 0 | { |
66 | 0 | SetKey(key, length, MakeParameters(Name::Rounds(), rounds)); |
67 | 0 | } |
68 | | |
69 | | void SimpleKeyingInterface::SetKeyWithIV(const byte *key, size_t length, const byte *iv, size_t ivLength) |
70 | 142 | { |
71 | 142 | SetKey(key, length, MakeParameters(Name::IV(), ConstByteArrayParameter(iv, ivLength))); |
72 | 142 | } |
73 | | |
74 | | void SimpleKeyingInterface::ThrowIfInvalidKeyLength(size_t length) |
75 | 6.99k | { |
76 | 6.99k | if (!IsValidKeyLength(length)) |
77 | 397 | throw InvalidKeyLength(GetAlgorithm().AlgorithmName(), length); |
78 | 6.99k | } |
79 | | |
80 | | void SimpleKeyingInterface::ThrowIfResynchronizable() |
81 | 53 | { |
82 | 53 | if (IsResynchronizable()) |
83 | 53 | throw InvalidArgument(GetAlgorithm().AlgorithmName() + ": this object requires an IV"); |
84 | 53 | } |
85 | | |
86 | | void SimpleKeyingInterface::ThrowIfInvalidIV(const byte *iv) |
87 | 805 | { |
88 | 805 | if (!iv && IVRequirement() == UNPREDICTABLE_RANDOM_IV) |
89 | 0 | throw InvalidArgument(GetAlgorithm().AlgorithmName() + ": this object cannot use a null IV"); |
90 | 805 | } |
91 | | |
92 | | size_t SimpleKeyingInterface::ThrowIfInvalidIVLength(int length) |
93 | 1.10k | { |
94 | 1.10k | size_t size = 0; |
95 | 1.10k | if (length < 0) |
96 | 228 | size = static_cast<size_t>(IVSize()); |
97 | 877 | else if ((size_t)length < MinIVLength()) |
98 | 17 | throw InvalidArgument(GetAlgorithm().AlgorithmName() + ": IV length " + IntToString(length) + " is less than the minimum of " + IntToString(MinIVLength())); |
99 | 860 | else if ((size_t)length > MaxIVLength()) |
100 | 8 | throw InvalidArgument(GetAlgorithm().AlgorithmName() + ": IV length " + IntToString(length) + " exceeds the maximum of " + IntToString(MaxIVLength())); |
101 | 852 | else |
102 | 852 | size = static_cast<size_t>(length); |
103 | | |
104 | 1.08k | return size; |
105 | 1.10k | } |
106 | | |
107 | | const byte * SimpleKeyingInterface::GetIVAndThrowIfInvalid(const NameValuePairs ¶ms, size_t &size) |
108 | 630 | { |
109 | 630 | ConstByteArrayParameter ivWithLength; |
110 | 630 | const byte *iv = NULLPTR; |
111 | 630 | bool found = false; |
112 | | |
113 | 630 | try {found = params.GetValue(Name::IV(), ivWithLength);} |
114 | 630 | catch (const NameValuePairs::ValueTypeMismatch &) {} |
115 | | |
116 | 630 | if (found) |
117 | 577 | { |
118 | 577 | iv = ivWithLength.begin(); |
119 | 577 | ThrowIfInvalidIV(iv); |
120 | 577 | size = ThrowIfInvalidIVLength(static_cast<int>(ivWithLength.size())); |
121 | 577 | } |
122 | 53 | else if (params.GetValue(Name::IV(), iv)) |
123 | 0 | { |
124 | 0 | ThrowIfInvalidIV(iv); |
125 | 0 | size = static_cast<size_t>(IVSize()); |
126 | 0 | } |
127 | 53 | else |
128 | 53 | { |
129 | 53 | ThrowIfResynchronizable(); |
130 | 53 | size = 0; |
131 | 53 | } |
132 | | |
133 | 630 | return iv; |
134 | 630 | } |
135 | | |
136 | | void SimpleKeyingInterface::GetNextIV(RandomNumberGenerator &rng, byte *iv) |
137 | 0 | { |
138 | 0 | rng.GenerateBlock(iv, IVSize()); |
139 | 0 | } |
140 | | |
141 | | size_t BlockTransformation::AdvancedProcessBlocks(const byte *inBlocks, const byte *xorBlocks, byte *outBlocks, size_t length, word32 flags) const |
142 | 865 | { |
143 | 865 | CRYPTOPP_ASSERT(inBlocks); |
144 | 865 | CRYPTOPP_ASSERT(outBlocks); |
145 | 865 | CRYPTOPP_ASSERT(length); |
146 | | |
147 | 865 | const unsigned int blockSize = BlockSize(); |
148 | 865 | size_t inIncrement = (flags & (BT_InBlockIsCounter|BT_DontIncrementInOutPointers)) ? 0 : blockSize; |
149 | 865 | size_t xorIncrement = xorBlocks ? blockSize : 0; |
150 | 865 | size_t outIncrement = (flags & BT_DontIncrementInOutPointers) ? 0 : blockSize; |
151 | | |
152 | 865 | if (flags & BT_ReverseDirection) |
153 | 19 | { |
154 | 19 | inBlocks = PtrAdd(inBlocks, length - blockSize); |
155 | 19 | xorBlocks = PtrAdd(xorBlocks, length - blockSize); |
156 | 19 | outBlocks = PtrAdd(outBlocks, length - blockSize); |
157 | 19 | inIncrement = 0-inIncrement; |
158 | 19 | xorIncrement = 0-xorIncrement; |
159 | 19 | outIncrement = 0-outIncrement; |
160 | 19 | } |
161 | | |
162 | | // Coverity finding. |
163 | 865 | const bool xorFlag = xorBlocks && (flags & BT_XorInput); |
164 | 30.1k | while (length >= blockSize) |
165 | 29.2k | { |
166 | 29.2k | if (xorFlag) |
167 | 427 | { |
168 | | // xorBlocks non-NULL and with BT_XorInput. |
169 | 427 | xorbuf(outBlocks, xorBlocks, inBlocks, blockSize); |
170 | 427 | ProcessBlock(outBlocks); |
171 | 427 | } |
172 | 28.8k | else |
173 | 28.8k | { |
174 | | // xorBlocks may be non-NULL and without BT_XorInput. |
175 | 28.8k | ProcessAndXorBlock(inBlocks, xorBlocks, outBlocks); |
176 | 28.8k | } |
177 | | |
178 | 29.2k | if (flags & BT_InBlockIsCounter) |
179 | 0 | const_cast<byte *>(inBlocks)[blockSize-1]++; |
180 | | |
181 | 29.2k | inBlocks = PtrAdd(inBlocks, inIncrement); |
182 | 29.2k | outBlocks = PtrAdd(outBlocks, outIncrement); |
183 | 29.2k | xorBlocks = PtrAdd(xorBlocks, xorIncrement); |
184 | 29.2k | length -= blockSize; |
185 | 29.2k | } |
186 | | |
187 | 865 | return length; |
188 | 865 | } |
189 | | |
190 | | unsigned int BlockTransformation::OptimalDataAlignment() const |
191 | 305 | { |
192 | 305 | return GetAlignmentOf<word32>(); |
193 | 305 | } |
194 | | |
195 | | unsigned int StreamTransformation::OptimalDataAlignment() const |
196 | 0 | { |
197 | 0 | return GetAlignmentOf<word32>(); |
198 | 0 | } |
199 | | |
200 | | unsigned int HashTransformation::OptimalDataAlignment() const |
201 | 0 | { |
202 | 0 | return GetAlignmentOf<word32>(); |
203 | 0 | } |
204 | | |
205 | | #if 0 |
206 | | void StreamTransformation::ProcessLastBlock(byte *outString, const byte *inString, size_t length) |
207 | | { |
208 | | CRYPTOPP_ASSERT(MinLastBlockSize() == 0); // this function should be overridden otherwise |
209 | | |
210 | | if (length == MandatoryBlockSize()) |
211 | | ProcessData(outString, inString, length); |
212 | | else if (length != 0) |
213 | | throw NotImplemented(AlgorithmName() + ": this object doesn't support a special last block"); |
214 | | } |
215 | | #endif |
216 | | |
217 | | size_t StreamTransformation::ProcessLastBlock(byte *outString, size_t outLength, const byte *inString, size_t inLength) |
218 | 0 | { |
219 | | // this function should be overridden otherwise |
220 | 0 | CRYPTOPP_ASSERT(MinLastBlockSize() == 0); |
221 | |
|
222 | 0 | if (inLength == MandatoryBlockSize()) |
223 | 0 | { |
224 | 0 | outLength = inLength; // squash unused warning |
225 | 0 | ProcessData(outString, inString, inLength); |
226 | 0 | } |
227 | 0 | else if (inLength != 0) |
228 | 0 | throw NotImplemented(AlgorithmName() + ": this object doesn't support a special last block"); |
229 | | |
230 | 0 | return outLength; |
231 | 0 | } |
232 | | |
233 | | void AuthenticatedSymmetricCipher::SpecifyDataLengths(lword headerLength, lword messageLength, lword footerLength) |
234 | 0 | { |
235 | 0 | if (headerLength > MaxHeaderLength()) |
236 | 0 | throw InvalidArgument(GetAlgorithm().AlgorithmName() + ": header length " + IntToString(headerLength) + " exceeds the maximum of " + IntToString(MaxHeaderLength())); |
237 | | |
238 | 0 | if (messageLength > MaxMessageLength()) |
239 | 0 | throw InvalidArgument(GetAlgorithm().AlgorithmName() + ": message length " + IntToString(messageLength) + " exceeds the maximum of " + IntToString(MaxMessageLength())); |
240 | | |
241 | 0 | if (footerLength > MaxFooterLength()) |
242 | 0 | throw InvalidArgument(GetAlgorithm().AlgorithmName() + ": footer length " + IntToString(footerLength) + " exceeds the maximum of " + IntToString(MaxFooterLength())); |
243 | | |
244 | 0 | UncheckedSpecifyDataLengths(headerLength, messageLength, footerLength); |
245 | 0 | } |
246 | | |
247 | | void AuthenticatedSymmetricCipher::EncryptAndAuthenticate(byte *ciphertext, byte *mac, size_t macSize, const byte *iv, int ivLength, const byte *header, size_t headerLength, const byte *message, size_t messageLength) |
248 | 0 | { |
249 | 0 | Resynchronize(iv, ivLength); |
250 | 0 | SpecifyDataLengths(headerLength, messageLength); |
251 | 0 | Update(header, headerLength); |
252 | 0 | ProcessString(ciphertext, message, messageLength); |
253 | 0 | TruncatedFinal(mac, macSize); |
254 | 0 | } |
255 | | |
256 | | bool AuthenticatedSymmetricCipher::DecryptAndVerify(byte *message, const byte *mac, size_t macLength, const byte *iv, int ivLength, const byte *header, size_t headerLength, const byte *ciphertext, size_t ciphertextLength) |
257 | 0 | { |
258 | 0 | Resynchronize(iv, ivLength); |
259 | 0 | SpecifyDataLengths(headerLength, ciphertextLength); |
260 | 0 | Update(header, headerLength); |
261 | 0 | ProcessString(message, ciphertext, ciphertextLength); |
262 | 0 | return TruncatedVerify(mac, macLength); |
263 | 0 | } |
264 | | |
265 | | std::string AuthenticatedSymmetricCipher::AlgorithmName() const |
266 | 0 | { |
267 | | // Squash C4505 on Visual Studio 2008 and friends |
268 | 0 | return "Unknown"; |
269 | 0 | } |
270 | | |
271 | | unsigned int RandomNumberGenerator::GenerateBit() |
272 | 0 | { |
273 | 0 | return GenerateByte() & 1; |
274 | 0 | } |
275 | | |
276 | | byte RandomNumberGenerator::GenerateByte() |
277 | 0 | { |
278 | 0 | byte b; |
279 | 0 | GenerateBlock(&b, 1); |
280 | 0 | return b; |
281 | 0 | } |
282 | | |
283 | | word32 RandomNumberGenerator::GenerateWord32(word32 min, word32 max) |
284 | 0 | { |
285 | 0 | const word32 range = max-min; |
286 | 0 | const unsigned int maxBits = BitPrecision(range); |
287 | |
|
288 | 0 | word32 value; |
289 | |
|
290 | 0 | do |
291 | 0 | { |
292 | 0 | GenerateBlock((byte *)&value, sizeof(value)); |
293 | 0 | value = Crop(value, maxBits); |
294 | 0 | } while (value > range); |
295 | |
|
296 | 0 | return value+min; |
297 | 0 | } |
298 | | |
299 | | // Stack recursion below... GenerateIntoBufferedTransformation calls GenerateBlock, |
300 | | // and GenerateBlock calls GenerateIntoBufferedTransformation. Ad infinitum. Also |
301 | | // see http://github.com/weidai11/cryptopp/issues/38. |
302 | | // |
303 | | // According to Wei, RandomNumberGenerator is an interface, and it should not |
304 | | // be instantiable. Its now spilt milk, and we are going to CRYPTOPP_ASSERT it in Debug |
305 | | // builds to alert the programmer and throw in Release builds. Developers have |
306 | | // a reference implementation in case its needed. If a programmer |
307 | | // unintentionally lands here, then they should ensure use of a |
308 | | // RandomNumberGenerator pointer or reference so polymorphism can provide the |
309 | | // proper runtime dispatching. |
310 | | |
311 | | void RandomNumberGenerator::GenerateBlock(byte *output, size_t size) |
312 | 0 | { |
313 | 0 | CRYPTOPP_UNUSED(output), CRYPTOPP_UNUSED(size); |
314 | |
|
315 | 0 | ArraySink s(output, size); |
316 | 0 | GenerateIntoBufferedTransformation(s, DEFAULT_CHANNEL, size); |
317 | 0 | } |
318 | | |
319 | | void RandomNumberGenerator::DiscardBytes(size_t n) |
320 | 0 | { |
321 | 0 | GenerateIntoBufferedTransformation(TheBitBucket(), DEFAULT_CHANNEL, n); |
322 | 0 | } |
323 | | |
324 | | void RandomNumberGenerator::GenerateIntoBufferedTransformation(BufferedTransformation &target, const std::string &channel, lword length) |
325 | 0 | { |
326 | 0 | FixedSizeSecBlock<byte, 256> buffer; |
327 | 0 | while (length) |
328 | 0 | { |
329 | 0 | size_t len = UnsignedMin(buffer.size(), length); |
330 | 0 | GenerateBlock(buffer, len); |
331 | 0 | (void)target.ChannelPut(channel, buffer, len); |
332 | 0 | length -= len; |
333 | 0 | } |
334 | 0 | } |
335 | | |
336 | | size_t KeyDerivationFunction::MinDerivedKeyLength() const |
337 | 0 | { |
338 | 0 | return 0; |
339 | 0 | } |
340 | | |
341 | | size_t KeyDerivationFunction::MaxDerivedKeyLength() const |
342 | 0 | { |
343 | 0 | return static_cast<size_t>(-1); |
344 | 0 | } |
345 | | |
346 | | void KeyDerivationFunction::ThrowIfInvalidDerivedKeyLength(size_t length) const |
347 | 5.55k | { |
348 | 5.55k | if (!IsValidDerivedLength(length)) |
349 | 205 | throw InvalidDerivedKeyLength(GetAlgorithm().AlgorithmName(), length); |
350 | 5.55k | } |
351 | | |
352 | 0 | void KeyDerivationFunction::SetParameters(const NameValuePairs& params) { |
353 | 0 | CRYPTOPP_UNUSED(params); |
354 | 0 | } |
355 | | |
356 | | /// \brief Random Number Generator that does not produce random numbers |
357 | | /// \details ClassNullRNG can be used for functions that require a RandomNumberGenerator |
358 | | /// but don't actually use it. The class throws NotImplemented when a generation function is called. |
359 | | /// \sa NullRNG() |
360 | | class ClassNullRNG : public RandomNumberGenerator |
361 | | { |
362 | | public: |
363 | | /// \brief The name of the generator |
364 | | /// \returns the string \a NullRNGs |
365 | 0 | std::string AlgorithmName() const {return "NullRNG";} |
366 | | |
367 | | #if defined(CRYPTOPP_DOXYGEN_PROCESSING) |
368 | | /// \brief An implementation that throws NotImplemented |
369 | | byte GenerateByte () {} |
370 | | /// \brief An implementation that throws NotImplemented |
371 | | unsigned int GenerateBit () {} |
372 | | /// \brief An implementation that throws NotImplemented |
373 | | word32 GenerateWord32 (word32 min, word32 max) {} |
374 | | #endif |
375 | | |
376 | | /// \brief An implementation that throws NotImplemented |
377 | | void GenerateBlock(byte *output, size_t size) |
378 | 0 | { |
379 | 0 | CRYPTOPP_UNUSED(output); CRYPTOPP_UNUSED(size); |
380 | 0 | throw NotImplemented("NullRNG: NullRNG should only be passed to functions that don't need to generate random bytes"); |
381 | 0 | } |
382 | | |
383 | | #if defined(CRYPTOPP_DOXYGEN_PROCESSING) |
384 | | /// \brief An implementation that throws NotImplemented |
385 | | void GenerateIntoBufferedTransformation (BufferedTransformation &target, const std::string &channel, lword length) {} |
386 | | /// \brief An implementation that throws NotImplemented |
387 | | void IncorporateEntropy (const byte *input, size_t length) {} |
388 | | /// \brief An implementation that returns \p false |
389 | | bool CanIncorporateEntropy () const {} |
390 | | /// \brief An implementation that does nothing |
391 | | void DiscardBytes (size_t n) {} |
392 | | /// \brief An implementation that does nothing |
393 | | void Shuffle (IT begin, IT end) {} |
394 | | |
395 | | private: |
396 | | Clonable* Clone () const { return NULLPTR; } |
397 | | #endif |
398 | | }; |
399 | | |
400 | | RandomNumberGenerator & NullRNG() |
401 | 0 | { |
402 | 0 | static ClassNullRNG s_nullRNG; |
403 | 0 | return s_nullRNG; |
404 | 0 | } |
405 | | |
406 | | bool HashTransformation::TruncatedVerify(const byte *digest, size_t digestLength) |
407 | 38 | { |
408 | | // Allocate at least 1 for calculated to avoid triggering diagnostics |
409 | 38 | ThrowIfInvalidTruncatedSize(digestLength); |
410 | 38 | SecByteBlock calculated(digestLength ? digestLength : 1); |
411 | 38 | TruncatedFinal(calculated, digestLength); |
412 | 38 | return VerifyBufsEqual(calculated, digest, digestLength); |
413 | 38 | } |
414 | | |
415 | | void HashTransformation::ThrowIfInvalidTruncatedSize(size_t size) const |
416 | 553k | { |
417 | 553k | if (size > DigestSize()) |
418 | 41 | throw InvalidArgument("HashTransformation: can't truncate a " + IntToString(DigestSize()) + " byte digest to " + IntToString(size) + " bytes"); |
419 | 553k | } |
420 | | |
421 | | unsigned int BufferedTransformation::GetMaxWaitObjectCount() const |
422 | 0 | { |
423 | 0 | const BufferedTransformation *t = AttachedTransformation(); |
424 | 0 | return t ? t->GetMaxWaitObjectCount() : 0; |
425 | 0 | } |
426 | | |
427 | | void BufferedTransformation::GetWaitObjects(WaitObjectContainer &container, CallStack const& callStack) |
428 | 0 | { |
429 | 0 | BufferedTransformation *t = AttachedTransformation(); |
430 | 0 | if (t) |
431 | 0 | t->GetWaitObjects(container, callStack); // reduce clutter by not adding to stack here |
432 | 0 | } |
433 | | |
434 | | void BufferedTransformation::Initialize(const NameValuePairs ¶meters, int propagation) |
435 | 412k | { |
436 | 412k | CRYPTOPP_UNUSED(propagation); |
437 | 412k | CRYPTOPP_ASSERT(!AttachedTransformation()); |
438 | 412k | IsolatedInitialize(parameters); |
439 | 412k | } |
440 | | |
441 | | bool BufferedTransformation::Flush(bool hardFlush, int propagation, bool blocking) |
442 | 0 | { |
443 | 0 | CRYPTOPP_UNUSED(propagation); |
444 | 0 | CRYPTOPP_ASSERT(!AttachedTransformation()); |
445 | 0 | return IsolatedFlush(hardFlush, blocking); |
446 | 0 | } |
447 | | |
448 | | bool BufferedTransformation::MessageSeriesEnd(int propagation, bool blocking) |
449 | 0 | { |
450 | 0 | CRYPTOPP_UNUSED(propagation); |
451 | 0 | CRYPTOPP_ASSERT(!AttachedTransformation()); |
452 | 0 | return IsolatedMessageSeriesEnd(blocking); |
453 | 0 | } |
454 | | |
455 | | byte * BufferedTransformation::ChannelCreatePutSpace(const std::string &channel, size_t &size) |
456 | 630 | { |
457 | 630 | byte* space = NULLPTR; |
458 | 630 | if (channel.empty()) |
459 | 630 | space = CreatePutSpace(size); |
460 | 0 | else |
461 | 0 | throw NoChannelSupport(AlgorithmName()); |
462 | 630 | return space; |
463 | 630 | } |
464 | | |
465 | | size_t BufferedTransformation::ChannelPut2(const std::string &channel, const byte *inString, size_t length, int messageEnd, bool blocking) |
466 | 301M | { |
467 | 301M | size_t size = 0; |
468 | 301M | if (channel.empty()) |
469 | 301M | size = Put2(inString, length, messageEnd, blocking); |
470 | 0 | else |
471 | 0 | throw NoChannelSupport(AlgorithmName()); |
472 | 301M | return size; |
473 | 301M | } |
474 | | |
475 | | size_t BufferedTransformation::ChannelPutModifiable2(const std::string &channel, byte *inString, size_t length, int messageEnd, bool blocking) |
476 | 4.91M | { |
477 | 4.91M | size_t size = 0; |
478 | 4.91M | if (channel.empty()) |
479 | 4.91M | size = PutModifiable2(inString, length, messageEnd, blocking); |
480 | 0 | else |
481 | 0 | size = ChannelPut2(channel, inString, length, messageEnd, blocking); |
482 | 4.91M | return size; |
483 | 4.91M | } |
484 | | |
485 | | bool BufferedTransformation::ChannelFlush(const std::string &channel, bool hardFlush, int propagation, bool blocking) |
486 | 0 | { |
487 | 0 | bool result = 0; |
488 | 0 | if (channel.empty()) |
489 | 0 | result = Flush(hardFlush, propagation, blocking); |
490 | 0 | else |
491 | 0 | throw NoChannelSupport(AlgorithmName()); |
492 | 0 | return result; |
493 | 0 | } |
494 | | |
495 | | bool BufferedTransformation::ChannelMessageSeriesEnd(const std::string &channel, int propagation, bool blocking) |
496 | 0 | { |
497 | 0 | bool result = false; |
498 | 0 | if (channel.empty()) |
499 | 0 | result = MessageSeriesEnd(propagation, blocking); |
500 | 0 | else |
501 | 0 | throw NoChannelSupport(AlgorithmName()); |
502 | 0 | return result; |
503 | 0 | } |
504 | | |
505 | | lword BufferedTransformation::MaxRetrievable() const |
506 | 5.55M | { |
507 | 5.55M | lword size = 0; |
508 | 5.55M | if (AttachedTransformation()) |
509 | 598k | size = AttachedTransformation()->MaxRetrievable(); |
510 | 4.95M | else |
511 | 4.95M | size = CopyTo(TheBitBucket()); |
512 | 5.55M | return size; |
513 | 5.55M | } |
514 | | |
515 | | bool BufferedTransformation::AnyRetrievable() const |
516 | 407k | { |
517 | 407k | bool result = false; |
518 | 407k | if (AttachedTransformation()) |
519 | 0 | result = AttachedTransformation()->AnyRetrievable(); |
520 | 407k | else |
521 | 407k | { |
522 | 407k | byte b; |
523 | 407k | result = Peek(b) != 0; |
524 | 407k | } |
525 | 407k | return result; |
526 | 407k | } |
527 | | |
528 | | size_t BufferedTransformation::Get(byte &outByte) |
529 | 298M | { |
530 | 298M | size_t size = 0; |
531 | 298M | if (AttachedTransformation()) |
532 | 9.31M | size = AttachedTransformation()->Get(outByte); |
533 | 289M | else |
534 | 289M | size = Get(&outByte, 1); |
535 | 298M | return size; |
536 | 298M | } |
537 | | |
538 | | size_t BufferedTransformation::Get(byte *outString, size_t getMax) |
539 | 289M | { |
540 | 289M | size_t size = 0; |
541 | 289M | if (AttachedTransformation()) |
542 | 479 | size = AttachedTransformation()->Get(outString, getMax); |
543 | 289M | else |
544 | 289M | { |
545 | 289M | ArraySink arraySink(outString, getMax); |
546 | 289M | size = (size_t)TransferTo(arraySink, getMax); |
547 | 289M | } |
548 | 289M | return size; |
549 | 289M | } |
550 | | |
551 | | size_t BufferedTransformation::Peek(byte &outByte) const |
552 | 6.51M | { |
553 | 6.51M | size_t size = 0; |
554 | 6.51M | if (AttachedTransformation()) |
555 | 835k | size = AttachedTransformation()->Peek(outByte); |
556 | 5.67M | else |
557 | 5.67M | size = Peek(&outByte, 1); |
558 | 6.51M | return size; |
559 | 6.51M | } |
560 | | |
561 | | size_t BufferedTransformation::Peek(byte *outString, size_t peekMax) const |
562 | 5.67M | { |
563 | 5.67M | size_t size = 0; |
564 | 5.67M | if (AttachedTransformation()) |
565 | 0 | size = AttachedTransformation()->Peek(outString, peekMax); |
566 | 5.67M | else |
567 | 5.67M | { |
568 | 5.67M | ArraySink arraySink(outString, peekMax); |
569 | 5.67M | size = (size_t)CopyTo(arraySink, peekMax); |
570 | 5.67M | } |
571 | 5.67M | return size; |
572 | 5.67M | } |
573 | | |
574 | | lword BufferedTransformation::Skip(lword skipMax) |
575 | 1.20M | { |
576 | 1.20M | lword size = 0; |
577 | 1.20M | if (AttachedTransformation()) |
578 | 509k | size = AttachedTransformation()->Skip(skipMax); |
579 | 695k | else |
580 | 695k | size = TransferTo(TheBitBucket(), skipMax); |
581 | 1.20M | return size; |
582 | 1.20M | } |
583 | | |
584 | | lword BufferedTransformation::TotalBytesRetrievable() const |
585 | 0 | { |
586 | 0 | lword size = 0; |
587 | 0 | if (AttachedTransformation()) |
588 | 0 | size = AttachedTransformation()->TotalBytesRetrievable(); |
589 | 0 | else |
590 | 0 | size = MaxRetrievable(); |
591 | 0 | return size; |
592 | 0 | } |
593 | | |
594 | | unsigned int BufferedTransformation::NumberOfMessages() const |
595 | 0 | { |
596 | 0 | unsigned int size = 0; |
597 | 0 | if (AttachedTransformation()) |
598 | 0 | size = AttachedTransformation()->NumberOfMessages(); |
599 | 0 | else |
600 | 0 | size = CopyMessagesTo(TheBitBucket()); |
601 | 0 | return size; |
602 | 0 | } |
603 | | |
604 | | bool BufferedTransformation::AnyMessages() const |
605 | 407k | { |
606 | 407k | bool result = false; |
607 | 407k | if (AttachedTransformation()) |
608 | 0 | result = AttachedTransformation()->AnyMessages(); |
609 | 407k | else |
610 | 407k | result = NumberOfMessages() != 0; |
611 | 407k | return result; |
612 | 407k | } |
613 | | |
614 | | bool BufferedTransformation::GetNextMessage() |
615 | 0 | { |
616 | 0 | bool result = false; |
617 | 0 | if (AttachedTransformation()) |
618 | 0 | result = AttachedTransformation()->GetNextMessage(); |
619 | 0 | else |
620 | 0 | { |
621 | 0 | CRYPTOPP_ASSERT(!AnyMessages()); |
622 | 0 | } |
623 | 0 | return result; |
624 | 0 | } |
625 | | |
626 | | unsigned int BufferedTransformation::SkipMessages(unsigned int count) |
627 | 0 | { |
628 | 0 | unsigned int size = 0; |
629 | 0 | if (AttachedTransformation()) |
630 | 0 | size = AttachedTransformation()->SkipMessages(count); |
631 | 0 | else |
632 | 0 | size = TransferMessagesTo(TheBitBucket(), count); |
633 | 0 | return size; |
634 | 0 | } |
635 | | |
636 | | size_t BufferedTransformation::TransferMessagesTo2(BufferedTransformation &target, unsigned int &messageCount, const std::string &channel, bool blocking) |
637 | 271k | { |
638 | 271k | if (AttachedTransformation()) |
639 | 0 | return AttachedTransformation()->TransferMessagesTo2(target, messageCount, channel, blocking); |
640 | 271k | else |
641 | 271k | { |
642 | 271k | unsigned int maxMessages = messageCount; |
643 | 407k | for (messageCount=0; messageCount < maxMessages && AnyMessages(); messageCount++) |
644 | 135k | { |
645 | 135k | size_t blockedBytes; |
646 | 135k | lword transferredBytes; |
647 | | |
648 | 271k | while (AnyRetrievable()) |
649 | 135k | { |
650 | | // MaxRetrievable() instead of LWORD_MAX due to GH #962. If |
651 | | // the target calls CreatePutSpace(), then the allocation |
652 | | // size will be LWORD_MAX. That happens when target is a |
653 | | // ByteQueue. Maybe ByteQueue should check the size, and if |
654 | | // it is LWORD_MAX or -1, then use a default like 4096. |
655 | 135k | transferredBytes = MaxRetrievable(); |
656 | 135k | blockedBytes = TransferTo2(target, transferredBytes, channel, blocking); |
657 | 135k | if (blockedBytes > 0) |
658 | 0 | return blockedBytes; |
659 | 135k | } |
660 | | |
661 | 135k | if (target.ChannelMessageEnd(channel, GetAutoSignalPropagation(), blocking)) |
662 | 0 | return 1; |
663 | | |
664 | 135k | bool result = GetNextMessage(); |
665 | 135k | CRYPTOPP_UNUSED(result); CRYPTOPP_ASSERT(result); |
666 | 135k | } |
667 | 271k | return 0; |
668 | 271k | } |
669 | 271k | } |
670 | | |
671 | | unsigned int BufferedTransformation::CopyMessagesTo(BufferedTransformation &target, unsigned int count, const std::string &channel) const |
672 | 0 | { |
673 | 0 | unsigned int size = 0; |
674 | 0 | if (AttachedTransformation()) |
675 | 0 | size = AttachedTransformation()->CopyMessagesTo(target, count, channel); |
676 | 0 | return size; |
677 | 0 | } |
678 | | |
679 | | void BufferedTransformation::SkipAll() |
680 | 0 | { |
681 | 0 | if (AttachedTransformation()) |
682 | 0 | AttachedTransformation()->SkipAll(); |
683 | 0 | else |
684 | 0 | { |
685 | 0 | while (SkipMessages()) {} |
686 | 0 | while (Skip()) {} |
687 | 0 | } |
688 | 0 | } |
689 | | |
690 | | size_t BufferedTransformation::TransferAllTo2(BufferedTransformation &target, const std::string &channel, bool blocking) |
691 | 135k | { |
692 | 135k | if (AttachedTransformation()) |
693 | 0 | return AttachedTransformation()->TransferAllTo2(target, channel, blocking); |
694 | 135k | else |
695 | 135k | { |
696 | 135k | CRYPTOPP_ASSERT(!NumberOfMessageSeries()); |
697 | | |
698 | 135k | unsigned int messageCount; |
699 | 135k | do |
700 | 271k | { |
701 | 271k | messageCount = UINT_MAX; |
702 | 271k | size_t blockedBytes = TransferMessagesTo2(target, messageCount, channel, blocking); |
703 | 271k | if (blockedBytes) |
704 | 0 | return blockedBytes; |
705 | 271k | } |
706 | 271k | while (messageCount != 0); |
707 | | |
708 | 135k | lword byteCount; |
709 | 135k | do |
710 | 135k | { |
711 | 135k | byteCount = ULONG_MAX; |
712 | 135k | size_t blockedBytes = TransferTo2(target, byteCount, channel, blocking); |
713 | 135k | if (blockedBytes) |
714 | 0 | return blockedBytes; |
715 | 135k | } |
716 | 135k | while (byteCount != 0); |
717 | | |
718 | 135k | return 0; |
719 | 135k | } |
720 | 135k | } |
721 | | |
722 | | void BufferedTransformation::CopyAllTo(BufferedTransformation &target, const std::string &channel) const |
723 | 0 | { |
724 | 0 | if (AttachedTransformation()) |
725 | 0 | AttachedTransformation()->CopyAllTo(target, channel); |
726 | 0 | else |
727 | 0 | { |
728 | 0 | CRYPTOPP_ASSERT(!NumberOfMessageSeries()); |
729 | 0 | while (CopyMessagesTo(target, UINT_MAX, channel)) {} |
730 | 0 | } |
731 | 0 | } |
732 | | |
733 | | void BufferedTransformation::SetRetrievalChannel(const std::string &channel) |
734 | 30 | { |
735 | 30 | if (AttachedTransformation()) |
736 | 15 | AttachedTransformation()->SetRetrievalChannel(channel); |
737 | 30 | } |
738 | | |
739 | | size_t BufferedTransformation::ChannelPutWord16(const std::string &channel, word16 value, ByteOrder order, bool blocking) |
740 | 0 | { |
741 | 0 | PutWord(false, order, m_buf, value); |
742 | 0 | return ChannelPut(channel, m_buf, 2, blocking); |
743 | 0 | } |
744 | | |
745 | | size_t BufferedTransformation::ChannelPutWord32(const std::string &channel, word32 value, ByteOrder order, bool blocking) |
746 | 0 | { |
747 | 0 | PutWord(false, order, m_buf, value); |
748 | 0 | return ChannelPut(channel, m_buf, 4, blocking); |
749 | 0 | } |
750 | | |
751 | | size_t BufferedTransformation::ChannelPutWord64(const std::string &channel, word64 value, ByteOrder order, bool blocking) |
752 | 0 | { |
753 | 0 | PutWord(false, order, m_buf, value); |
754 | 0 | return ChannelPut(channel, m_buf, 8, blocking); |
755 | 0 | } |
756 | | |
757 | | size_t BufferedTransformation::PutWord16(word16 value, ByteOrder order, bool blocking) |
758 | 0 | { |
759 | 0 | return ChannelPutWord16(DEFAULT_CHANNEL, value, order, blocking); |
760 | 0 | } |
761 | | |
762 | | size_t BufferedTransformation::PutWord32(word32 value, ByteOrder order, bool blocking) |
763 | 0 | { |
764 | 0 | return ChannelPutWord32(DEFAULT_CHANNEL, value, order, blocking); |
765 | 0 | } |
766 | | |
767 | | size_t BufferedTransformation::PutWord64(word64 value, ByteOrder order, bool blocking) |
768 | 0 | { |
769 | 0 | return ChannelPutWord64(DEFAULT_CHANNEL, value, order, blocking); |
770 | 0 | } |
771 | | |
772 | | size_t BufferedTransformation::PeekWord16(word16 &value, ByteOrder order) const |
773 | 0 | { |
774 | 0 | byte buf[2] = {0, 0}; |
775 | 0 | size_t len = Peek(buf, 2); |
776 | |
|
777 | 0 | if (order == BIG_ENDIAN_ORDER) |
778 | 0 | value = word16((buf[0] << 8) | buf[1]); |
779 | 0 | else |
780 | 0 | value = word16((buf[1] << 8) | buf[0]); |
781 | |
|
782 | 0 | return len; |
783 | 0 | } |
784 | | |
785 | | size_t BufferedTransformation::PeekWord32(word32 &value, ByteOrder order) const |
786 | 0 | { |
787 | 0 | byte buf[4] = {0, 0, 0, 0}; |
788 | 0 | size_t len = Peek(buf, 4); |
789 | |
|
790 | 0 | if (order == BIG_ENDIAN_ORDER) |
791 | 0 | value = word32((buf[0] << 24) | (buf[1] << 16) | |
792 | 0 | (buf[2] << 8) | (buf[3] << 0)); |
793 | 0 | else |
794 | 0 | value = word32((buf[3] << 24) | (buf[2] << 16) | |
795 | 0 | (buf[1] << 8) | (buf[0] << 0)); |
796 | |
|
797 | 0 | return len; |
798 | 0 | } |
799 | | |
800 | | size_t BufferedTransformation::PeekWord64(word64 &value, ByteOrder order) const |
801 | 0 | { |
802 | 0 | byte buf[8] = {0, 0, 0, 0, 0, 0, 0, 0}; |
803 | 0 | size_t len = Peek(buf, 8); |
804 | |
|
805 | 0 | if (order == BIG_ENDIAN_ORDER) |
806 | 0 | value = ((word64)buf[0] << 56) | ((word64)buf[1] << 48) | ((word64)buf[2] << 40) | |
807 | 0 | ((word64)buf[3] << 32) | ((word64)buf[4] << 24) | ((word64)buf[5] << 16) | |
808 | 0 | ((word64)buf[6] << 8) | (word64)buf[7]; |
809 | 0 | else |
810 | 0 | value = ((word64)buf[7] << 56) | ((word64)buf[6] << 48) | ((word64)buf[5] << 40) | |
811 | 0 | ((word64)buf[4] << 32) | ((word64)buf[3] << 24) | ((word64)buf[2] << 16) | |
812 | 0 | ((word64)buf[1] << 8) | (word64)buf[0]; |
813 | |
|
814 | 0 | return len; |
815 | 0 | } |
816 | | |
817 | | size_t BufferedTransformation::GetWord16(word16 &value, ByteOrder order) |
818 | 0 | { |
819 | 0 | return (size_t)Skip(PeekWord16(value, order)); |
820 | 0 | } |
821 | | |
822 | | size_t BufferedTransformation::GetWord32(word32 &value, ByteOrder order) |
823 | 0 | { |
824 | 0 | return (size_t)Skip(PeekWord32(value, order)); |
825 | 0 | } |
826 | | |
827 | | size_t BufferedTransformation::GetWord64(word64 &value, ByteOrder order) |
828 | 0 | { |
829 | 0 | return (size_t)Skip(PeekWord64(value, order)); |
830 | 0 | } |
831 | | |
832 | | void BufferedTransformation::Attach(BufferedTransformation *newAttachment) |
833 | 0 | { |
834 | 0 | if (AttachedTransformation() && AttachedTransformation()->Attachable()) |
835 | 0 | AttachedTransformation()->Attach(newAttachment); |
836 | 0 | else |
837 | 0 | Detach(newAttachment); |
838 | 0 | } |
839 | | |
840 | | void GeneratableCryptoMaterial::GenerateRandomWithKeySize(RandomNumberGenerator &rng, unsigned int keySize) |
841 | 0 | { |
842 | 0 | GenerateRandom(rng, MakeParameters("KeySize", (int)keySize)); |
843 | 0 | } |
844 | | |
845 | | class PK_DefaultEncryptionFilter : public Unflushable<Filter> |
846 | | { |
847 | | public: |
848 | | PK_DefaultEncryptionFilter(RandomNumberGenerator &rng, const PK_Encryptor &encryptor, BufferedTransformation *attachment, const NameValuePairs ¶meters) |
849 | | : m_rng(rng), m_encryptor(encryptor), m_parameters(parameters) |
850 | 0 | { |
851 | 0 | Detach(attachment); |
852 | 0 | } |
853 | | |
854 | | size_t Put2(const byte *inString, size_t length, int messageEnd, bool blocking) |
855 | 0 | { |
856 | 0 | FILTER_BEGIN; |
857 | 0 | m_plaintextQueue.Put(inString, length); |
858 | |
|
859 | 0 | if (messageEnd) |
860 | 0 | { |
861 | 0 | { |
862 | 0 | size_t plaintextLength; |
863 | 0 | if (!SafeConvert(m_plaintextQueue.CurrentSize(), plaintextLength)) |
864 | 0 | throw InvalidArgument("PK_DefaultEncryptionFilter: plaintext too long"); |
865 | 0 | size_t ciphertextLength = m_encryptor.CiphertextLength(plaintextLength); |
866 | |
|
867 | 0 | SecByteBlock plaintext(plaintextLength); |
868 | 0 | m_plaintextQueue.Get(plaintext, plaintextLength); |
869 | 0 | m_ciphertext.resize(ciphertextLength); |
870 | 0 | m_encryptor.Encrypt(m_rng, plaintext, plaintextLength, m_ciphertext, m_parameters); |
871 | 0 | } |
872 | | |
873 | 0 | FILTER_OUTPUT(1, m_ciphertext, m_ciphertext.size(), messageEnd); |
874 | 0 | } |
875 | 0 | FILTER_END_NO_MESSAGE_END; |
876 | 0 | } |
877 | | |
878 | | RandomNumberGenerator &m_rng; |
879 | | const PK_Encryptor &m_encryptor; |
880 | | const NameValuePairs &m_parameters; |
881 | | ByteQueue m_plaintextQueue; |
882 | | SecByteBlock m_ciphertext; |
883 | | }; |
884 | | |
885 | | BufferedTransformation * PK_Encryptor::CreateEncryptionFilter(RandomNumberGenerator &rng, BufferedTransformation *attachment, const NameValuePairs ¶meters) const |
886 | 0 | { |
887 | 0 | return new PK_DefaultEncryptionFilter(rng, *this, attachment, parameters); |
888 | 0 | } |
889 | | |
890 | | class PK_DefaultDecryptionFilter : public Unflushable<Filter> |
891 | | { |
892 | | public: |
893 | | PK_DefaultDecryptionFilter(RandomNumberGenerator &rng, const PK_Decryptor &decryptor, BufferedTransformation *attachment, const NameValuePairs ¶meters) |
894 | | : m_rng(rng), m_decryptor(decryptor), m_parameters(parameters) |
895 | 0 | { |
896 | 0 | Detach(attachment); |
897 | 0 | } |
898 | | |
899 | | size_t Put2(const byte *inString, size_t length, int messageEnd, bool blocking) |
900 | 0 | { |
901 | 0 | FILTER_BEGIN; |
902 | 0 | m_ciphertextQueue.Put(inString, length); |
903 | |
|
904 | 0 | if (messageEnd) |
905 | 0 | { |
906 | 0 | { |
907 | 0 | size_t ciphertextLength; |
908 | 0 | if (!SafeConvert(m_ciphertextQueue.CurrentSize(), ciphertextLength)) |
909 | 0 | throw InvalidArgument("PK_DefaultDecryptionFilter: ciphertext too long"); |
910 | 0 | size_t maxPlaintextLength = m_decryptor.MaxPlaintextLength(ciphertextLength); |
911 | |
|
912 | 0 | SecByteBlock ciphertext(ciphertextLength); |
913 | 0 | m_ciphertextQueue.Get(ciphertext, ciphertextLength); |
914 | 0 | m_plaintext.resize(maxPlaintextLength); |
915 | 0 | m_result = m_decryptor.Decrypt(m_rng, ciphertext, ciphertextLength, m_plaintext, m_parameters); |
916 | 0 | if (!m_result.isValidCoding) |
917 | 0 | throw InvalidCiphertext(m_decryptor.AlgorithmName() + ": invalid ciphertext"); |
918 | 0 | } |
919 | | |
920 | 0 | FILTER_OUTPUT(1, m_plaintext, m_result.messageLength, messageEnd); |
921 | 0 | } |
922 | 0 | FILTER_END_NO_MESSAGE_END; |
923 | 0 | } |
924 | | |
925 | | RandomNumberGenerator &m_rng; |
926 | | const PK_Decryptor &m_decryptor; |
927 | | const NameValuePairs &m_parameters; |
928 | | ByteQueue m_ciphertextQueue; |
929 | | SecByteBlock m_plaintext; |
930 | | DecodingResult m_result; |
931 | | }; |
932 | | |
933 | | BufferedTransformation * PK_Decryptor::CreateDecryptionFilter(RandomNumberGenerator &rng, BufferedTransformation *attachment, const NameValuePairs ¶meters) const |
934 | 0 | { |
935 | 0 | return new PK_DefaultDecryptionFilter(rng, *this, attachment, parameters); |
936 | 0 | } |
937 | | |
938 | | size_t PK_Signer::Sign(RandomNumberGenerator &rng, PK_MessageAccumulator *messageAccumulator, byte *signature) const |
939 | 0 | { |
940 | 0 | member_ptr<PK_MessageAccumulator> m(messageAccumulator); |
941 | 0 | return SignAndRestart(rng, *m, signature, false); |
942 | 0 | } |
943 | | |
944 | | size_t PK_Signer::SignMessage(RandomNumberGenerator &rng, const byte *message, size_t messageLen, byte *signature) const |
945 | 0 | { |
946 | 0 | member_ptr<PK_MessageAccumulator> m(NewSignatureAccumulator(rng)); |
947 | 0 | m->Update(message, messageLen); |
948 | 0 | return SignAndRestart(rng, *m, signature, false); |
949 | 0 | } |
950 | | |
951 | | size_t PK_Signer::SignMessageWithRecovery(RandomNumberGenerator &rng, const byte *recoverableMessage, size_t recoverableMessageLength, |
952 | | const byte *nonrecoverableMessage, size_t nonrecoverableMessageLength, byte *signature) const |
953 | 0 | { |
954 | 0 | member_ptr<PK_MessageAccumulator> m(NewSignatureAccumulator(rng)); |
955 | 0 | InputRecoverableMessage(*m, recoverableMessage, recoverableMessageLength); |
956 | 0 | m->Update(nonrecoverableMessage, nonrecoverableMessageLength); |
957 | 0 | return SignAndRestart(rng, *m, signature, false); |
958 | 0 | } |
959 | | |
960 | | bool PK_Verifier::Verify(PK_MessageAccumulator *messageAccumulator) const |
961 | 0 | { |
962 | 0 | member_ptr<PK_MessageAccumulator> m(messageAccumulator); |
963 | 0 | return VerifyAndRestart(*m); |
964 | 0 | } |
965 | | |
966 | | bool PK_Verifier::VerifyMessage(const byte *message, size_t messageLen, const byte *signature, size_t signatureLen) const |
967 | 0 | { |
968 | 0 | member_ptr<PK_MessageAccumulator> m(NewVerificationAccumulator()); |
969 | 0 | InputSignature(*m, signature, signatureLen); |
970 | 0 | m->Update(message, messageLen); |
971 | 0 | return VerifyAndRestart(*m); |
972 | 0 | } |
973 | | |
974 | | DecodingResult PK_Verifier::Recover(byte *recoveredMessage, PK_MessageAccumulator *messageAccumulator) const |
975 | 0 | { |
976 | 0 | member_ptr<PK_MessageAccumulator> m(messageAccumulator); |
977 | 0 | return RecoverAndRestart(recoveredMessage, *m); |
978 | 0 | } |
979 | | |
980 | | DecodingResult PK_Verifier::RecoverMessage(byte *recoveredMessage, |
981 | | const byte *nonrecoverableMessage, size_t nonrecoverableMessageLength, |
982 | | const byte *signature, size_t signatureLength) const |
983 | 0 | { |
984 | 0 | member_ptr<PK_MessageAccumulator> m(NewVerificationAccumulator()); |
985 | 0 | InputSignature(*m, signature, signatureLength); |
986 | 0 | m->Update(nonrecoverableMessage, nonrecoverableMessageLength); |
987 | 0 | return RecoverAndRestart(recoveredMessage, *m); |
988 | 0 | } |
989 | | |
990 | | void SimpleKeyAgreementDomain::GenerateKeyPair(RandomNumberGenerator &rng, byte *privateKey, byte *publicKey) const |
991 | 0 | { |
992 | 0 | GeneratePrivateKey(rng, privateKey); |
993 | 0 | GeneratePublicKey(rng, privateKey, publicKey); |
994 | 0 | } |
995 | | |
996 | | void AuthenticatedKeyAgreementDomain::GenerateStaticKeyPair(RandomNumberGenerator &rng, byte *privateKey, byte *publicKey) const |
997 | 0 | { |
998 | 0 | GenerateStaticPrivateKey(rng, privateKey); |
999 | 0 | GenerateStaticPublicKey(rng, privateKey, publicKey); |
1000 | 0 | } |
1001 | | |
1002 | | void AuthenticatedKeyAgreementDomain::GenerateEphemeralKeyPair(RandomNumberGenerator &rng, byte *privateKey, byte *publicKey) const |
1003 | 0 | { |
1004 | 0 | GenerateEphemeralPrivateKey(rng, privateKey); |
1005 | 0 | GenerateEphemeralPublicKey(rng, privateKey, publicKey); |
1006 | 0 | } |
1007 | | |
1008 | | // Allow a distro or packager to override the build-time version |
1009 | | // http://github.com/weidai11/cryptopp/issues/371 |
1010 | | #ifndef CRYPTOPP_BUILD_VERSION |
1011 | 0 | # define CRYPTOPP_BUILD_VERSION CRYPTOPP_VERSION |
1012 | | #endif |
1013 | | int LibraryVersion(CRYPTOPP_NOINLINE_DOTDOTDOT) |
1014 | 0 | { |
1015 | 0 | return CRYPTOPP_BUILD_VERSION; |
1016 | 0 | } |
1017 | | |
1018 | | class NullNameValuePairs : public NameValuePairs |
1019 | | { |
1020 | | public: |
1021 | 10 | NullNameValuePairs() {} // Clang complains a default ctor must be available |
1022 | | bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const |
1023 | 326 | {CRYPTOPP_UNUSED(name); CRYPTOPP_UNUSED(valueType); CRYPTOPP_UNUSED(pValue); return false;} |
1024 | | }; |
1025 | | |
1026 | | #if HAVE_GCC_INIT_PRIORITY |
1027 | | const std::string DEFAULT_CHANNEL __attribute__ ((init_priority (CRYPTOPP_INIT_PRIORITY + 25))) = ""; |
1028 | | const std::string AAD_CHANNEL __attribute__ ((init_priority (CRYPTOPP_INIT_PRIORITY + 26))) = "AAD"; |
1029 | | const NullNameValuePairs s_nullNameValuePairs __attribute__ ((init_priority (CRYPTOPP_INIT_PRIORITY + 27))); |
1030 | | const NameValuePairs& g_nullNameValuePairs = s_nullNameValuePairs; |
1031 | | #elif HAVE_MSC_INIT_PRIORITY |
1032 | | #pragma warning(disable: 4073) |
1033 | | #pragma init_seg(lib) |
1034 | | const std::string DEFAULT_CHANNEL = ""; |
1035 | | const std::string AAD_CHANNEL = "AAD"; |
1036 | | const NullNameValuePairs s_nullNameValuePairs; |
1037 | | const NameValuePairs& g_nullNameValuePairs = s_nullNameValuePairs; |
1038 | | #pragma warning(default: 4073) |
1039 | | #elif HAVE_XLC_INIT_PRIORITY |
1040 | | #pragma priority(260) |
1041 | | const std::string DEFAULT_CHANNEL = ""; |
1042 | | const std::string AAD_CHANNEL = "AAD"; |
1043 | | const NullNameValuePairs s_nullNameValuePairs; |
1044 | | const NameValuePairs& g_nullNameValuePairs = s_nullNameValuePairs; |
1045 | | #else |
1046 | | const std::string DEFAULT_CHANNEL = ""; |
1047 | | const std::string AAD_CHANNEL = "AAD"; |
1048 | | const simple_ptr<NullNameValuePairs> s_pNullNameValuePairs(new NullNameValuePairs); |
1049 | | const NameValuePairs &g_nullNameValuePairs = *s_pNullNameValuePairs.m_p; |
1050 | | #endif |
1051 | | |
1052 | | NAMESPACE_END // CryptoPP |
1053 | | |
1054 | | #endif // CRYPTOPP_IMPORTS |