From caf9e032e6b4ccb114a74a3936c916bcfaba262d Mon Sep 17 00:00:00 2001 From: weidai Date: Mon, 2 Mar 2009 02:39:17 +0000 Subject: changes for 5.6: - added AuthenticatedSymmetricCipher interface class and Filter wrappers - added CCM, GCM (with SSE2 assembly), CMAC, and SEED - improved AES speed on x86 and x64 - removed WORD64_AVAILABLE; compiler 64-bit int support is now required git-svn-id: svn://svn.code.sf.net/p/cryptopp/code/trunk/c5@433 57ff6487-cd31-0410-9ec3-f628ee90f5f0 --- cryptlib.cpp | 123 ++++++++++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 101 insertions(+), 22 deletions(-) (limited to 'cryptlib.cpp') diff --git a/cryptlib.cpp b/cryptlib.cpp index bbab37c..1d0a002 100644 --- a/cryptlib.cpp +++ b/cryptlib.cpp @@ -21,9 +21,7 @@ NAMESPACE_BEGIN(CryptoPP) CRYPTOPP_COMPILE_ASSERT(sizeof(byte) == 1); CRYPTOPP_COMPILE_ASSERT(sizeof(word16) == 2); CRYPTOPP_COMPILE_ASSERT(sizeof(word32) == 4); -#ifdef WORD64_AVAILABLE CRYPTOPP_COMPILE_ASSERT(sizeof(word64) == 8); -#endif #ifdef CRYPTOPP_NATIVE_DWORD_AVAILABLE CRYPTOPP_COMPILE_ASSERT(sizeof(dword) == 2*sizeof(word)); #endif @@ -60,9 +58,9 @@ void SimpleKeyingInterface::SetKeyWithRounds(const byte *key, size_t length, int SetKey(key, length, MakeParameters(Name::Rounds(), rounds)); } -void SimpleKeyingInterface::SetKeyWithIV(const byte *key, size_t length, const byte *iv) +void SimpleKeyingInterface::SetKeyWithIV(const byte *key, size_t length, const byte *iv, size_t ivLength) { - SetKey(key, length, MakeParameters(Name::IV(), iv)); + SetKey(key, length, MakeParameters(Name::IV(), ConstByteArrayParameter(iv, ivLength))); } void SimpleKeyingInterface::ThrowIfInvalidKeyLength(size_t length) @@ -83,14 +81,46 @@ void SimpleKeyingInterface::ThrowIfInvalidIV(const byte *iv) throw InvalidArgument(GetAlgorithm().AlgorithmName() + ": this object cannot use a null IV"); } -const byte * SimpleKeyingInterface::GetIVAndThrowIfInvalid(const NameValuePairs ¶ms) +size_t SimpleKeyingInterface::ThrowIfInvalidIVLength(int size) +{ + if (size < 0) + return IVSize(); + else if ((size_t)size < MinIVLength()) + throw InvalidArgument(GetAlgorithm().AlgorithmName() + ": IV length " + IntToString(size) + " is less than the minimum of " + IntToString(MinIVLength())); + else if ((size_t)size > MaxIVLength()) + throw InvalidArgument(GetAlgorithm().AlgorithmName() + ": IV length " + IntToString(size) + " exceeds the maximum of " + IntToString(MaxIVLength())); + else + return size; +} + +const byte * SimpleKeyingInterface::GetIVAndThrowIfInvalid(const NameValuePairs ¶ms, size_t &size) { + ConstByteArrayParameter ivWithLength; const byte *iv; - if (params.GetValue(Name::IV(), iv)) + bool found = false; + + try {found = params.GetValue(Name::IV(), ivWithLength);} + catch (const NameValuePairs::ValueTypeMismatch &) {} + + if (found) + { + iv = ivWithLength.begin(); ThrowIfInvalidIV(iv); + size = ThrowIfInvalidIVLength((int)ivWithLength.size()); + return iv; + } + else if (params.GetValue(Name::IV(), iv)) + { + ThrowIfInvalidIV(iv); + size = IVSize(); + return iv; + } else + { ThrowIfResynchronizable(); - return iv; + size = 0; + return NULL; + } } void SimpleKeyingInterface::GetNextIV(RandomNumberGenerator &rng, byte *IV) @@ -98,20 +128,55 @@ void SimpleKeyingInterface::GetNextIV(RandomNumberGenerator &rng, byte *IV) rng.GenerateBlock(IV, IVSize()); } -void BlockTransformation::ProcessAndXorMultipleBlocks(const byte *inBlocks, const byte *xorBlocks, byte *outBlocks, size_t numberOfBlocks) const +size_t BlockTransformation::AdvancedProcessBlocks(const byte *inBlocks, const byte *xorBlocks, byte *outBlocks, size_t length, word32 flags) const { - unsigned int blockSize = BlockSize(); - while (numberOfBlocks--) + size_t blockSize = BlockSize(); + size_t inIncrement = (flags & (BT_InBlockIsCounter|BT_DontIncrementInOutPointers)) ? 0 : blockSize; + size_t xorIncrement = xorBlocks ? blockSize : 0; + size_t outIncrement = (flags & BT_DontIncrementInOutPointers) ? 0 : blockSize; + + if (flags & BT_ReverseDirection) + { + assert(length % blockSize == 0); + inBlocks += length - blockSize; + xorBlocks += length - blockSize; + outBlocks += length - blockSize; + inIncrement = 0-inIncrement; + xorIncrement = 0-xorIncrement; + outIncrement = 0-outIncrement; + } + + while (length >= blockSize) { - ProcessAndXorBlock(inBlocks, xorBlocks, outBlocks); - inBlocks += blockSize; - outBlocks += blockSize; - if (xorBlocks) - xorBlocks += blockSize; + if (flags & BT_XorInput) + { + xorbuf(outBlocks, xorBlocks, inBlocks, blockSize); + ProcessBlock(outBlocks); + } + else + ProcessAndXorBlock(inBlocks, xorBlocks, outBlocks); + if (flags & BT_InBlockIsCounter) + const_cast(inBlocks)[blockSize-1]++; + inBlocks += inIncrement; + outBlocks += outIncrement; + xorBlocks += xorIncrement; + length -= blockSize; } + + return length; } -unsigned int BlockTransformation::BlockAlignment() const +unsigned int BlockTransformation::OptimalDataAlignment() const +{ + return GetAlignmentOf(); +} + +unsigned int StreamTransformation::OptimalDataAlignment() const +{ + return GetAlignmentOf(); +} + +unsigned int HashTransformation::OptimalDataAlignment() const { return GetAlignmentOf(); } @@ -123,7 +188,21 @@ void StreamTransformation::ProcessLastBlock(byte *outString, const byte *inStrin if (length == MandatoryBlockSize()) ProcessData(outString, inString, length); else if (length != 0) - throw NotImplemented("StreamTransformation: this object does't support a special last block"); + throw NotImplemented(AlgorithmName() + ": this object does't support a special last block"); +} + +void AuthenticatedSymmetricCipher::SpecifyDataLengths(lword headerLength, lword messageLength, lword footerLength) +{ + if (headerLength > MaxHeaderLength()) + throw InvalidArgument(GetAlgorithm().AlgorithmName() + ": header length " + IntToString(headerLength) + " exceeds the maximum of " + IntToString(MaxHeaderLength())); + + if (messageLength > MaxMessageLength()) + throw InvalidArgument(GetAlgorithm().AlgorithmName() + ": message length " + IntToString(messageLength) + " exceeds the maximum of " + IntToString(MaxMessageLength())); + + if (footerLength > MaxFooterLength()) + throw InvalidArgument(GetAlgorithm().AlgorithmName() + ": footer length " + IntToString(footerLength) + " exceeds the maximum of " + IntToString(MaxFooterLength())); + + UncheckedSpecifyDataLengths(headerLength, messageLength, footerLength); } unsigned int RandomNumberGenerator::GenerateBit() @@ -196,7 +275,7 @@ bool HashTransformation::TruncatedVerify(const byte *digestIn, size_t digestLeng ThrowIfInvalidTruncatedSize(digestLength); SecByteBlock digest(digestLength); TruncatedFinal(digest, digestLength); - return memcmp(digest, digestIn, digestLength) == 0; + return VerifyBufsEqual(digest, digestIn, digestLength); } void HashTransformation::ThrowIfInvalidTruncatedSize(size_t size) const @@ -241,7 +320,7 @@ byte * BufferedTransformation::ChannelCreatePutSpace(const std::string &channel, if (channel.empty()) return CreatePutSpace(size); else - throw NoChannelSupport(); + throw NoChannelSupport(AlgorithmName()); } size_t BufferedTransformation::ChannelPut2(const std::string &channel, const byte *begin, size_t length, int messageEnd, bool blocking) @@ -249,7 +328,7 @@ size_t BufferedTransformation::ChannelPut2(const std::string &channel, const byt if (channel.empty()) return Put2(begin, length, messageEnd, blocking); else - throw NoChannelSupport(); + throw NoChannelSupport(AlgorithmName()); } size_t BufferedTransformation::ChannelPutModifiable2(const std::string &channel, byte *begin, size_t length, int messageEnd, bool blocking) @@ -265,7 +344,7 @@ bool BufferedTransformation::ChannelFlush(const std::string &channel, bool compl if (channel.empty()) return Flush(completeFlush, propagation, blocking); else - throw NoChannelSupport(); + throw NoChannelSupport(AlgorithmName()); } bool BufferedTransformation::ChannelMessageSeriesEnd(const std::string &channel, int propagation, bool blocking) @@ -273,7 +352,7 @@ bool BufferedTransformation::ChannelMessageSeriesEnd(const std::string &channel, if (channel.empty()) return MessageSeriesEnd(propagation, blocking); else - throw NoChannelSupport(); + throw NoChannelSupport(AlgorithmName()); } lword BufferedTransformation::MaxRetrievable() const -- cgit v1.2.1