source: git/src-cryptopp/cryptlib.cpp

Last change on this file was 00a3bd6, checked in by David Stainton <dstainton415@…>, at 2016-10-12T13:30:29Z

Add extern declaraton and assignment of cryptopp_extra_version

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