Path: blob/a-new-beginning/SharedDependencies/Sources/cryptopp/cryptlib.cpp
2 views
// cryptlib.cpp - originally written and placed in the public domain by Wei Dai12#include "pch.h"3#include "config.h"45#if CRYPTOPP_MSC_VERSION6# pragma warning(disable: 4127 4189 4459)7#endif89#if CRYPTOPP_GCC_DIAGNOSTIC_AVAILABLE10# pragma GCC diagnostic ignored "-Wunused-value"11# pragma GCC diagnostic ignored "-Wunused-variable"12# pragma GCC diagnostic ignored "-Wunused-parameter"13#endif1415#ifndef CRYPTOPP_IMPORTS1617#include "cryptlib.h"18#include "filters.h"19#include "algparam.h"20#include "fips140.h"21#include "argnames.h"22#include "fltrimpl.h"23#include "osrng.h"24#include "secblock.h"25#include "smartptr.h"26#include "stdcpp.h"27#include "misc.h"2829NAMESPACE_BEGIN(CryptoPP)3031CRYPTOPP_COMPILE_ASSERT(sizeof(byte) == 1);32CRYPTOPP_COMPILE_ASSERT(sizeof(word16) == 2);33CRYPTOPP_COMPILE_ASSERT(sizeof(word32) == 4);34CRYPTOPP_COMPILE_ASSERT(sizeof(word64) == 8);35#ifdef CRYPTOPP_NATIVE_DWORD_AVAILABLE36CRYPTOPP_COMPILE_ASSERT(sizeof(dword) == 2*sizeof(word));37#endif3839BufferedTransformation & TheBitBucket()40{41static BitBucket bitBucket;42return bitBucket;43}4445Algorithm::Algorithm(bool checkSelfTestStatus)46{47if (checkSelfTestStatus && FIPS_140_2_ComplianceEnabled())48{49if (GetPowerUpSelfTestStatus() == POWER_UP_SELF_TEST_NOT_DONE && !PowerUpSelfTestInProgressOnThisThread())50throw SelfTestFailure("Cryptographic algorithms are disabled before the power-up self tests are performed.");5152if (GetPowerUpSelfTestStatus() == POWER_UP_SELF_TEST_FAILED)53throw SelfTestFailure("Cryptographic algorithms are disabled after a power-up self test failed.");54}55}5657void SimpleKeyingInterface::SetKey(const byte *key, size_t length, const NameValuePairs ¶ms)58{59this->ThrowIfInvalidKeyLength(length);60this->UncheckedSetKey(key, static_cast<unsigned int>(length), params);61}6263void SimpleKeyingInterface::SetKeyWithRounds(const byte *key, size_t length, int rounds)64{65SetKey(key, length, MakeParameters(Name::Rounds(), rounds));66}6768void SimpleKeyingInterface::SetKeyWithIV(const byte *key, size_t length, const byte *iv, size_t ivLength)69{70SetKey(key, length, MakeParameters(Name::IV(), ConstByteArrayParameter(iv, ivLength)));71}7273void SimpleKeyingInterface::ThrowIfInvalidKeyLength(size_t length)74{75if (!IsValidKeyLength(length))76throw InvalidKeyLength(GetAlgorithm().AlgorithmName(), length);77}7879void SimpleKeyingInterface::ThrowIfResynchronizable()80{81if (IsResynchronizable())82throw InvalidArgument(GetAlgorithm().AlgorithmName() + ": this object requires an IV");83}8485void SimpleKeyingInterface::ThrowIfInvalidIV(const byte *iv)86{87if (!iv && IVRequirement() == UNPREDICTABLE_RANDOM_IV)88throw InvalidArgument(GetAlgorithm().AlgorithmName() + ": this object cannot use a null IV");89}9091size_t SimpleKeyingInterface::ThrowIfInvalidIVLength(int length)92{93size_t size = 0;94if (length < 0)95size = static_cast<size_t>(IVSize());96else if ((size_t)length < MinIVLength())97throw InvalidArgument(GetAlgorithm().AlgorithmName() + ": IV length " + IntToString(length) + " is less than the minimum of " + IntToString(MinIVLength()));98else if ((size_t)length > MaxIVLength())99throw InvalidArgument(GetAlgorithm().AlgorithmName() + ": IV length " + IntToString(length) + " exceeds the maximum of " + IntToString(MaxIVLength()));100else101size = static_cast<size_t>(length);102103return size;104}105106const byte * SimpleKeyingInterface::GetIVAndThrowIfInvalid(const NameValuePairs ¶ms, size_t &size)107{108ConstByteArrayParameter ivWithLength;109const byte *iv = NULLPTR;110bool found = false;111112try {found = params.GetValue(Name::IV(), ivWithLength);}113catch (const NameValuePairs::ValueTypeMismatch &) {}114115if (found)116{117iv = ivWithLength.begin();118ThrowIfInvalidIV(iv);119size = ThrowIfInvalidIVLength(static_cast<int>(ivWithLength.size()));120}121else if (params.GetValue(Name::IV(), iv))122{123ThrowIfInvalidIV(iv);124size = static_cast<size_t>(IVSize());125}126else127{128ThrowIfResynchronizable();129size = 0;130}131132return iv;133}134135void SimpleKeyingInterface::GetNextIV(RandomNumberGenerator &rng, byte *iv)136{137rng.GenerateBlock(iv, IVSize());138}139140size_t BlockTransformation::AdvancedProcessBlocks(const byte *inBlocks, const byte *xorBlocks, byte *outBlocks, size_t length, word32 flags) const141{142CRYPTOPP_ASSERT(inBlocks);143CRYPTOPP_ASSERT(outBlocks);144CRYPTOPP_ASSERT(length);145146const unsigned int blockSize = BlockSize();147size_t inIncrement = (flags & (BT_InBlockIsCounter|BT_DontIncrementInOutPointers)) ? 0 : blockSize;148size_t xorIncrement = xorBlocks ? blockSize : 0;149size_t outIncrement = (flags & BT_DontIncrementInOutPointers) ? 0 : blockSize;150151if (flags & BT_ReverseDirection)152{153inBlocks = PtrAdd(inBlocks, length - blockSize);154xorBlocks = PtrAdd(xorBlocks, length - blockSize);155outBlocks = PtrAdd(outBlocks, length - blockSize);156inIncrement = 0-inIncrement;157xorIncrement = 0-xorIncrement;158outIncrement = 0-outIncrement;159}160161// Coverity finding.162const bool xorFlag = xorBlocks && (flags & BT_XorInput);163while (length >= blockSize)164{165if (xorFlag)166{167// xorBlocks non-NULL and with BT_XorInput.168xorbuf(outBlocks, xorBlocks, inBlocks, blockSize);169ProcessBlock(outBlocks);170}171else172{173// xorBlocks may be non-NULL and without BT_XorInput.174ProcessAndXorBlock(inBlocks, xorBlocks, outBlocks);175}176177if (flags & BT_InBlockIsCounter)178const_cast<byte *>(inBlocks)[blockSize-1]++;179180inBlocks = PtrAdd(inBlocks, inIncrement);181outBlocks = PtrAdd(outBlocks, outIncrement);182xorBlocks = PtrAdd(xorBlocks, xorIncrement);183length -= blockSize;184}185186return length;187}188189unsigned int BlockTransformation::OptimalDataAlignment() const190{191return GetAlignmentOf<word32>();192}193194unsigned int StreamTransformation::OptimalDataAlignment() const195{196return GetAlignmentOf<word32>();197}198199unsigned int HashTransformation::OptimalDataAlignment() const200{201return GetAlignmentOf<word32>();202}203204#if 0205void StreamTransformation::ProcessLastBlock(byte *outString, const byte *inString, size_t length)206{207CRYPTOPP_ASSERT(MinLastBlockSize() == 0); // this function should be overridden otherwise208209if (length == MandatoryBlockSize())210ProcessData(outString, inString, length);211else if (length != 0)212throw NotImplemented(AlgorithmName() + ": this object doesn't support a special last block");213}214#endif215216size_t StreamTransformation::ProcessLastBlock(byte *outString, size_t outLength, const byte *inString, size_t inLength)217{218// this function should be overridden otherwise219CRYPTOPP_ASSERT(MinLastBlockSize() == 0);220221if (inLength == MandatoryBlockSize())222{223outLength = inLength; // squash unused warning224ProcessData(outString, inString, inLength);225}226else if (inLength != 0)227throw NotImplemented(AlgorithmName() + ": this object doesn't support a special last block");228229return outLength;230}231232void AuthenticatedSymmetricCipher::SpecifyDataLengths(lword headerLength, lword messageLength, lword footerLength)233{234if (headerLength > MaxHeaderLength())235throw InvalidArgument(GetAlgorithm().AlgorithmName() + ": header length " + IntToString(headerLength) + " exceeds the maximum of " + IntToString(MaxHeaderLength()));236237if (messageLength > MaxMessageLength())238throw InvalidArgument(GetAlgorithm().AlgorithmName() + ": message length " + IntToString(messageLength) + " exceeds the maximum of " + IntToString(MaxMessageLength()));239240if (footerLength > MaxFooterLength())241throw InvalidArgument(GetAlgorithm().AlgorithmName() + ": footer length " + IntToString(footerLength) + " exceeds the maximum of " + IntToString(MaxFooterLength()));242243UncheckedSpecifyDataLengths(headerLength, messageLength, footerLength);244}245246void 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)247{248Resynchronize(iv, ivLength);249SpecifyDataLengths(headerLength, messageLength);250Update(header, headerLength);251ProcessString(ciphertext, message, messageLength);252TruncatedFinal(mac, macSize);253}254255bool 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)256{257Resynchronize(iv, ivLength);258SpecifyDataLengths(headerLength, ciphertextLength);259Update(header, headerLength);260ProcessString(message, ciphertext, ciphertextLength);261return TruncatedVerify(mac, macLength);262}263264std::string AuthenticatedSymmetricCipher::AlgorithmName() const265{266// Squash C4505 on Visual Studio 2008 and friends267return "Unknown";268}269270unsigned int RandomNumberGenerator::GenerateBit()271{272return GenerateByte() & 1;273}274275byte RandomNumberGenerator::GenerateByte()276{277byte b;278GenerateBlock(&b, 1);279return b;280}281282word32 RandomNumberGenerator::GenerateWord32(word32 min, word32 max)283{284const word32 range = max-min;285const unsigned int maxBits = BitPrecision(range);286287word32 value;288289do290{291GenerateBlock((byte *)&value, sizeof(value));292value = Crop(value, maxBits);293} while (value > range);294295return value+min;296}297298// Stack recursion below... GenerateIntoBufferedTransformation calls GenerateBlock,299// and GenerateBlock calls GenerateIntoBufferedTransformation. Ad infinitum. Also300// see http://github.com/weidai11/cryptopp/issues/38.301//302// According to Wei, RandomNumberGenerator is an interface, and it should not303// be instantiable. Its now spilt milk, and we are going to CRYPTOPP_ASSERT it in Debug304// builds to alert the programmer and throw in Release builds. Developers have305// a reference implementation in case its needed. If a programmer306// unintentionally lands here, then they should ensure use of a307// RandomNumberGenerator pointer or reference so polymorphism can provide the308// proper runtime dispatching.309310void RandomNumberGenerator::GenerateBlock(byte *output, size_t size)311{312CRYPTOPP_UNUSED(output), CRYPTOPP_UNUSED(size);313314ArraySink s(output, size);315GenerateIntoBufferedTransformation(s, DEFAULT_CHANNEL, size);316}317318void RandomNumberGenerator::DiscardBytes(size_t n)319{320GenerateIntoBufferedTransformation(TheBitBucket(), DEFAULT_CHANNEL, n);321}322323void RandomNumberGenerator::GenerateIntoBufferedTransformation(BufferedTransformation &target, const std::string &channel, lword length)324{325FixedSizeSecBlock<byte, 256> buffer;326while (length)327{328size_t len = UnsignedMin(buffer.size(), length);329GenerateBlock(buffer, len);330(void)target.ChannelPut(channel, buffer, len);331length -= len;332}333}334335size_t KeyDerivationFunction::MinDerivedKeyLength() const336{337return 0;338}339340size_t KeyDerivationFunction::MaxDerivedKeyLength() const341{342return static_cast<size_t>(-1);343}344345void KeyDerivationFunction::ThrowIfInvalidDerivedKeyLength(size_t length) const346{347if (!IsValidDerivedLength(length))348throw InvalidDerivedKeyLength(GetAlgorithm().AlgorithmName(), length);349}350351void KeyDerivationFunction::SetParameters(const NameValuePairs& params) {352CRYPTOPP_UNUSED(params);353}354355/// \brief Random Number Generator that does not produce random numbers356/// \details ClassNullRNG can be used for functions that require a RandomNumberGenerator357/// but don't actually use it. The class throws NotImplemented when a generation function is called.358/// \sa NullRNG()359class ClassNullRNG : public RandomNumberGenerator360{361public:362/// \brief The name of the generator363/// \returns the string \a NullRNGs364std::string AlgorithmName() const {return "NullRNG";}365366#if defined(CRYPTOPP_DOXYGEN_PROCESSING)367/// \brief An implementation that throws NotImplemented368byte GenerateByte () {}369/// \brief An implementation that throws NotImplemented370unsigned int GenerateBit () {}371/// \brief An implementation that throws NotImplemented372word32 GenerateWord32 (word32 min, word32 max) {}373#endif374375/// \brief An implementation that throws NotImplemented376void GenerateBlock(byte *output, size_t size)377{378CRYPTOPP_UNUSED(output); CRYPTOPP_UNUSED(size);379throw NotImplemented("NullRNG: NullRNG should only be passed to functions that don't need to generate random bytes");380}381382#if defined(CRYPTOPP_DOXYGEN_PROCESSING)383/// \brief An implementation that throws NotImplemented384void GenerateIntoBufferedTransformation (BufferedTransformation &target, const std::string &channel, lword length) {}385/// \brief An implementation that throws NotImplemented386void IncorporateEntropy (const byte *input, size_t length) {}387/// \brief An implementation that returns \p false388bool CanIncorporateEntropy () const {}389/// \brief An implementation that does nothing390void DiscardBytes (size_t n) {}391/// \brief An implementation that does nothing392void Shuffle (IT begin, IT end) {}393394private:395Clonable* Clone () const { return NULLPTR; }396#endif397};398399RandomNumberGenerator & NullRNG()400{401static ClassNullRNG s_nullRNG;402return s_nullRNG;403}404405bool HashTransformation::TruncatedVerify(const byte *digest, size_t digestLength)406{407// Allocate at least 1 for calculated to avoid triggering diagnostics408ThrowIfInvalidTruncatedSize(digestLength);409SecByteBlock calculated(digestLength ? digestLength : 1);410TruncatedFinal(calculated, digestLength);411return VerifyBufsEqual(calculated, digest, digestLength);412}413414void HashTransformation::ThrowIfInvalidTruncatedSize(size_t size) const415{416if (size > DigestSize())417throw InvalidArgument("HashTransformation: can't truncate a " + IntToString(DigestSize()) + " byte digest to " + IntToString(size) + " bytes");418}419420unsigned int BufferedTransformation::GetMaxWaitObjectCount() const421{422const BufferedTransformation *t = AttachedTransformation();423return t ? t->GetMaxWaitObjectCount() : 0;424}425426void BufferedTransformation::GetWaitObjects(WaitObjectContainer &container, CallStack const& callStack)427{428BufferedTransformation *t = AttachedTransformation();429if (t)430t->GetWaitObjects(container, callStack); // reduce clutter by not adding to stack here431}432433void BufferedTransformation::Initialize(const NameValuePairs ¶meters, int propagation)434{435CRYPTOPP_UNUSED(propagation);436CRYPTOPP_ASSERT(!AttachedTransformation());437IsolatedInitialize(parameters);438}439440bool BufferedTransformation::Flush(bool hardFlush, int propagation, bool blocking)441{442CRYPTOPP_UNUSED(propagation);443CRYPTOPP_ASSERT(!AttachedTransformation());444return IsolatedFlush(hardFlush, blocking);445}446447bool BufferedTransformation::MessageSeriesEnd(int propagation, bool blocking)448{449CRYPTOPP_UNUSED(propagation);450CRYPTOPP_ASSERT(!AttachedTransformation());451return IsolatedMessageSeriesEnd(blocking);452}453454byte * BufferedTransformation::ChannelCreatePutSpace(const std::string &channel, size_t &size)455{456byte* space = NULLPTR;457if (channel.empty())458space = CreatePutSpace(size);459else460throw NoChannelSupport(AlgorithmName());461return space;462}463464size_t BufferedTransformation::ChannelPut2(const std::string &channel, const byte *inString, size_t length, int messageEnd, bool blocking)465{466size_t size = 0;467if (channel.empty())468size = Put2(inString, length, messageEnd, blocking);469else470throw NoChannelSupport(AlgorithmName());471return size;472}473474size_t BufferedTransformation::ChannelPutModifiable2(const std::string &channel, byte *inString, size_t length, int messageEnd, bool blocking)475{476size_t size = 0;477if (channel.empty())478size = PutModifiable2(inString, length, messageEnd, blocking);479else480size = ChannelPut2(channel, inString, length, messageEnd, blocking);481return size;482}483484bool BufferedTransformation::ChannelFlush(const std::string &channel, bool hardFlush, int propagation, bool blocking)485{486bool result = 0;487if (channel.empty())488result = Flush(hardFlush, propagation, blocking);489else490throw NoChannelSupport(AlgorithmName());491return result;492}493494bool BufferedTransformation::ChannelMessageSeriesEnd(const std::string &channel, int propagation, bool blocking)495{496bool result = false;497if (channel.empty())498result = MessageSeriesEnd(propagation, blocking);499else500throw NoChannelSupport(AlgorithmName());501return result;502}503504lword BufferedTransformation::MaxRetrievable() const505{506lword size = 0;507if (AttachedTransformation())508size = AttachedTransformation()->MaxRetrievable();509else510size = CopyTo(TheBitBucket());511return size;512}513514bool BufferedTransformation::AnyRetrievable() const515{516bool result = false;517if (AttachedTransformation())518result = AttachedTransformation()->AnyRetrievable();519else520{521byte b;522result = Peek(b) != 0;523}524return result;525}526527size_t BufferedTransformation::Get(byte &outByte)528{529size_t size = 0;530if (AttachedTransformation())531size = AttachedTransformation()->Get(outByte);532else533size = Get(&outByte, 1);534return size;535}536537size_t BufferedTransformation::Get(byte *outString, size_t getMax)538{539size_t size = 0;540if (AttachedTransformation())541size = AttachedTransformation()->Get(outString, getMax);542else543{544ArraySink arraySink(outString, getMax);545size = (size_t)TransferTo(arraySink, getMax);546}547return size;548}549550size_t BufferedTransformation::Peek(byte &outByte) const551{552size_t size = 0;553if (AttachedTransformation())554size = AttachedTransformation()->Peek(outByte);555else556size = Peek(&outByte, 1);557return size;558}559560size_t BufferedTransformation::Peek(byte *outString, size_t peekMax) const561{562size_t size = 0;563if (AttachedTransformation())564size = AttachedTransformation()->Peek(outString, peekMax);565else566{567ArraySink arraySink(outString, peekMax);568size = (size_t)CopyTo(arraySink, peekMax);569}570return size;571}572573lword BufferedTransformation::Skip(lword skipMax)574{575lword size = 0;576if (AttachedTransformation())577size = AttachedTransformation()->Skip(skipMax);578else579size = TransferTo(TheBitBucket(), skipMax);580return size;581}582583lword BufferedTransformation::TotalBytesRetrievable() const584{585lword size = 0;586if (AttachedTransformation())587size = AttachedTransformation()->TotalBytesRetrievable();588else589size = MaxRetrievable();590return size;591}592593unsigned int BufferedTransformation::NumberOfMessages() const594{595unsigned int size = 0;596if (AttachedTransformation())597size = AttachedTransformation()->NumberOfMessages();598else599size = CopyMessagesTo(TheBitBucket());600return size;601}602603bool BufferedTransformation::AnyMessages() const604{605bool result = false;606if (AttachedTransformation())607result = AttachedTransformation()->AnyMessages();608else609result = NumberOfMessages() != 0;610return result;611}612613bool BufferedTransformation::GetNextMessage()614{615bool result = false;616if (AttachedTransformation())617result = AttachedTransformation()->GetNextMessage();618else619{620CRYPTOPP_ASSERT(!AnyMessages());621}622return result;623}624625unsigned int BufferedTransformation::SkipMessages(unsigned int count)626{627unsigned int size = 0;628if (AttachedTransformation())629size = AttachedTransformation()->SkipMessages(count);630else631size = TransferMessagesTo(TheBitBucket(), count);632return size;633}634635size_t BufferedTransformation::TransferMessagesTo2(BufferedTransformation &target, unsigned int &messageCount, const std::string &channel, bool blocking)636{637if (AttachedTransformation())638return AttachedTransformation()->TransferMessagesTo2(target, messageCount, channel, blocking);639else640{641unsigned int maxMessages = messageCount;642for (messageCount=0; messageCount < maxMessages && AnyMessages(); messageCount++)643{644size_t blockedBytes;645lword transferredBytes;646647while (AnyRetrievable())648{649// MaxRetrievable() instead of LWORD_MAX due to GH #962. If650// the target calls CreatePutSpace(), then the allocation651// size will be LWORD_MAX. That happens when target is a652// ByteQueue. Maybe ByteQueue should check the size, and if653// it is LWORD_MAX or -1, then use a default like 4096.654transferredBytes = MaxRetrievable();655blockedBytes = TransferTo2(target, transferredBytes, channel, blocking);656if (blockedBytes > 0)657return blockedBytes;658}659660if (target.ChannelMessageEnd(channel, GetAutoSignalPropagation(), blocking))661return 1;662663bool result = GetNextMessage();664CRYPTOPP_UNUSED(result); CRYPTOPP_ASSERT(result);665}666return 0;667}668}669670unsigned int BufferedTransformation::CopyMessagesTo(BufferedTransformation &target, unsigned int count, const std::string &channel) const671{672unsigned int size = 0;673if (AttachedTransformation())674size = AttachedTransformation()->CopyMessagesTo(target, count, channel);675return size;676}677678void BufferedTransformation::SkipAll()679{680if (AttachedTransformation())681AttachedTransformation()->SkipAll();682else683{684while (SkipMessages()) {}685while (Skip()) {}686}687}688689size_t BufferedTransformation::TransferAllTo2(BufferedTransformation &target, const std::string &channel, bool blocking)690{691if (AttachedTransformation())692return AttachedTransformation()->TransferAllTo2(target, channel, blocking);693else694{695CRYPTOPP_ASSERT(!NumberOfMessageSeries());696697unsigned int messageCount;698do699{700messageCount = UINT_MAX;701size_t blockedBytes = TransferMessagesTo2(target, messageCount, channel, blocking);702if (blockedBytes)703return blockedBytes;704}705while (messageCount != 0);706707lword byteCount;708do709{710byteCount = ULONG_MAX;711size_t blockedBytes = TransferTo2(target, byteCount, channel, blocking);712if (blockedBytes)713return blockedBytes;714}715while (byteCount != 0);716717return 0;718}719}720721void BufferedTransformation::CopyAllTo(BufferedTransformation &target, const std::string &channel) const722{723if (AttachedTransformation())724AttachedTransformation()->CopyAllTo(target, channel);725else726{727CRYPTOPP_ASSERT(!NumberOfMessageSeries());728while (CopyMessagesTo(target, UINT_MAX, channel)) {}729}730}731732void BufferedTransformation::SetRetrievalChannel(const std::string &channel)733{734if (AttachedTransformation())735AttachedTransformation()->SetRetrievalChannel(channel);736}737738size_t BufferedTransformation::ChannelPutWord16(const std::string &channel, word16 value, ByteOrder order, bool blocking)739{740PutWord(false, order, m_buf, value);741return ChannelPut(channel, m_buf, 2, blocking);742}743744size_t BufferedTransformation::ChannelPutWord32(const std::string &channel, word32 value, ByteOrder order, bool blocking)745{746PutWord(false, order, m_buf, value);747return ChannelPut(channel, m_buf, 4, blocking);748}749750size_t BufferedTransformation::ChannelPutWord64(const std::string &channel, word64 value, ByteOrder order, bool blocking)751{752PutWord(false, order, m_buf, value);753return ChannelPut(channel, m_buf, 8, blocking);754}755756size_t BufferedTransformation::PutWord16(word16 value, ByteOrder order, bool blocking)757{758return ChannelPutWord16(DEFAULT_CHANNEL, value, order, blocking);759}760761size_t BufferedTransformation::PutWord32(word32 value, ByteOrder order, bool blocking)762{763return ChannelPutWord32(DEFAULT_CHANNEL, value, order, blocking);764}765766size_t BufferedTransformation::PutWord64(word64 value, ByteOrder order, bool blocking)767{768return ChannelPutWord64(DEFAULT_CHANNEL, value, order, blocking);769}770771size_t BufferedTransformation::PeekWord16(word16 &value, ByteOrder order) const772{773byte buf[2] = {0, 0};774size_t len = Peek(buf, 2);775776if (order == BIG_ENDIAN_ORDER)777value = word16((buf[0] << 8) | buf[1]);778else779value = word16((buf[1] << 8) | buf[0]);780781return len;782}783784size_t BufferedTransformation::PeekWord32(word32 &value, ByteOrder order) const785{786byte buf[4] = {0, 0, 0, 0};787size_t len = Peek(buf, 4);788789if (order == BIG_ENDIAN_ORDER)790value = word32((buf[0] << 24) | (buf[1] << 16) |791(buf[2] << 8) | (buf[3] << 0));792else793value = word32((buf[3] << 24) | (buf[2] << 16) |794(buf[1] << 8) | (buf[0] << 0));795796return len;797}798799size_t BufferedTransformation::PeekWord64(word64 &value, ByteOrder order) const800{801byte buf[8] = {0, 0, 0, 0, 0, 0, 0, 0};802size_t len = Peek(buf, 8);803804if (order == BIG_ENDIAN_ORDER)805value = ((word64)buf[0] << 56) | ((word64)buf[1] << 48) | ((word64)buf[2] << 40) |806((word64)buf[3] << 32) | ((word64)buf[4] << 24) | ((word64)buf[5] << 16) |807((word64)buf[6] << 8) | (word64)buf[7];808else809value = ((word64)buf[7] << 56) | ((word64)buf[6] << 48) | ((word64)buf[5] << 40) |810((word64)buf[4] << 32) | ((word64)buf[3] << 24) | ((word64)buf[2] << 16) |811((word64)buf[1] << 8) | (word64)buf[0];812813return len;814}815816size_t BufferedTransformation::GetWord16(word16 &value, ByteOrder order)817{818return (size_t)Skip(PeekWord16(value, order));819}820821size_t BufferedTransformation::GetWord32(word32 &value, ByteOrder order)822{823return (size_t)Skip(PeekWord32(value, order));824}825826size_t BufferedTransformation::GetWord64(word64 &value, ByteOrder order)827{828return (size_t)Skip(PeekWord64(value, order));829}830831void BufferedTransformation::Attach(BufferedTransformation *newAttachment)832{833if (AttachedTransformation() && AttachedTransformation()->Attachable())834AttachedTransformation()->Attach(newAttachment);835else836Detach(newAttachment);837}838839void GeneratableCryptoMaterial::GenerateRandomWithKeySize(RandomNumberGenerator &rng, unsigned int keySize)840{841GenerateRandom(rng, MakeParameters("KeySize", (int)keySize));842}843844class PK_DefaultEncryptionFilter : public Unflushable<Filter>845{846public:847PK_DefaultEncryptionFilter(RandomNumberGenerator &rng, const PK_Encryptor &encryptor, BufferedTransformation *attachment, const NameValuePairs ¶meters)848: m_rng(rng), m_encryptor(encryptor), m_parameters(parameters)849{850Detach(attachment);851}852853size_t Put2(const byte *inString, size_t length, int messageEnd, bool blocking)854{855FILTER_BEGIN;856m_plaintextQueue.Put(inString, length);857858if (messageEnd)859{860{861size_t plaintextLength;862if (!SafeConvert(m_plaintextQueue.CurrentSize(), plaintextLength))863throw InvalidArgument("PK_DefaultEncryptionFilter: plaintext too long");864size_t ciphertextLength = m_encryptor.CiphertextLength(plaintextLength);865866SecByteBlock plaintext(plaintextLength);867m_plaintextQueue.Get(plaintext, plaintextLength);868m_ciphertext.resize(ciphertextLength);869m_encryptor.Encrypt(m_rng, plaintext, plaintextLength, m_ciphertext, m_parameters);870}871872FILTER_OUTPUT(1, m_ciphertext, m_ciphertext.size(), messageEnd);873}874FILTER_END_NO_MESSAGE_END;875}876877RandomNumberGenerator &m_rng;878const PK_Encryptor &m_encryptor;879const NameValuePairs &m_parameters;880ByteQueue m_plaintextQueue;881SecByteBlock m_ciphertext;882};883884BufferedTransformation * PK_Encryptor::CreateEncryptionFilter(RandomNumberGenerator &rng, BufferedTransformation *attachment, const NameValuePairs ¶meters) const885{886return new PK_DefaultEncryptionFilter(rng, *this, attachment, parameters);887}888889class PK_DefaultDecryptionFilter : public Unflushable<Filter>890{891public:892PK_DefaultDecryptionFilter(RandomNumberGenerator &rng, const PK_Decryptor &decryptor, BufferedTransformation *attachment, const NameValuePairs ¶meters)893: m_rng(rng), m_decryptor(decryptor), m_parameters(parameters)894{895Detach(attachment);896}897898size_t Put2(const byte *inString, size_t length, int messageEnd, bool blocking)899{900FILTER_BEGIN;901m_ciphertextQueue.Put(inString, length);902903if (messageEnd)904{905{906size_t ciphertextLength;907if (!SafeConvert(m_ciphertextQueue.CurrentSize(), ciphertextLength))908throw InvalidArgument("PK_DefaultDecryptionFilter: ciphertext too long");909size_t maxPlaintextLength = m_decryptor.MaxPlaintextLength(ciphertextLength);910911SecByteBlock ciphertext(ciphertextLength);912m_ciphertextQueue.Get(ciphertext, ciphertextLength);913m_plaintext.resize(maxPlaintextLength);914m_result = m_decryptor.Decrypt(m_rng, ciphertext, ciphertextLength, m_plaintext, m_parameters);915if (!m_result.isValidCoding)916throw InvalidCiphertext(m_decryptor.AlgorithmName() + ": invalid ciphertext");917}918919FILTER_OUTPUT(1, m_plaintext, m_result.messageLength, messageEnd);920}921FILTER_END_NO_MESSAGE_END;922}923924RandomNumberGenerator &m_rng;925const PK_Decryptor &m_decryptor;926const NameValuePairs &m_parameters;927ByteQueue m_ciphertextQueue;928SecByteBlock m_plaintext;929DecodingResult m_result;930};931932BufferedTransformation * PK_Decryptor::CreateDecryptionFilter(RandomNumberGenerator &rng, BufferedTransformation *attachment, const NameValuePairs ¶meters) const933{934return new PK_DefaultDecryptionFilter(rng, *this, attachment, parameters);935}936937size_t PK_Signer::Sign(RandomNumberGenerator &rng, PK_MessageAccumulator *messageAccumulator, byte *signature) const938{939member_ptr<PK_MessageAccumulator> m(messageAccumulator);940return SignAndRestart(rng, *m, signature, false);941}942943size_t PK_Signer::SignMessage(RandomNumberGenerator &rng, const byte *message, size_t messageLen, byte *signature) const944{945member_ptr<PK_MessageAccumulator> m(NewSignatureAccumulator(rng));946m->Update(message, messageLen);947return SignAndRestart(rng, *m, signature, false);948}949950size_t PK_Signer::SignMessageWithRecovery(RandomNumberGenerator &rng, const byte *recoverableMessage, size_t recoverableMessageLength,951const byte *nonrecoverableMessage, size_t nonrecoverableMessageLength, byte *signature) const952{953member_ptr<PK_MessageAccumulator> m(NewSignatureAccumulator(rng));954InputRecoverableMessage(*m, recoverableMessage, recoverableMessageLength);955m->Update(nonrecoverableMessage, nonrecoverableMessageLength);956return SignAndRestart(rng, *m, signature, false);957}958959bool PK_Verifier::Verify(PK_MessageAccumulator *messageAccumulator) const960{961member_ptr<PK_MessageAccumulator> m(messageAccumulator);962return VerifyAndRestart(*m);963}964965bool PK_Verifier::VerifyMessage(const byte *message, size_t messageLen, const byte *signature, size_t signatureLen) const966{967member_ptr<PK_MessageAccumulator> m(NewVerificationAccumulator());968InputSignature(*m, signature, signatureLen);969m->Update(message, messageLen);970return VerifyAndRestart(*m);971}972973DecodingResult PK_Verifier::Recover(byte *recoveredMessage, PK_MessageAccumulator *messageAccumulator) const974{975member_ptr<PK_MessageAccumulator> m(messageAccumulator);976return RecoverAndRestart(recoveredMessage, *m);977}978979DecodingResult PK_Verifier::RecoverMessage(byte *recoveredMessage,980const byte *nonrecoverableMessage, size_t nonrecoverableMessageLength,981const byte *signature, size_t signatureLength) const982{983member_ptr<PK_MessageAccumulator> m(NewVerificationAccumulator());984InputSignature(*m, signature, signatureLength);985m->Update(nonrecoverableMessage, nonrecoverableMessageLength);986return RecoverAndRestart(recoveredMessage, *m);987}988989void SimpleKeyAgreementDomain::GenerateKeyPair(RandomNumberGenerator &rng, byte *privateKey, byte *publicKey) const990{991GeneratePrivateKey(rng, privateKey);992GeneratePublicKey(rng, privateKey, publicKey);993}994995void AuthenticatedKeyAgreementDomain::GenerateStaticKeyPair(RandomNumberGenerator &rng, byte *privateKey, byte *publicKey) const996{997GenerateStaticPrivateKey(rng, privateKey);998GenerateStaticPublicKey(rng, privateKey, publicKey);999}10001001void AuthenticatedKeyAgreementDomain::GenerateEphemeralKeyPair(RandomNumberGenerator &rng, byte *privateKey, byte *publicKey) const1002{1003GenerateEphemeralPrivateKey(rng, privateKey);1004GenerateEphemeralPublicKey(rng, privateKey, publicKey);1005}10061007// Allow a distro or packager to override the build-time version1008// http://github.com/weidai11/cryptopp/issues/3711009#ifndef CRYPTOPP_BUILD_VERSION1010# define CRYPTOPP_BUILD_VERSION CRYPTOPP_VERSION1011#endif1012int LibraryVersion(CRYPTOPP_NOINLINE_DOTDOTDOT)1013{1014return CRYPTOPP_BUILD_VERSION;1015}10161017class NullNameValuePairs : public NameValuePairs1018{1019public:1020NullNameValuePairs() {} // Clang complains a default ctor must be available1021bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const1022{CRYPTOPP_UNUSED(name); CRYPTOPP_UNUSED(valueType); CRYPTOPP_UNUSED(pValue); return false;}1023};10241025#if HAVE_GCC_INIT_PRIORITY1026const std::string DEFAULT_CHANNEL __attribute__ ((init_priority (CRYPTOPP_INIT_PRIORITY + 25))) = "";1027const std::string AAD_CHANNEL __attribute__ ((init_priority (CRYPTOPP_INIT_PRIORITY + 26))) = "AAD";1028const NullNameValuePairs s_nullNameValuePairs __attribute__ ((init_priority (CRYPTOPP_INIT_PRIORITY + 27)));1029const NameValuePairs& g_nullNameValuePairs = s_nullNameValuePairs;1030#elif HAVE_MSC_INIT_PRIORITY1031#pragma warning(disable: 4073)1032#pragma init_seg(lib)1033const std::string DEFAULT_CHANNEL = "";1034const std::string AAD_CHANNEL = "AAD";1035const NullNameValuePairs s_nullNameValuePairs;1036const NameValuePairs& g_nullNameValuePairs = s_nullNameValuePairs;1037#pragma warning(default: 4073)1038#elif HAVE_XLC_INIT_PRIORITY1039#pragma priority(260)1040const std::string DEFAULT_CHANNEL = "";1041const std::string AAD_CHANNEL = "AAD";1042const NullNameValuePairs s_nullNameValuePairs;1043const NameValuePairs& g_nullNameValuePairs = s_nullNameValuePairs;1044#else1045const std::string DEFAULT_CHANNEL = "";1046const std::string AAD_CHANNEL = "AAD";1047const simple_ptr<NullNameValuePairs> s_pNullNameValuePairs(new NullNameValuePairs);1048const NameValuePairs &g_nullNameValuePairs = *s_pNullNameValuePairs.m_p;1049#endif10501051NAMESPACE_END // CryptoPP10521053#endif // CRYPTOPP_IMPORTS105410551056