monotone

monotone Mtn Source Tree

Root/cryptopp/cryptlib.cpp

1// cryptlib.cpp - written and placed in the public domain by Wei Dai
2
3#include "pch.h"
4#include "cryptlib.h"
5#include "misc.h"
6#include "filters.h"
7#include "algparam.h"
8#include "fips140.h"
9#include "argnames.h"
10
11#include <memory>
12
13NAMESPACE_BEGIN(CryptoPP)
14
15CRYPTOPP_COMPILE_ASSERT(sizeof(byte) == 1);
16CRYPTOPP_COMPILE_ASSERT(sizeof(word16) == 2);
17CRYPTOPP_COMPILE_ASSERT(sizeof(word32) == 4);
18#ifdef WORD64_AVAILABLE
19CRYPTOPP_COMPILE_ASSERT(sizeof(word64) == 8);
20#endif
21CRYPTOPP_COMPILE_ASSERT(sizeof(dword) == 2*sizeof(word));
22
23const std::string BufferedTransformation::NULL_CHANNEL;
24const NullNameValuePairs g_nullNameValuePairs;
25
26BufferedTransformation & TheBitBucket()
27{
28static BitBucket bitBucket;
29return bitBucket;
30}
31
32Algorithm::Algorithm(bool checkSelfTestStatus)
33{
34if (checkSelfTestStatus && FIPS_140_2_ComplianceEnabled())
35{
36if (GetPowerUpSelfTestStatus() == POWER_UP_SELF_TEST_NOT_DONE && !PowerUpSelfTestInProgressOnThisThread())
37throw SelfTestFailure("Cryptographic algorithms are disabled before the power-up self tests are performed.");
38
39if (GetPowerUpSelfTestStatus() == POWER_UP_SELF_TEST_FAILED)
40throw SelfTestFailure("Cryptographic algorithms are disabled after power-up a self test failed.");
41}
42}
43
44void SimpleKeyingInterface::SetKeyWithRounds(const byte *key, unsigned int length, int rounds)
45{
46SetKey(key, length, MakeParameters(Name::Rounds(), rounds));
47}
48
49void SimpleKeyingInterface::SetKeyWithIV(const byte *key, unsigned int length, const byte *iv)
50{
51SetKey(key, length, MakeParameters(Name::IV(), iv));
52}
53
54void SimpleKeyingInterface::ThrowIfInvalidKeyLength(const Algorithm &algorithm, unsigned int length)
55{
56if (!IsValidKeyLength(length))
57throw InvalidKeyLength(algorithm.AlgorithmName(), length);
58}
59
60void BlockTransformation::ProcessAndXorMultipleBlocks(const byte *inBlocks, const byte *xorBlocks, byte *outBlocks, unsigned int numberOfBlocks) const
61{
62unsigned int blockSize = BlockSize();
63while (numberOfBlocks--)
64{
65ProcessAndXorBlock(inBlocks, xorBlocks, outBlocks);
66inBlocks += blockSize;
67outBlocks += blockSize;
68if (xorBlocks)
69xorBlocks += blockSize;
70}
71}
72
73void StreamTransformation::ProcessLastBlock(byte *outString, const byte *inString, unsigned int length)
74{
75assert(MinLastBlockSize() == 0);// this function should be overriden otherwise
76
77if (length == MandatoryBlockSize())
78ProcessData(outString, inString, length);
79else if (length != 0)
80throw NotImplemented("StreamTransformation: this object does't support a special last block");
81}
82
83unsigned int RandomNumberGenerator::GenerateBit()
84{
85return Parity(GenerateByte());
86}
87
88void RandomNumberGenerator::GenerateBlock(byte *output, unsigned int size)
89{
90while (size--)
91*output++ = GenerateByte();
92}
93
94word32 RandomNumberGenerator::GenerateWord32(word32 min, word32 max)
95{
96word32 range = max-min;
97const int maxBytes = BytePrecision(range);
98const int maxBits = BitPrecision(range);
99
100word32 value;
101
102do
103{
104value = 0;
105for (int i=0; i<maxBytes; i++)
106value = (value << 8) | GenerateByte();
107
108value = Crop(value, maxBits);
109} while (value > range);
110
111return value+min;
112}
113
114void RandomNumberGenerator::DiscardBytes(unsigned int n)
115{
116while (n--)
117GenerateByte();
118}
119
120RandomNumberGenerator & NullRNG()
121{
122class NullRNG : public RandomNumberGenerator
123{
124public:
125std::string AlgorithmName() const {return "NullRNG";}
126byte GenerateByte() {throw NotImplemented("NullRNG: NullRNG should only be passed to functions that don't need to generate random bytes");}
127};
128
129static NullRNG s_nullRNG;
130return s_nullRNG;
131}
132
133bool HashTransformation::TruncatedVerify(const byte *digestIn, unsigned int digestLength)
134{
135ThrowIfInvalidTruncatedSize(digestLength);
136SecByteBlock digest(digestLength);
137TruncatedFinal(digest, digestLength);
138return memcmp(digest, digestIn, digestLength) == 0;
139}
140
141void HashTransformation::ThrowIfInvalidTruncatedSize(unsigned int size) const
142{
143if (size > DigestSize())
144throw InvalidArgument("HashTransformation: can't truncate a " + IntToString(DigestSize()) + " byte digest to " + IntToString(size) + " bytes");
145}
146
147unsigned int BufferedTransformation::GetMaxWaitObjectCount() const
148{
149const BufferedTransformation *t = AttachedTransformation();
150return t ? t->GetMaxWaitObjectCount() : 0;
151}
152
153void BufferedTransformation::GetWaitObjects(WaitObjectContainer &container)
154{
155BufferedTransformation *t = AttachedTransformation();
156if (t)
157t->GetWaitObjects(container);
158}
159
160void BufferedTransformation::Initialize(const NameValuePairs &parameters, int propagation)
161{
162assert(!AttachedTransformation());
163IsolatedInitialize(parameters);
164}
165
166bool BufferedTransformation::Flush(bool hardFlush, int propagation, bool blocking)
167{
168assert(!AttachedTransformation());
169return IsolatedFlush(hardFlush, blocking);
170}
171
172bool BufferedTransformation::MessageSeriesEnd(int propagation, bool blocking)
173{
174assert(!AttachedTransformation());
175return IsolatedMessageSeriesEnd(blocking);
176}
177
178byte * BufferedTransformation::ChannelCreatePutSpace(const std::string &channel, unsigned int &size)
179{
180if (channel.empty())
181return CreatePutSpace(size);
182else
183throw NoChannelSupport();
184}
185
186unsigned int BufferedTransformation::ChannelPut2(const std::string &channel, const byte *begin, unsigned int length, int messageEnd, bool blocking)
187{
188if (channel.empty())
189return Put2(begin, length, messageEnd, blocking);
190else
191throw NoChannelSupport();
192}
193
194unsigned int BufferedTransformation::ChannelPutModifiable2(const std::string &channel, byte *begin, unsigned int length, int messageEnd, bool blocking)
195{
196if (channel.empty())
197return PutModifiable2(begin, length, messageEnd, blocking);
198else
199return ChannelPut2(channel, begin, length, messageEnd, blocking);
200}
201
202void BufferedTransformation::ChannelInitialize(const std::string &channel, const NameValuePairs &parameters, int propagation)
203{
204if (channel.empty())
205Initialize(parameters, propagation);
206else
207throw NoChannelSupport();
208}
209
210bool BufferedTransformation::ChannelFlush(const std::string &channel, bool completeFlush, int propagation, bool blocking)
211{
212if (channel.empty())
213return Flush(completeFlush, propagation, blocking);
214else
215throw NoChannelSupport();
216}
217
218bool BufferedTransformation::ChannelMessageSeriesEnd(const std::string &channel, int propagation, bool blocking)
219{
220if (channel.empty())
221return MessageSeriesEnd(propagation, blocking);
222else
223throw NoChannelSupport();
224}
225
226unsigned long BufferedTransformation::MaxRetrievable() const
227{
228if (AttachedTransformation())
229return AttachedTransformation()->MaxRetrievable();
230else
231return CopyTo(TheBitBucket());
232}
233
234bool BufferedTransformation::AnyRetrievable() const
235{
236if (AttachedTransformation())
237return AttachedTransformation()->AnyRetrievable();
238else
239{
240byte b;
241return Peek(b) != 0;
242}
243}
244
245unsigned int BufferedTransformation::Get(byte &outByte)
246{
247if (AttachedTransformation())
248return AttachedTransformation()->Get(outByte);
249else
250return Get(&outByte, 1);
251}
252
253unsigned int BufferedTransformation::Get(byte *outString, unsigned int getMax)
254{
255if (AttachedTransformation())
256return AttachedTransformation()->Get(outString, getMax);
257else
258{
259ArraySink arraySink(outString, getMax);
260return TransferTo(arraySink, getMax);
261}
262}
263
264unsigned int BufferedTransformation::Peek(byte &outByte) const
265{
266if (AttachedTransformation())
267return AttachedTransformation()->Peek(outByte);
268else
269return Peek(&outByte, 1);
270}
271
272unsigned int BufferedTransformation::Peek(byte *outString, unsigned int peekMax) const
273{
274if (AttachedTransformation())
275return AttachedTransformation()->Peek(outString, peekMax);
276else
277{
278ArraySink arraySink(outString, peekMax);
279return CopyTo(arraySink, peekMax);
280}
281}
282
283unsigned long BufferedTransformation::Skip(unsigned long skipMax)
284{
285if (AttachedTransformation())
286return AttachedTransformation()->Skip(skipMax);
287else
288return TransferTo(TheBitBucket(), skipMax);
289}
290
291unsigned long BufferedTransformation::TotalBytesRetrievable() const
292{
293if (AttachedTransformation())
294return AttachedTransformation()->TotalBytesRetrievable();
295else
296return MaxRetrievable();
297}
298
299unsigned int BufferedTransformation::NumberOfMessages() const
300{
301if (AttachedTransformation())
302return AttachedTransformation()->NumberOfMessages();
303else
304return CopyMessagesTo(TheBitBucket());
305}
306
307bool BufferedTransformation::AnyMessages() const
308{
309if (AttachedTransformation())
310return AttachedTransformation()->AnyMessages();
311else
312return NumberOfMessages() != 0;
313}
314
315bool BufferedTransformation::GetNextMessage()
316{
317if (AttachedTransformation())
318return AttachedTransformation()->GetNextMessage();
319else
320{
321assert(!AnyMessages());
322return false;
323}
324}
325
326unsigned int BufferedTransformation::SkipMessages(unsigned int count)
327{
328if (AttachedTransformation())
329return AttachedTransformation()->SkipMessages(count);
330else
331return TransferMessagesTo(TheBitBucket(), count);
332}
333
334unsigned int BufferedTransformation::TransferMessagesTo2(BufferedTransformation &target, unsigned int &messageCount, const std::string &channel, bool blocking)
335{
336if (AttachedTransformation())
337return AttachedTransformation()->TransferMessagesTo2(target, messageCount, channel, blocking);
338else
339{
340unsigned int maxMessages = messageCount;
341for (messageCount=0; messageCount < maxMessages && AnyMessages(); messageCount++)
342{
343unsigned int blockedBytes;
344unsigned long transferedBytes;
345
346while (AnyRetrievable())
347{
348transferedBytes = ULONG_MAX;
349blockedBytes = TransferTo2(target, transferedBytes, channel, blocking);
350if (blockedBytes > 0)
351return blockedBytes;
352}
353
354if (target.ChannelMessageEnd(channel, GetAutoSignalPropagation(), blocking))
355return 1;
356
357bool result = GetNextMessage();
358assert(result);
359}
360return 0;
361}
362}
363
364unsigned int BufferedTransformation::CopyMessagesTo(BufferedTransformation &target, unsigned int count, const std::string &channel) const
365{
366if (AttachedTransformation())
367return AttachedTransformation()->CopyMessagesTo(target, count, channel);
368else
369return 0;
370}
371
372void BufferedTransformation::SkipAll()
373{
374if (AttachedTransformation())
375AttachedTransformation()->SkipAll();
376else
377{
378while (SkipMessages()) {}
379while (Skip()) {}
380}
381}
382
383unsigned int BufferedTransformation::TransferAllTo2(BufferedTransformation &target, const std::string &channel, bool blocking)
384{
385if (AttachedTransformation())
386return AttachedTransformation()->TransferAllTo2(target, channel, blocking);
387else
388{
389assert(!NumberOfMessageSeries());
390
391unsigned int messageCount;
392do
393{
394messageCount = UINT_MAX;
395unsigned int blockedBytes = TransferMessagesTo2(target, messageCount, channel, blocking);
396if (blockedBytes)
397return blockedBytes;
398}
399while (messageCount != 0);
400
401unsigned long byteCount;
402do
403{
404byteCount = ULONG_MAX;
405unsigned int blockedBytes = TransferTo2(target, byteCount, channel, blocking);
406if (blockedBytes)
407return blockedBytes;
408}
409while (byteCount != 0);
410
411return 0;
412}
413}
414
415void BufferedTransformation::CopyAllTo(BufferedTransformation &target, const std::string &channel) const
416{
417if (AttachedTransformation())
418AttachedTransformation()->CopyAllTo(target, channel);
419else
420{
421assert(!NumberOfMessageSeries());
422while (CopyMessagesTo(target, UINT_MAX, channel)) {}
423}
424}
425
426void BufferedTransformation::SetRetrievalChannel(const std::string &channel)
427{
428if (AttachedTransformation())
429AttachedTransformation()->SetRetrievalChannel(channel);
430}
431
432unsigned int BufferedTransformation::ChannelPutWord16(const std::string &channel, word16 value, ByteOrder order, bool blocking)
433{
434FixedSizeSecBlock<byte, 2> buf;
435PutWord(false, order, buf, value);
436return ChannelPut(channel, buf, 2, blocking);
437}
438
439unsigned int BufferedTransformation::ChannelPutWord32(const std::string &channel, word32 value, ByteOrder order, bool blocking)
440{
441FixedSizeSecBlock<byte, 4> buf;
442PutWord(false, order, buf, value);
443return ChannelPut(channel, buf, 4, blocking);
444}
445
446unsigned int BufferedTransformation::PutWord16(word16 value, ByteOrder order, bool blocking)
447{
448return ChannelPutWord16(NULL_CHANNEL, value, order, blocking);
449}
450
451unsigned int BufferedTransformation::PutWord32(word32 value, ByteOrder order, bool blocking)
452{
453return ChannelPutWord32(NULL_CHANNEL, value, order, blocking);
454}
455
456unsigned int BufferedTransformation::PeekWord16(word16 &value, ByteOrder order)
457{
458byte buf[2] = {0, 0};
459unsigned int len = Peek(buf, 2);
460
461if (order)
462value = (buf[0] << 8) | buf[1];
463else
464value = (buf[1] << 8) | buf[0];
465
466return len;
467}
468
469unsigned int BufferedTransformation::PeekWord32(word32 &value, ByteOrder order)
470{
471byte buf[4] = {0, 0, 0, 0};
472unsigned int len = Peek(buf, 4);
473
474if (order)
475value = (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf [3];
476else
477value = (buf[3] << 24) | (buf[2] << 16) | (buf[1] << 8) | buf [0];
478
479return len;
480}
481
482unsigned int BufferedTransformation::GetWord16(word16 &value, ByteOrder order)
483{
484return Skip(PeekWord16(value, order));
485}
486
487unsigned int BufferedTransformation::GetWord32(word32 &value, ByteOrder order)
488{
489return Skip(PeekWord32(value, order));
490}
491
492void BufferedTransformation::Attach(BufferedTransformation *newOut)
493{
494if (AttachedTransformation() && AttachedTransformation()->Attachable())
495AttachedTransformation()->Attach(newOut);
496else
497Detach(newOut);
498}
499
500void GeneratableCryptoMaterial::GenerateRandomWithKeySize(RandomNumberGenerator &rng, unsigned int keySize)
501{
502GenerateRandom(rng, MakeParameters("KeySize", (int)keySize));
503}
504
505BufferedTransformation * PK_Encryptor::CreateEncryptionFilter(RandomNumberGenerator &rng, BufferedTransformation *attachment) const
506{
507struct EncryptionFilter : public Unflushable<FilterWithInputQueue>
508{
509// VC60 complains if this function is missing
510EncryptionFilter(const EncryptionFilter &x) : Unflushable<FilterWithInputQueue>(NULL), m_rng(x.m_rng), m_encryptor(x.m_encryptor) {}
511
512EncryptionFilter(RandomNumberGenerator &rng, const PK_Encryptor &encryptor, BufferedTransformation *attachment)
513: Unflushable<FilterWithInputQueue>(attachment), m_rng(rng), m_encryptor(encryptor)
514{
515}
516
517bool IsolatedMessageEnd(bool blocking)
518{
519switch (m_continueAt)
520{
521case 0:
522{
523unsigned int plaintextLength = m_inQueue.CurrentSize();
524m_ciphertextLength = m_encryptor.CiphertextLength(plaintextLength);
525
526SecByteBlock plaintext(plaintextLength);
527m_inQueue.Get(plaintext, plaintextLength);
528m_ciphertext.resize(m_ciphertextLength);
529m_encryptor.Encrypt(m_rng, plaintext, plaintextLength, m_ciphertext);
530}
531
532case 1:
533if (!Output(1, m_ciphertext, m_ciphertextLength, 0, blocking))
534return false;
535};
536return true;
537}
538
539RandomNumberGenerator &m_rng;
540const PK_Encryptor &m_encryptor;
541unsigned int m_ciphertextLength;
542SecByteBlock m_ciphertext;
543};
544
545return new EncryptionFilter(rng, *this, attachment);
546}
547
548BufferedTransformation * PK_Decryptor::CreateDecryptionFilter(RandomNumberGenerator &rng, BufferedTransformation *attachment) const
549{
550struct DecryptionFilter : public Unflushable<FilterWithInputQueue>
551{
552// VC60 complains if this function is missing
553DecryptionFilter(const DecryptionFilter &x) : Unflushable<FilterWithInputQueue>(NULL), m_rng(x.m_rng), m_decryptor(x.m_decryptor) {}
554
555DecryptionFilter(RandomNumberGenerator &rng, const PK_Decryptor &decryptor, BufferedTransformation *attachment)
556: Unflushable<FilterWithInputQueue>(attachment), m_rng(rng), m_decryptor(decryptor)
557{
558}
559
560bool IsolatedMessageEnd(bool blocking)
561{
562switch (m_continueAt)
563{
564case 0:
565{
566unsigned int ciphertextLength = m_inQueue.CurrentSize();
567unsigned int maxPlaintextLength = m_decryptor.MaxPlaintextLength(ciphertextLength);
568
569SecByteBlock ciphertext(ciphertextLength);
570m_inQueue.Get(ciphertext, ciphertextLength);
571m_plaintext.resize(maxPlaintextLength);
572m_result = m_decryptor.Decrypt(m_rng, ciphertext, ciphertextLength, m_plaintext);
573if (!m_result.isValidCoding)
574throw InvalidCiphertext(m_decryptor.AlgorithmName() + ": invalid ciphertext");
575}
576
577case 1:
578if (!Output(1, m_plaintext, m_result.messageLength, 0, blocking))
579return false;
580}
581return true;
582}
583
584RandomNumberGenerator &m_rng;
585const PK_Decryptor &m_decryptor;
586SecByteBlock m_plaintext;
587DecodingResult m_result;
588};
589
590return new DecryptionFilter(rng, *this, attachment);
591}
592
593unsigned int PK_FixedLengthCryptoSystem::MaxPlaintextLength(unsigned int cipherTextLength) const
594{
595if (cipherTextLength == FixedCiphertextLength())
596return FixedMaxPlaintextLength();
597else
598return 0;
599}
600
601unsigned int PK_FixedLengthCryptoSystem::CiphertextLength(unsigned int plainTextLength) const
602{
603if (plainTextLength <= FixedMaxPlaintextLength())
604return FixedCiphertextLength();
605else
606return 0;
607}
608
609DecodingResult PK_FixedLengthDecryptor::Decrypt(RandomNumberGenerator &rng, const byte *cipherText, unsigned int cipherTextLength, byte *plainText) const
610{
611if (cipherTextLength != FixedCiphertextLength())
612return DecodingResult();
613
614return FixedLengthDecrypt(rng, cipherText, plainText);
615}
616
617unsigned int PK_Signer::Sign(RandomNumberGenerator &rng, PK_MessageAccumulator *messageAccumulator, byte *signature) const
618{
619std::auto_ptr<PK_MessageAccumulator> m(messageAccumulator);
620return SignAndRestart(rng, *m, signature, false);
621}
622
623unsigned int PK_Signer::SignMessage(RandomNumberGenerator &rng, const byte *message, unsigned int messageLen, byte *signature) const
624{
625std::auto_ptr<PK_MessageAccumulator> m(NewSignatureAccumulator(rng));
626m->Update(message, messageLen);
627return SignAndRestart(rng, *m, signature, false);
628}
629
630unsigned int PK_Signer::SignMessageWithRecovery(RandomNumberGenerator &rng, const byte *recoverableMessage, unsigned int recoverableMessageLength,
631const byte *nonrecoverableMessage, unsigned int nonrecoverableMessageLength, byte *signature) const
632{
633std::auto_ptr<PK_MessageAccumulator> m(NewSignatureAccumulator(rng));
634InputRecoverableMessage(*m, recoverableMessage, recoverableMessageLength);
635m->Update(nonrecoverableMessage, nonrecoverableMessageLength);
636return SignAndRestart(rng, *m, signature, false);
637}
638
639bool PK_Verifier::Verify(PK_MessageAccumulator *messageAccumulator) const
640{
641std::auto_ptr<PK_MessageAccumulator> m(messageAccumulator);
642return VerifyAndRestart(*m);
643}
644
645bool PK_Verifier::VerifyMessage(const byte *message, unsigned int messageLen, const byte *signature, unsigned int signatureLength) const
646{
647std::auto_ptr<PK_MessageAccumulator> m(NewVerificationAccumulator());
648InputSignature(*m, signature, signatureLength);
649m->Update(message, messageLen);
650return VerifyAndRestart(*m);
651}
652
653DecodingResult PK_Verifier::Recover(byte *recoveredMessage, PK_MessageAccumulator *messageAccumulator) const
654{
655std::auto_ptr<PK_MessageAccumulator> m(messageAccumulator);
656return RecoverAndRestart(recoveredMessage, *m);
657}
658
659DecodingResult PK_Verifier::RecoverMessage(byte *recoveredMessage,
660const byte *nonrecoverableMessage, unsigned int nonrecoverableMessageLength,
661const byte *signature, unsigned int signatureLength) const
662{
663std::auto_ptr<PK_MessageAccumulator> m(NewVerificationAccumulator());
664InputSignature(*m, signature, signatureLength);
665m->Update(nonrecoverableMessage, nonrecoverableMessageLength);
666return RecoverAndRestart(recoveredMessage, *m);
667}
668
669void SimpleKeyAgreementDomain::GenerateKeyPair(RandomNumberGenerator &rng, byte *privateKey, byte *publicKey) const
670{
671GeneratePrivateKey(rng, privateKey);
672GeneratePublicKey(rng, privateKey, publicKey);
673}
674
675void AuthenticatedKeyAgreementDomain::GenerateStaticKeyPair(RandomNumberGenerator &rng, byte *privateKey, byte *publicKey) const
676{
677GenerateStaticPrivateKey(rng, privateKey);
678GenerateStaticPublicKey(rng, privateKey, publicKey);
679}
680
681void AuthenticatedKeyAgreementDomain::GenerateEphemeralKeyPair(RandomNumberGenerator &rng, byte *privateKey, byte *publicKey) const
682{
683GenerateEphemeralPrivateKey(rng, privateKey);
684GenerateEphemeralPublicKey(rng, privateKey, publicKey);
685}
686
687NAMESPACE_END

Archive Download this file

Branches

Tags

Quick Links:     www.monotone.ca    -     Downloads    -     Documentation    -     Wiki    -     Code Forge    -     Build Status