Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
folium-app
GitHub Repository: folium-app/Folium
Path: blob/a-new-beginning/SharedDependencies/Sources/cryptopp/cryptlib.cpp
2 views
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
{
42
static BitBucket bitBucket;
43
return bitBucket;
44
}
45
46
Algorithm::Algorithm(bool checkSelfTestStatus)
47
{
48
if (checkSelfTestStatus && FIPS_140_2_ComplianceEnabled())
49
{
50
if (GetPowerUpSelfTestStatus() == POWER_UP_SELF_TEST_NOT_DONE && !PowerUpSelfTestInProgressOnThisThread())
51
throw SelfTestFailure("Cryptographic algorithms are disabled before the power-up self tests are performed.");
52
53
if (GetPowerUpSelfTestStatus() == POWER_UP_SELF_TEST_FAILED)
54
throw SelfTestFailure("Cryptographic algorithms are disabled after a power-up self test failed.");
55
}
56
}
57
58
void SimpleKeyingInterface::SetKey(const byte *key, size_t length, const NameValuePairs &params)
59
{
60
this->ThrowIfInvalidKeyLength(length);
61
this->UncheckedSetKey(key, static_cast<unsigned int>(length), params);
62
}
63
64
void SimpleKeyingInterface::SetKeyWithRounds(const byte *key, size_t length, int rounds)
65
{
66
SetKey(key, length, MakeParameters(Name::Rounds(), rounds));
67
}
68
69
void SimpleKeyingInterface::SetKeyWithIV(const byte *key, size_t length, const byte *iv, size_t ivLength)
70
{
71
SetKey(key, length, MakeParameters(Name::IV(), ConstByteArrayParameter(iv, ivLength)));
72
}
73
74
void SimpleKeyingInterface::ThrowIfInvalidKeyLength(size_t length)
75
{
76
if (!IsValidKeyLength(length))
77
throw InvalidKeyLength(GetAlgorithm().AlgorithmName(), length);
78
}
79
80
void SimpleKeyingInterface::ThrowIfResynchronizable()
81
{
82
if (IsResynchronizable())
83
throw InvalidArgument(GetAlgorithm().AlgorithmName() + ": this object requires an IV");
84
}
85
86
void SimpleKeyingInterface::ThrowIfInvalidIV(const byte *iv)
87
{
88
if (!iv && IVRequirement() == UNPREDICTABLE_RANDOM_IV)
89
throw InvalidArgument(GetAlgorithm().AlgorithmName() + ": this object cannot use a null IV");
90
}
91
92
size_t SimpleKeyingInterface::ThrowIfInvalidIVLength(int length)
93
{
94
size_t size = 0;
95
if (length < 0)
96
size = static_cast<size_t>(IVSize());
97
else if ((size_t)length < MinIVLength())
98
throw InvalidArgument(GetAlgorithm().AlgorithmName() + ": IV length " + IntToString(length) + " is less than the minimum of " + IntToString(MinIVLength()));
99
else if ((size_t)length > MaxIVLength())
100
throw InvalidArgument(GetAlgorithm().AlgorithmName() + ": IV length " + IntToString(length) + " exceeds the maximum of " + IntToString(MaxIVLength()));
101
else
102
size = static_cast<size_t>(length);
103
104
return size;
105
}
106
107
const byte * SimpleKeyingInterface::GetIVAndThrowIfInvalid(const NameValuePairs &params, size_t &size)
108
{
109
ConstByteArrayParameter ivWithLength;
110
const byte *iv = NULLPTR;
111
bool found = false;
112
113
try {found = params.GetValue(Name::IV(), ivWithLength);}
114
catch (const NameValuePairs::ValueTypeMismatch &) {}
115
116
if (found)
117
{
118
iv = ivWithLength.begin();
119
ThrowIfInvalidIV(iv);
120
size = ThrowIfInvalidIVLength(static_cast<int>(ivWithLength.size()));
121
}
122
else if (params.GetValue(Name::IV(), iv))
123
{
124
ThrowIfInvalidIV(iv);
125
size = static_cast<size_t>(IVSize());
126
}
127
else
128
{
129
ThrowIfResynchronizable();
130
size = 0;
131
}
132
133
return iv;
134
}
135
136
void SimpleKeyingInterface::GetNextIV(RandomNumberGenerator &rng, byte *iv)
137
{
138
rng.GenerateBlock(iv, IVSize());
139
}
140
141
size_t BlockTransformation::AdvancedProcessBlocks(const byte *inBlocks, const byte *xorBlocks, byte *outBlocks, size_t length, word32 flags) const
142
{
143
CRYPTOPP_ASSERT(inBlocks);
144
CRYPTOPP_ASSERT(outBlocks);
145
CRYPTOPP_ASSERT(length);
146
147
const unsigned int blockSize = BlockSize();
148
size_t inIncrement = (flags & (BT_InBlockIsCounter|BT_DontIncrementInOutPointers)) ? 0 : blockSize;
149
size_t xorIncrement = xorBlocks ? blockSize : 0;
150
size_t outIncrement = (flags & BT_DontIncrementInOutPointers) ? 0 : blockSize;
151
152
if (flags & BT_ReverseDirection)
153
{
154
inBlocks = PtrAdd(inBlocks, length - blockSize);
155
xorBlocks = PtrAdd(xorBlocks, length - blockSize);
156
outBlocks = PtrAdd(outBlocks, length - blockSize);
157
inIncrement = 0-inIncrement;
158
xorIncrement = 0-xorIncrement;
159
outIncrement = 0-outIncrement;
160
}
161
162
// Coverity finding.
163
const bool xorFlag = xorBlocks && (flags & BT_XorInput);
164
while (length >= blockSize)
165
{
166
if (xorFlag)
167
{
168
// xorBlocks non-NULL and with BT_XorInput.
169
xorbuf(outBlocks, xorBlocks, inBlocks, blockSize);
170
ProcessBlock(outBlocks);
171
}
172
else
173
{
174
// xorBlocks may be non-NULL and without BT_XorInput.
175
ProcessAndXorBlock(inBlocks, xorBlocks, outBlocks);
176
}
177
178
if (flags & BT_InBlockIsCounter)
179
const_cast<byte *>(inBlocks)[blockSize-1]++;
180
181
inBlocks = PtrAdd(inBlocks, inIncrement);
182
outBlocks = PtrAdd(outBlocks, outIncrement);
183
xorBlocks = PtrAdd(xorBlocks, xorIncrement);
184
length -= blockSize;
185
}
186
187
return length;
188
}
189
190
unsigned int BlockTransformation::OptimalDataAlignment() const
191
{
192
return GetAlignmentOf<word32>();
193
}
194
195
unsigned int StreamTransformation::OptimalDataAlignment() const
196
{
197
return GetAlignmentOf<word32>();
198
}
199
200
unsigned int HashTransformation::OptimalDataAlignment() const
201
{
202
return GetAlignmentOf<word32>();
203
}
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
{
219
// this function should be overridden otherwise
220
CRYPTOPP_ASSERT(MinLastBlockSize() == 0);
221
222
if (inLength == MandatoryBlockSize())
223
{
224
outLength = inLength; // squash unused warning
225
ProcessData(outString, inString, inLength);
226
}
227
else if (inLength != 0)
228
throw NotImplemented(AlgorithmName() + ": this object doesn't support a special last block");
229
230
return outLength;
231
}
232
233
void AuthenticatedSymmetricCipher::SpecifyDataLengths(lword headerLength, lword messageLength, lword footerLength)
234
{
235
if (headerLength > MaxHeaderLength())
236
throw InvalidArgument(GetAlgorithm().AlgorithmName() + ": header length " + IntToString(headerLength) + " exceeds the maximum of " + IntToString(MaxHeaderLength()));
237
238
if (messageLength > MaxMessageLength())
239
throw InvalidArgument(GetAlgorithm().AlgorithmName() + ": message length " + IntToString(messageLength) + " exceeds the maximum of " + IntToString(MaxMessageLength()));
240
241
if (footerLength > MaxFooterLength())
242
throw InvalidArgument(GetAlgorithm().AlgorithmName() + ": footer length " + IntToString(footerLength) + " exceeds the maximum of " + IntToString(MaxFooterLength()));
243
244
UncheckedSpecifyDataLengths(headerLength, messageLength, footerLength);
245
}
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
{
249
Resynchronize(iv, ivLength);
250
SpecifyDataLengths(headerLength, messageLength);
251
Update(header, headerLength);
252
ProcessString(ciphertext, message, messageLength);
253
TruncatedFinal(mac, macSize);
254
}
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
{
258
Resynchronize(iv, ivLength);
259
SpecifyDataLengths(headerLength, ciphertextLength);
260
Update(header, headerLength);
261
ProcessString(message, ciphertext, ciphertextLength);
262
return TruncatedVerify(mac, macLength);
263
}
264
265
std::string AuthenticatedSymmetricCipher::AlgorithmName() const
266
{
267
// Squash C4505 on Visual Studio 2008 and friends
268
return "Unknown";
269
}
270
271
unsigned int RandomNumberGenerator::GenerateBit()
272
{
273
return GenerateByte() & 1;
274
}
275
276
byte RandomNumberGenerator::GenerateByte()
277
{
278
byte b;
279
GenerateBlock(&b, 1);
280
return b;
281
}
282
283
word32 RandomNumberGenerator::GenerateWord32(word32 min, word32 max)
284
{
285
const word32 range = max-min;
286
const unsigned int maxBits = BitPrecision(range);
287
288
word32 value;
289
290
do
291
{
292
GenerateBlock((byte *)&value, sizeof(value));
293
value = Crop(value, maxBits);
294
} while (value > range);
295
296
return value+min;
297
}
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
{
313
CRYPTOPP_UNUSED(output), CRYPTOPP_UNUSED(size);
314
315
ArraySink s(output, size);
316
GenerateIntoBufferedTransformation(s, DEFAULT_CHANNEL, size);
317
}
318
319
void RandomNumberGenerator::DiscardBytes(size_t n)
320
{
321
GenerateIntoBufferedTransformation(TheBitBucket(), DEFAULT_CHANNEL, n);
322
}
323
324
void RandomNumberGenerator::GenerateIntoBufferedTransformation(BufferedTransformation &target, const std::string &channel, lword length)
325
{
326
FixedSizeSecBlock<byte, 256> buffer;
327
while (length)
328
{
329
size_t len = UnsignedMin(buffer.size(), length);
330
GenerateBlock(buffer, len);
331
(void)target.ChannelPut(channel, buffer, len);
332
length -= len;
333
}
334
}
335
336
size_t KeyDerivationFunction::MinDerivedKeyLength() const
337
{
338
return 0;
339
}
340
341
size_t KeyDerivationFunction::MaxDerivedKeyLength() const
342
{
343
return static_cast<size_t>(-1);
344
}
345
346
void KeyDerivationFunction::ThrowIfInvalidDerivedKeyLength(size_t length) const
347
{
348
if (!IsValidDerivedLength(length))
349
throw InvalidDerivedKeyLength(GetAlgorithm().AlgorithmName(), length);
350
}
351
352
void KeyDerivationFunction::SetParameters(const NameValuePairs& params) {
353
CRYPTOPP_UNUSED(params);
354
}
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
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
{
379
CRYPTOPP_UNUSED(output); CRYPTOPP_UNUSED(size);
380
throw NotImplemented("NullRNG: NullRNG should only be passed to functions that don't need to generate random bytes");
381
}
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
{
402
static ClassNullRNG s_nullRNG;
403
return s_nullRNG;
404
}
405
406
bool HashTransformation::TruncatedVerify(const byte *digest, size_t digestLength)
407
{
408
// Allocate at least 1 for calculated to avoid triggering diagnostics
409
ThrowIfInvalidTruncatedSize(digestLength);
410
SecByteBlock calculated(digestLength ? digestLength : 1);
411
TruncatedFinal(calculated, digestLength);
412
return VerifyBufsEqual(calculated, digest, digestLength);
413
}
414
415
void HashTransformation::ThrowIfInvalidTruncatedSize(size_t size) const
416
{
417
if (size > DigestSize())
418
throw InvalidArgument("HashTransformation: can't truncate a " + IntToString(DigestSize()) + " byte digest to " + IntToString(size) + " bytes");
419
}
420
421
unsigned int BufferedTransformation::GetMaxWaitObjectCount() const
422
{
423
const BufferedTransformation *t = AttachedTransformation();
424
return t ? t->GetMaxWaitObjectCount() : 0;
425
}
426
427
void BufferedTransformation::GetWaitObjects(WaitObjectContainer &container, CallStack const& callStack)
428
{
429
BufferedTransformation *t = AttachedTransformation();
430
if (t)
431
t->GetWaitObjects(container, callStack); // reduce clutter by not adding to stack here
432
}
433
434
void BufferedTransformation::Initialize(const NameValuePairs &parameters, int propagation)
435
{
436
CRYPTOPP_UNUSED(propagation);
437
CRYPTOPP_ASSERT(!AttachedTransformation());
438
IsolatedInitialize(parameters);
439
}
440
441
bool BufferedTransformation::Flush(bool hardFlush, int propagation, bool blocking)
442
{
443
CRYPTOPP_UNUSED(propagation);
444
CRYPTOPP_ASSERT(!AttachedTransformation());
445
return IsolatedFlush(hardFlush, blocking);
446
}
447
448
bool BufferedTransformation::MessageSeriesEnd(int propagation, bool blocking)
449
{
450
CRYPTOPP_UNUSED(propagation);
451
CRYPTOPP_ASSERT(!AttachedTransformation());
452
return IsolatedMessageSeriesEnd(blocking);
453
}
454
455
byte * BufferedTransformation::ChannelCreatePutSpace(const std::string &channel, size_t &size)
456
{
457
byte* space = NULLPTR;
458
if (channel.empty())
459
space = CreatePutSpace(size);
460
else
461
throw NoChannelSupport(AlgorithmName());
462
return space;
463
}
464
465
size_t BufferedTransformation::ChannelPut2(const std::string &channel, const byte *inString, size_t length, int messageEnd, bool blocking)
466
{
467
size_t size = 0;
468
if (channel.empty())
469
size = Put2(inString, length, messageEnd, blocking);
470
else
471
throw NoChannelSupport(AlgorithmName());
472
return size;
473
}
474
475
size_t BufferedTransformation::ChannelPutModifiable2(const std::string &channel, byte *inString, size_t length, int messageEnd, bool blocking)
476
{
477
size_t size = 0;
478
if (channel.empty())
479
size = PutModifiable2(inString, length, messageEnd, blocking);
480
else
481
size = ChannelPut2(channel, inString, length, messageEnd, blocking);
482
return size;
483
}
484
485
bool BufferedTransformation::ChannelFlush(const std::string &channel, bool hardFlush, int propagation, bool blocking)
486
{
487
bool result = 0;
488
if (channel.empty())
489
result = Flush(hardFlush, propagation, blocking);
490
else
491
throw NoChannelSupport(AlgorithmName());
492
return result;
493
}
494
495
bool BufferedTransformation::ChannelMessageSeriesEnd(const std::string &channel, int propagation, bool blocking)
496
{
497
bool result = false;
498
if (channel.empty())
499
result = MessageSeriesEnd(propagation, blocking);
500
else
501
throw NoChannelSupport(AlgorithmName());
502
return result;
503
}
504
505
lword BufferedTransformation::MaxRetrievable() const
506
{
507
lword size = 0;
508
if (AttachedTransformation())
509
size = AttachedTransformation()->MaxRetrievable();
510
else
511
size = CopyTo(TheBitBucket());
512
return size;
513
}
514
515
bool BufferedTransformation::AnyRetrievable() const
516
{
517
bool result = false;
518
if (AttachedTransformation())
519
result = AttachedTransformation()->AnyRetrievable();
520
else
521
{
522
byte b;
523
result = Peek(b) != 0;
524
}
525
return result;
526
}
527
528
size_t BufferedTransformation::Get(byte &outByte)
529
{
530
size_t size = 0;
531
if (AttachedTransformation())
532
size = AttachedTransformation()->Get(outByte);
533
else
534
size = Get(&outByte, 1);
535
return size;
536
}
537
538
size_t BufferedTransformation::Get(byte *outString, size_t getMax)
539
{
540
size_t size = 0;
541
if (AttachedTransformation())
542
size = AttachedTransformation()->Get(outString, getMax);
543
else
544
{
545
ArraySink arraySink(outString, getMax);
546
size = (size_t)TransferTo(arraySink, getMax);
547
}
548
return size;
549
}
550
551
size_t BufferedTransformation::Peek(byte &outByte) const
552
{
553
size_t size = 0;
554
if (AttachedTransformation())
555
size = AttachedTransformation()->Peek(outByte);
556
else
557
size = Peek(&outByte, 1);
558
return size;
559
}
560
561
size_t BufferedTransformation::Peek(byte *outString, size_t peekMax) const
562
{
563
size_t size = 0;
564
if (AttachedTransformation())
565
size = AttachedTransformation()->Peek(outString, peekMax);
566
else
567
{
568
ArraySink arraySink(outString, peekMax);
569
size = (size_t)CopyTo(arraySink, peekMax);
570
}
571
return size;
572
}
573
574
lword BufferedTransformation::Skip(lword skipMax)
575
{
576
lword size = 0;
577
if (AttachedTransformation())
578
size = AttachedTransformation()->Skip(skipMax);
579
else
580
size = TransferTo(TheBitBucket(), skipMax);
581
return size;
582
}
583
584
lword BufferedTransformation::TotalBytesRetrievable() const
585
{
586
lword size = 0;
587
if (AttachedTransformation())
588
size = AttachedTransformation()->TotalBytesRetrievable();
589
else
590
size = MaxRetrievable();
591
return size;
592
}
593
594
unsigned int BufferedTransformation::NumberOfMessages() const
595
{
596
unsigned int size = 0;
597
if (AttachedTransformation())
598
size = AttachedTransformation()->NumberOfMessages();
599
else
600
size = CopyMessagesTo(TheBitBucket());
601
return size;
602
}
603
604
bool BufferedTransformation::AnyMessages() const
605
{
606
bool result = false;
607
if (AttachedTransformation())
608
result = AttachedTransformation()->AnyMessages();
609
else
610
result = NumberOfMessages() != 0;
611
return result;
612
}
613
614
bool BufferedTransformation::GetNextMessage()
615
{
616
bool result = false;
617
if (AttachedTransformation())
618
result = AttachedTransformation()->GetNextMessage();
619
else
620
{
621
CRYPTOPP_ASSERT(!AnyMessages());
622
}
623
return result;
624
}
625
626
unsigned int BufferedTransformation::SkipMessages(unsigned int count)
627
{
628
unsigned int size = 0;
629
if (AttachedTransformation())
630
size = AttachedTransformation()->SkipMessages(count);
631
else
632
size = TransferMessagesTo(TheBitBucket(), count);
633
return size;
634
}
635
636
size_t BufferedTransformation::TransferMessagesTo2(BufferedTransformation &target, unsigned int &messageCount, const std::string &channel, bool blocking)
637
{
638
if (AttachedTransformation())
639
return AttachedTransformation()->TransferMessagesTo2(target, messageCount, channel, blocking);
640
else
641
{
642
unsigned int maxMessages = messageCount;
643
for (messageCount=0; messageCount < maxMessages && AnyMessages(); messageCount++)
644
{
645
size_t blockedBytes;
646
lword transferredBytes;
647
648
while (AnyRetrievable())
649
{
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
transferredBytes = MaxRetrievable();
656
blockedBytes = TransferTo2(target, transferredBytes, channel, blocking);
657
if (blockedBytes > 0)
658
return blockedBytes;
659
}
660
661
if (target.ChannelMessageEnd(channel, GetAutoSignalPropagation(), blocking))
662
return 1;
663
664
bool result = GetNextMessage();
665
CRYPTOPP_UNUSED(result); CRYPTOPP_ASSERT(result);
666
}
667
return 0;
668
}
669
}
670
671
unsigned int BufferedTransformation::CopyMessagesTo(BufferedTransformation &target, unsigned int count, const std::string &channel) const
672
{
673
unsigned int size = 0;
674
if (AttachedTransformation())
675
size = AttachedTransformation()->CopyMessagesTo(target, count, channel);
676
return size;
677
}
678
679
void BufferedTransformation::SkipAll()
680
{
681
if (AttachedTransformation())
682
AttachedTransformation()->SkipAll();
683
else
684
{
685
while (SkipMessages()) {}
686
while (Skip()) {}
687
}
688
}
689
690
size_t BufferedTransformation::TransferAllTo2(BufferedTransformation &target, const std::string &channel, bool blocking)
691
{
692
if (AttachedTransformation())
693
return AttachedTransformation()->TransferAllTo2(target, channel, blocking);
694
else
695
{
696
CRYPTOPP_ASSERT(!NumberOfMessageSeries());
697
698
unsigned int messageCount;
699
do
700
{
701
messageCount = UINT_MAX;
702
size_t blockedBytes = TransferMessagesTo2(target, messageCount, channel, blocking);
703
if (blockedBytes)
704
return blockedBytes;
705
}
706
while (messageCount != 0);
707
708
lword byteCount;
709
do
710
{
711
byteCount = ULONG_MAX;
712
size_t blockedBytes = TransferTo2(target, byteCount, channel, blocking);
713
if (blockedBytes)
714
return blockedBytes;
715
}
716
while (byteCount != 0);
717
718
return 0;
719
}
720
}
721
722
void BufferedTransformation::CopyAllTo(BufferedTransformation &target, const std::string &channel) const
723
{
724
if (AttachedTransformation())
725
AttachedTransformation()->CopyAllTo(target, channel);
726
else
727
{
728
CRYPTOPP_ASSERT(!NumberOfMessageSeries());
729
while (CopyMessagesTo(target, UINT_MAX, channel)) {}
730
}
731
}
732
733
void BufferedTransformation::SetRetrievalChannel(const std::string &channel)
734
{
735
if (AttachedTransformation())
736
AttachedTransformation()->SetRetrievalChannel(channel);
737
}
738
739
size_t BufferedTransformation::ChannelPutWord16(const std::string &channel, word16 value, ByteOrder order, bool blocking)
740
{
741
PutWord(false, order, m_buf, value);
742
return ChannelPut(channel, m_buf, 2, blocking);
743
}
744
745
size_t BufferedTransformation::ChannelPutWord32(const std::string &channel, word32 value, ByteOrder order, bool blocking)
746
{
747
PutWord(false, order, m_buf, value);
748
return ChannelPut(channel, m_buf, 4, blocking);
749
}
750
751
size_t BufferedTransformation::ChannelPutWord64(const std::string &channel, word64 value, ByteOrder order, bool blocking)
752
{
753
PutWord(false, order, m_buf, value);
754
return ChannelPut(channel, m_buf, 8, blocking);
755
}
756
757
size_t BufferedTransformation::PutWord16(word16 value, ByteOrder order, bool blocking)
758
{
759
return ChannelPutWord16(DEFAULT_CHANNEL, value, order, blocking);
760
}
761
762
size_t BufferedTransformation::PutWord32(word32 value, ByteOrder order, bool blocking)
763
{
764
return ChannelPutWord32(DEFAULT_CHANNEL, value, order, blocking);
765
}
766
767
size_t BufferedTransformation::PutWord64(word64 value, ByteOrder order, bool blocking)
768
{
769
return ChannelPutWord64(DEFAULT_CHANNEL, value, order, blocking);
770
}
771
772
size_t BufferedTransformation::PeekWord16(word16 &value, ByteOrder order) const
773
{
774
byte buf[2] = {0, 0};
775
size_t len = Peek(buf, 2);
776
777
if (order == BIG_ENDIAN_ORDER)
778
value = word16((buf[0] << 8) | buf[1]);
779
else
780
value = word16((buf[1] << 8) | buf[0]);
781
782
return len;
783
}
784
785
size_t BufferedTransformation::PeekWord32(word32 &value, ByteOrder order) const
786
{
787
byte buf[4] = {0, 0, 0, 0};
788
size_t len = Peek(buf, 4);
789
790
if (order == BIG_ENDIAN_ORDER)
791
value = word32((buf[0] << 24) | (buf[1] << 16) |
792
(buf[2] << 8) | (buf[3] << 0));
793
else
794
value = word32((buf[3] << 24) | (buf[2] << 16) |
795
(buf[1] << 8) | (buf[0] << 0));
796
797
return len;
798
}
799
800
size_t BufferedTransformation::PeekWord64(word64 &value, ByteOrder order) const
801
{
802
byte buf[8] = {0, 0, 0, 0, 0, 0, 0, 0};
803
size_t len = Peek(buf, 8);
804
805
if (order == BIG_ENDIAN_ORDER)
806
value = ((word64)buf[0] << 56) | ((word64)buf[1] << 48) | ((word64)buf[2] << 40) |
807
((word64)buf[3] << 32) | ((word64)buf[4] << 24) | ((word64)buf[5] << 16) |
808
((word64)buf[6] << 8) | (word64)buf[7];
809
else
810
value = ((word64)buf[7] << 56) | ((word64)buf[6] << 48) | ((word64)buf[5] << 40) |
811
((word64)buf[4] << 32) | ((word64)buf[3] << 24) | ((word64)buf[2] << 16) |
812
((word64)buf[1] << 8) | (word64)buf[0];
813
814
return len;
815
}
816
817
size_t BufferedTransformation::GetWord16(word16 &value, ByteOrder order)
818
{
819
return (size_t)Skip(PeekWord16(value, order));
820
}
821
822
size_t BufferedTransformation::GetWord32(word32 &value, ByteOrder order)
823
{
824
return (size_t)Skip(PeekWord32(value, order));
825
}
826
827
size_t BufferedTransformation::GetWord64(word64 &value, ByteOrder order)
828
{
829
return (size_t)Skip(PeekWord64(value, order));
830
}
831
832
void BufferedTransformation::Attach(BufferedTransformation *newAttachment)
833
{
834
if (AttachedTransformation() && AttachedTransformation()->Attachable())
835
AttachedTransformation()->Attach(newAttachment);
836
else
837
Detach(newAttachment);
838
}
839
840
void GeneratableCryptoMaterial::GenerateRandomWithKeySize(RandomNumberGenerator &rng, unsigned int keySize)
841
{
842
GenerateRandom(rng, MakeParameters("KeySize", (int)keySize));
843
}
844
845
class PK_DefaultEncryptionFilter : public Unflushable<Filter>
846
{
847
public:
848
PK_DefaultEncryptionFilter(RandomNumberGenerator &rng, const PK_Encryptor &encryptor, BufferedTransformation *attachment, const NameValuePairs &parameters)
849
: m_rng(rng), m_encryptor(encryptor), m_parameters(parameters)
850
{
851
Detach(attachment);
852
}
853
854
size_t Put2(const byte *inString, size_t length, int messageEnd, bool blocking)
855
{
856
FILTER_BEGIN;
857
m_plaintextQueue.Put(inString, length);
858
859
if (messageEnd)
860
{
861
{
862
size_t plaintextLength;
863
if (!SafeConvert(m_plaintextQueue.CurrentSize(), plaintextLength))
864
throw InvalidArgument("PK_DefaultEncryptionFilter: plaintext too long");
865
size_t ciphertextLength = m_encryptor.CiphertextLength(plaintextLength);
866
867
SecByteBlock plaintext(plaintextLength);
868
m_plaintextQueue.Get(plaintext, plaintextLength);
869
m_ciphertext.resize(ciphertextLength);
870
m_encryptor.Encrypt(m_rng, plaintext, plaintextLength, m_ciphertext, m_parameters);
871
}
872
873
FILTER_OUTPUT(1, m_ciphertext, m_ciphertext.size(), messageEnd);
874
}
875
FILTER_END_NO_MESSAGE_END;
876
}
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 &parameters) const
886
{
887
return new PK_DefaultEncryptionFilter(rng, *this, attachment, parameters);
888
}
889
890
class PK_DefaultDecryptionFilter : public Unflushable<Filter>
891
{
892
public:
893
PK_DefaultDecryptionFilter(RandomNumberGenerator &rng, const PK_Decryptor &decryptor, BufferedTransformation *attachment, const NameValuePairs &parameters)
894
: m_rng(rng), m_decryptor(decryptor), m_parameters(parameters)
895
{
896
Detach(attachment);
897
}
898
899
size_t Put2(const byte *inString, size_t length, int messageEnd, bool blocking)
900
{
901
FILTER_BEGIN;
902
m_ciphertextQueue.Put(inString, length);
903
904
if (messageEnd)
905
{
906
{
907
size_t ciphertextLength;
908
if (!SafeConvert(m_ciphertextQueue.CurrentSize(), ciphertextLength))
909
throw InvalidArgument("PK_DefaultDecryptionFilter: ciphertext too long");
910
size_t maxPlaintextLength = m_decryptor.MaxPlaintextLength(ciphertextLength);
911
912
SecByteBlock ciphertext(ciphertextLength);
913
m_ciphertextQueue.Get(ciphertext, ciphertextLength);
914
m_plaintext.resize(maxPlaintextLength);
915
m_result = m_decryptor.Decrypt(m_rng, ciphertext, ciphertextLength, m_plaintext, m_parameters);
916
if (!m_result.isValidCoding)
917
throw InvalidCiphertext(m_decryptor.AlgorithmName() + ": invalid ciphertext");
918
}
919
920
FILTER_OUTPUT(1, m_plaintext, m_result.messageLength, messageEnd);
921
}
922
FILTER_END_NO_MESSAGE_END;
923
}
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 &parameters) const
934
{
935
return new PK_DefaultDecryptionFilter(rng, *this, attachment, parameters);
936
}
937
938
size_t PK_Signer::Sign(RandomNumberGenerator &rng, PK_MessageAccumulator *messageAccumulator, byte *signature) const
939
{
940
member_ptr<PK_MessageAccumulator> m(messageAccumulator);
941
return SignAndRestart(rng, *m, signature, false);
942
}
943
944
size_t PK_Signer::SignMessage(RandomNumberGenerator &rng, const byte *message, size_t messageLen, byte *signature) const
945
{
946
member_ptr<PK_MessageAccumulator> m(NewSignatureAccumulator(rng));
947
m->Update(message, messageLen);
948
return SignAndRestart(rng, *m, signature, false);
949
}
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
{
954
member_ptr<PK_MessageAccumulator> m(NewSignatureAccumulator(rng));
955
InputRecoverableMessage(*m, recoverableMessage, recoverableMessageLength);
956
m->Update(nonrecoverableMessage, nonrecoverableMessageLength);
957
return SignAndRestart(rng, *m, signature, false);
958
}
959
960
bool PK_Verifier::Verify(PK_MessageAccumulator *messageAccumulator) const
961
{
962
member_ptr<PK_MessageAccumulator> m(messageAccumulator);
963
return VerifyAndRestart(*m);
964
}
965
966
bool PK_Verifier::VerifyMessage(const byte *message, size_t messageLen, const byte *signature, size_t signatureLen) const
967
{
968
member_ptr<PK_MessageAccumulator> m(NewVerificationAccumulator());
969
InputSignature(*m, signature, signatureLen);
970
m->Update(message, messageLen);
971
return VerifyAndRestart(*m);
972
}
973
974
DecodingResult PK_Verifier::Recover(byte *recoveredMessage, PK_MessageAccumulator *messageAccumulator) const
975
{
976
member_ptr<PK_MessageAccumulator> m(messageAccumulator);
977
return RecoverAndRestart(recoveredMessage, *m);
978
}
979
980
DecodingResult PK_Verifier::RecoverMessage(byte *recoveredMessage,
981
const byte *nonrecoverableMessage, size_t nonrecoverableMessageLength,
982
const byte *signature, size_t signatureLength) const
983
{
984
member_ptr<PK_MessageAccumulator> m(NewVerificationAccumulator());
985
InputSignature(*m, signature, signatureLength);
986
m->Update(nonrecoverableMessage, nonrecoverableMessageLength);
987
return RecoverAndRestart(recoveredMessage, *m);
988
}
989
990
void SimpleKeyAgreementDomain::GenerateKeyPair(RandomNumberGenerator &rng, byte *privateKey, byte *publicKey) const
991
{
992
GeneratePrivateKey(rng, privateKey);
993
GeneratePublicKey(rng, privateKey, publicKey);
994
}
995
996
void AuthenticatedKeyAgreementDomain::GenerateStaticKeyPair(RandomNumberGenerator &rng, byte *privateKey, byte *publicKey) const
997
{
998
GenerateStaticPrivateKey(rng, privateKey);
999
GenerateStaticPublicKey(rng, privateKey, publicKey);
1000
}
1001
1002
void AuthenticatedKeyAgreementDomain::GenerateEphemeralKeyPair(RandomNumberGenerator &rng, byte *privateKey, byte *publicKey) const
1003
{
1004
GenerateEphemeralPrivateKey(rng, privateKey);
1005
GenerateEphemeralPublicKey(rng, privateKey, publicKey);
1006
}
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
# define CRYPTOPP_BUILD_VERSION CRYPTOPP_VERSION
1012
#endif
1013
int LibraryVersion(CRYPTOPP_NOINLINE_DOTDOTDOT)
1014
{
1015
return CRYPTOPP_BUILD_VERSION;
1016
}
1017
1018
class NullNameValuePairs : public NameValuePairs
1019
{
1020
public:
1021
NullNameValuePairs() {} // Clang complains a default ctor must be available
1022
bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const
1023
{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
1055
1056