diff --git a/Readme.txt b/Readme.txt index e7fe597b..b2dc2900 100644 --- a/Readme.txt +++ b/Readme.txt @@ -1,5 +1,5 @@ Crypto++: a C++ Class Library of Cryptographic Schemes -Version 6.0 (in development) +Version 5.2.2 (in development) This library includes: @@ -344,6 +344,7 @@ the mailing list. - fixed inability to instantiate PanamaMAC - fixed problems with inline documentation -6.0 - added SHA-224 +5.2.2 - added SHA-224 + - put SHA-256, SHA-384, SHA-512, RSASSA-PSS into DLL Written by Wei Dai diff --git a/bench.cpp b/bench.cpp index 65480ad4..c75d4704 100644 --- a/bench.cpp +++ b/bench.cpp @@ -231,6 +231,9 @@ void BenchmarkAll(double t) BenchMarkKeyless("Tiger", t); #endif BenchMarkKeyless("RIPE-MD160", t); + BenchMarkKeyless("RIPE-MD320", t); + BenchMarkKeyless("RIPE-MD128", t); + BenchMarkKeyless("RIPE-MD256", t); BenchMarkKeyless >("Panama Hash (little endian)", t); BenchMarkKeyless >("Panama Hash (big endian)", t); #ifdef WORD64_AVAILABLE @@ -280,7 +283,6 @@ void BenchmarkAll(double t) BenchMarkKeyedVariable("SHACAL-2 (512-bit key)", t, 64); #ifdef WORD64_AVAILABLE BenchMarkKeyedVariable("Camellia (128-bit key)", t, 16); - BenchMarkKeyedVariable("Camellia (192-bit key)", t, 24); BenchMarkKeyedVariable("Camellia (256-bit key)", t, 32); #endif BenchMarkKeyed("MD5-MAC", t); diff --git a/cryptlib.h b/cryptlib.h index fb6f5448..d65a2f09 100644 --- a/cryptlib.h +++ b/cryptlib.h @@ -4,7 +4,7 @@ classes that provide a uniform interface to this library. */ -/*! \mainpage Crypto++TM Library 5.2.1 Reference Manual +/*! \mainpage Crypto++® Library 5.2.2 Reference Manual
Abstract Base Classes
cryptlib.h diff --git a/dll.cpp b/dll.cpp index 24f4d8df..dcebc703 100644 --- a/dll.cpp +++ b/dll.cpp @@ -40,6 +40,20 @@ CRYPTOPP_DLL_TEMPLATE_CLASS AbstractEuclideanDomain; template<> const byte PKCS_DigestDecoration::decoration[] = {0x30,0x21,0x30,0x09,0x06,0x05,0x2B,0x0E,0x03,0x02,0x1A,0x05,0x00,0x04,0x14}; template<> const unsigned int PKCS_DigestDecoration::length = sizeof(PKCS_DigestDecoration::decoration); +template<> const byte PKCS_DigestDecoration::decoration[] = {0x30,0x31,0x30,0x0d,0x06,0x09,0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x01,0x05,0x00,0x04,0x20}; +template<> const unsigned int PKCS_DigestDecoration::length = sizeof(PKCS_DigestDecoration::decoration); + +template<> const byte PKCS_DigestDecoration::decoration[] = {0x30,0x41,0x30,0x0d,0x06,0x09,0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x02,0x05,0x00,0x04,0x30}; +template<> const unsigned int PKCS_DigestDecoration::length = sizeof(PKCS_DigestDecoration::decoration); + +template<> const byte PKCS_DigestDecoration::decoration[] = {0x30,0x51,0x30,0x0d,0x06,0x09,0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x03,0x05,0x00,0x04,0x40}; +template<> const unsigned int PKCS_DigestDecoration::length = sizeof(PKCS_DigestDecoration::decoration); + +template<> const byte EMSA2HashId::id = 0x33; +template<> const byte EMSA2HashId::id = 0x34; +template<> const byte EMSA2HashId::id = 0x36; +template<> const byte EMSA2HashId::id = 0x35; + NAMESPACE_END #endif diff --git a/dll.h b/dll.h index 0a175503..72c85bc8 100644 --- a/dll.h +++ b/dll.h @@ -26,6 +26,7 @@ #include "nbtheory.h" #include "osrng.h" #include "pkcspad.h" +#include "pssr.h" #include "randpool.h" #include "rsa.h" #include "sha.h" diff --git a/haval.h b/haval.h index 12926abd..23c4b440 100644 --- a/haval.h +++ b/haval.h @@ -6,6 +6,8 @@ NAMESPACE_BEGIN(CryptoPP) /// HAVAL +/*! \warning HAVAL with 128-bit or 160-bit output is considered insecure, and should not be used + unless you absolutely need it for compatibility. */ class HAVAL : public IteratedHash { public: diff --git a/iterhash.cpp b/iterhash.cpp index a863782a..3e01556f 100644 --- a/iterhash.cpp +++ b/iterhash.cpp @@ -6,11 +6,6 @@ NAMESPACE_BEGIN(CryptoPP) -HashInputTooLong::HashInputTooLong(const std::string &alg) - : InvalidDataFormat("IteratedHashBase: input data exceeds maximum allowed by hash function " + alg) -{ -} - template void IteratedHashBase::Update(const byte *input, unsigned int len) { HashWordType oldCountLo = m_countLo, oldCountHi = m_countHi; @@ -80,9 +75,17 @@ template byte * IteratedHashBase::CreateUpdateSpa template unsigned int IteratedHashBase::HashMultipleBlocks(const T *input, unsigned int length) { unsigned int blockSize = BlockSize(); + bool noReverse = NativeByteOrderIs(GetByteOrder()); do { - HashBlock(input); + if (noReverse) + HashEndianCorrectedBlock(input); + else + { + ByteReverse(this->m_data.begin(), input, this->BlockSize()); + HashEndianCorrectedBlock(this->m_data); + } + input += blockSize/sizeof(T); length -= blockSize; } @@ -111,4 +114,22 @@ template void IteratedHashBase::Restart() Init(); } +template void IteratedHashBase::TruncatedFinal(byte *digest, unsigned int size) +{ + this->ThrowIfInvalidTruncatedSize(size); + + PadLastBlock(this->BlockSize() - 2*sizeof(HashWordType)); + ByteOrder order = this->GetByteOrder(); + ConditionalByteReverse(order, this->m_data, this->m_data, this->BlockSize() - 2*sizeof(HashWordType)); + + this->m_data[this->m_data.size()-2] = order ? this->GetBitCountHi() : this->GetBitCountLo(); + this->m_data[this->m_data.size()-1] = order ? this->GetBitCountLo() : this->GetBitCountHi(); + + HashEndianCorrectedBlock(this->m_data); + ConditionalByteReverse(order, this->m_digest, this->m_digest, this->DigestSize()); + memcpy(digest, this->m_digest, size); + + this->Restart(); // reinit for next use +} + NAMESPACE_END diff --git a/iterhash.h b/iterhash.h index 899a89f5..4453c82b 100644 --- a/iterhash.h +++ b/iterhash.h @@ -12,7 +12,8 @@ NAMESPACE_BEGIN(CryptoPP) class CRYPTOPP_DLL HashInputTooLong : public InvalidDataFormat { public: - explicit HashInputTooLong(const std::string &alg); + explicit HashInputTooLong(const std::string &alg) + : InvalidDataFormat("IteratedHashBase: input data exceeds maximum allowed by hash function " + alg) {} }; //! _ @@ -29,6 +30,7 @@ public: void Update(const byte *input, unsigned int length); byte * CreateUpdateSpace(unsigned int &size); void Restart(); + void TruncatedFinal(byte *digest, unsigned int size); protected: void SetBlockSize(unsigned int blockSize) {m_data.resize(blockSize / sizeof(HashWordType));} @@ -37,10 +39,13 @@ protected: T GetBitCountHi() const {return (m_countLo >> (8*sizeof(T)-3)) + (m_countHi << 3);} T GetBitCountLo() const {return m_countLo << 3;} - virtual unsigned int HashMultipleBlocks(const T *input, unsigned int length); void PadLastBlock(unsigned int lastBlockSize, byte padFirst=0x80); virtual void Init() =0; - virtual void HashBlock(const T *input) =0; + + virtual ByteOrder GetByteOrder() const =0; + virtual void HashEndianCorrectedBlock(const HashWordType *data) =0; + virtual unsigned int HashMultipleBlocks(const T *input, unsigned int length); + void HashBlock(const HashWordType *input) {HashMultipleBlocks(input, BlockSize());} SecBlock m_data; // Data buffer SecBlock m_digest; // Message digest @@ -50,7 +55,7 @@ private: }; #ifdef WORD64_AVAILABLE -CRYPTOPP_STATIC_TEMPLATE_CLASS IteratedHashBase; +CRYPTOPP_DLL_TEMPLATE_CLASS IteratedHashBase; CRYPTOPP_STATIC_TEMPLATE_CLASS IteratedHashBase; #endif @@ -58,33 +63,23 @@ CRYPTOPP_DLL_TEMPLATE_CLASS IteratedHashBase; CRYPTOPP_STATIC_TEMPLATE_CLASS IteratedHashBase; //! _ -template -class CRYPTOPP_NO_VTABLE IteratedHashBase2 : public IteratedHashBase +template +class CRYPTOPP_NO_VTABLE IteratedHash : public IteratedHashBase { public: - typedef B ByteOrderClass; - typedef typename IteratedHashBase::HashWordType HashWordType; + typedef T_Endianness ByteOrderClass; + typedef T_HashWordType HashWordType; + + enum {BLOCKSIZE = T_BlockSize}; + CRYPTOPP_COMPILE_ASSERT((BLOCKSIZE & (BLOCKSIZE - 1)) == 0); // blockSize is a power of 2 + + ByteOrder GetByteOrder() const {return T_Endianness::ToEnum();} inline static void CorrectEndianess(HashWordType *out, const HashWordType *in, unsigned int byteCount) { - ConditionalByteReverse(B::ToEnum(), out, in, byteCount); + ConditionalByteReverse(T_Endianness::ToEnum(), out, in, byteCount); } - void TruncatedFinal(byte *digest, unsigned int size); - -protected: - void HashBlock(const HashWordType *input); - virtual void HashEndianCorrectedBlock(const HashWordType *data) =0; -}; - -//! _ -template -class CRYPTOPP_NO_VTABLE IteratedHash : public IteratedHashBase2 -{ -public: - enum {BLOCKSIZE = T_BlockSize}; - CRYPTOPP_COMPILE_ASSERT((BLOCKSIZE & (BLOCKSIZE - 1)) == 0); // blockSize is a power of 2 - protected: IteratedHash() {this->SetBlockSize(T_BlockSize);} }; @@ -108,36 +103,6 @@ protected: void Init() {T_Transform::InitState(this->m_digest);} }; -// ************************************************************* - -template void IteratedHashBase2::TruncatedFinal(byte *digest, unsigned int size) -{ - this->ThrowIfInvalidTruncatedSize(size); - - PadLastBlock(this->BlockSize() - 2*sizeof(HashWordType)); - CorrectEndianess(this->m_data, this->m_data, this->BlockSize() - 2*sizeof(HashWordType)); - - this->m_data[this->m_data.size()-2] = B::ToEnum() ? this->GetBitCountHi() : this->GetBitCountLo(); - this->m_data[this->m_data.size()-1] = B::ToEnum() ? this->GetBitCountLo() : this->GetBitCountHi(); - - HashEndianCorrectedBlock(this->m_data); - CorrectEndianess(this->m_digest, this->m_digest, this->DigestSize()); - memcpy(digest, this->m_digest, size); - - this->Restart(); // reinit for next use -} - -template void IteratedHashBase2::HashBlock(const HashWordType *input) -{ - if (NativeByteOrderIs(B::ToEnum())) - HashEndianCorrectedBlock(input); - else - { - ByteReverse(this->m_data.begin(), input, this->BlockSize()); - HashEndianCorrectedBlock(this->m_data); - } -} - NAMESPACE_END #endif diff --git a/md4.h b/md4.h index b33104ca..bf5399c1 100644 --- a/md4.h +++ b/md4.h @@ -7,7 +7,7 @@ NAMESPACE_BEGIN(CryptoPP) //! MD4 /*! \warning MD4 is considered insecure, and should not be used - unless you absolutely need compatibility with a broken product. */ + unless you absolutely need it for compatibility. */ class MD4 : public IteratedHashWithStaticTransform { public: diff --git a/md5.h b/md5.h index f17780ed..7fb9f172 100644 --- a/md5.h +++ b/md5.h @@ -6,7 +6,8 @@ NAMESPACE_BEGIN(CryptoPP) //! MD5 -/*! 128 Bit Hash */ +/*! \warning MD5 is considered insecure, and should not be used + unless you absolutely need it for compatibility. */ class MD5 : public IteratedHashWithStaticTransform { public: diff --git a/pkcspad.cpp b/pkcspad.cpp index cbccb15c..a51858cc 100644 --- a/pkcspad.cpp +++ b/pkcspad.cpp @@ -7,6 +7,7 @@ NAMESPACE_BEGIN(CryptoPP) +// more in dll.cpp template<> const byte PKCS_DigestDecoration::decoration[] = {0x30,0x20,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x02,0x05,0x00,0x04,0x10}; template<> const unsigned int PKCS_DigestDecoration::length = sizeof(PKCS_DigestDecoration::decoration); @@ -19,15 +20,6 @@ template<> const unsigned int PKCS_DigestDecoration::length = sizeof( template<> const byte PKCS_DigestDecoration::decoration[] = {0x30,0x29,0x30,0x0D,0x06,0x09,0x2B,0x06,0x01,0x04,0x01,0xDA,0x47,0x0C,0x02,0x05,0x00,0x04,0x18}; template<> const unsigned int PKCS_DigestDecoration::length = sizeof(PKCS_DigestDecoration::decoration); -template<> const byte PKCS_DigestDecoration::decoration[] = {0x30,0x31,0x30,0x0d,0x06,0x09,0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x01,0x05,0x00,0x04,0x20}; -template<> const unsigned int PKCS_DigestDecoration::length = sizeof(PKCS_DigestDecoration::decoration); - -template<> const byte PKCS_DigestDecoration::decoration[] = {0x30,0x41,0x30,0x0d,0x06,0x09,0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x02,0x05,0x00,0x04,0x30}; -template<> const unsigned int PKCS_DigestDecoration::length = sizeof(PKCS_DigestDecoration::decoration); - -template<> const byte PKCS_DigestDecoration::decoration[] = {0x30,0x51,0x30,0x0d,0x06,0x09,0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x03,0x05,0x00,0x04,0x40}; -template<> const unsigned int PKCS_DigestDecoration::length = sizeof(PKCS_DigestDecoration::decoration); - unsigned int PKCS_EncryptionPaddingScheme::MaxUnpaddedLength(unsigned int paddedLength) const { return SaturatingSubtract(paddedLength/8, 10U); diff --git a/pkcspad.h b/pkcspad.h index 93bc3f17..f3d31db4 100644 --- a/pkcspad.h +++ b/pkcspad.h @@ -40,6 +40,13 @@ class SHA384; class SHA512; // end of list +#ifdef CRYPTOPP_IS_DLL +CRYPTOPP_DLL_TEMPLATE_CLASS PKCS_DigestDecoration; +CRYPTOPP_DLL_TEMPLATE_CLASS PKCS_DigestDecoration; +CRYPTOPP_DLL_TEMPLATE_CLASS PKCS_DigestDecoration; +CRYPTOPP_DLL_TEMPLATE_CLASS PKCS_DigestDecoration; +#endif + //! EMSA-PKCS1-v1_5 class CRYPTOPP_DLL PKCS1v15_SignatureMessageEncodingMethod : public PK_DeterministicSignatureMessageEncodingMethod { @@ -75,10 +82,6 @@ struct PKCS1v15 : public SignatureStandard, public EncryptionStandard typedef PKCS1v15_SignatureMessageEncodingMethod SignatureMessageEncodingMethod; }; -#ifdef CRYPTOPP_IS_DLL -CRYPTOPP_DLL_TEMPLATE_CLASS PKCS_DigestDecoration; -#endif - NAMESPACE_END #endif diff --git a/pssr.cpp b/pssr.cpp index 2589b14b..19360d3a 100644 --- a/pssr.cpp +++ b/pssr.cpp @@ -5,14 +5,13 @@ NAMESPACE_BEGIN(CryptoPP) -template<> const byte EMSA2HashId::id = 0x33; +// more in dll.cpp template<> const byte EMSA2HashId::id = 0x31; template<> const byte EMSA2HashId::id = 0x32; -template<> const byte EMSA2HashId::id = 0x34; -template<> const byte EMSA2HashId::id = 0x36; -template<> const byte EMSA2HashId::id = 0x35; template<> const byte EMSA2HashId::id = 0x37; +#ifndef CRYPTOPP_IMPORTS + unsigned int PSSR_MEM_Base::MaxRecoverableLength(unsigned int representativeBitLength, unsigned int hashIdentifierLength, unsigned int digestLength) const { if (AllowRecovery()) @@ -128,4 +127,6 @@ DecodingResult PSSR_MEM_Base::RecoverMessageFromRepresentative( return result; } +#endif + NAMESPACE_END diff --git a/pssr.h b/pssr.h index 9e12e90d..6389beab 100644 --- a/pssr.h +++ b/pssr.h @@ -4,9 +4,13 @@ #include "pubkey.h" #include +#ifdef CRYPTOPP_IS_DLL +#include "sha.h" +#endif + NAMESPACE_BEGIN(CryptoPP) -class PSSR_MEM_Base : public PK_RecoverableSignatureMessageEncodingMethod +class CRYPTOPP_DLL PSSR_MEM_Base : public PK_RecoverableSignatureMessageEncodingMethod { virtual bool AllowRecovery() const =0; virtual unsigned int SaltLen(unsigned int hashLen) const =0; @@ -28,8 +32,9 @@ public: byte *recoverableMessage) const; }; -template struct EMSA2HashId +template class EMSA2HashId { +public: static const byte id; }; @@ -43,6 +48,13 @@ class SHA512; class Whirlpool; // end of list +#ifdef CRYPTOPP_IS_DLL +CRYPTOPP_DLL_TEMPLATE_CLASS EMSA2HashId; +CRYPTOPP_DLL_TEMPLATE_CLASS EMSA2HashId; +CRYPTOPP_DLL_TEMPLATE_CLASS EMSA2HashId; +CRYPTOPP_DLL_TEMPLATE_CLASS EMSA2HashId; +#endif + template class EMSA2HashIdLookup : public BASE { diff --git a/ripemd.h b/ripemd.h index 40fd8f4f..56871a91 100644 --- a/ripemd.h +++ b/ripemd.h @@ -15,7 +15,7 @@ public: static const char * StaticAlgorithmName() {return "RIPEMD-160";} }; -/*! Digest Length = 320 bits, Security = 160 bits */ +/*! Digest Length = 320 bits, Security is similar to RIPEMD-160 */ class RIPEMD320 : public IteratedHashWithStaticTransform { public: @@ -24,7 +24,8 @@ public: static const char * StaticAlgorithmName() {return "RIPEMD-320";} }; -/*! Digest Length = 128 bits */ +/*! \warning RIPEMD-128 is considered insecure, and should not be used + unless you absolutely need it for compatibility. */ class RIPEMD128 : public IteratedHashWithStaticTransform { public: @@ -33,7 +34,8 @@ public: static const char * StaticAlgorithmName() {return "RIPEMD-128";} }; -/*! Digest Length = 256 bits, Security = 128 bits */ +/*! \warning RIPEMD-256 is considered insecure, and should not be used + unless you absolutely need it for compatibility. */ class RIPEMD256 : public IteratedHashWithStaticTransform { public: diff --git a/sha.cpp b/sha.cpp index 7ce449aa..ff3a2cb5 100644 --- a/sha.cpp +++ b/sha.cpp @@ -4,6 +4,9 @@ // Both are in the public domain. #include "pch.h" + +#ifndef CRYPTOPP_IMPORTS + #include "sha.h" #include "misc.h" @@ -14,8 +17,6 @@ NAMESPACE_BEGIN(CryptoPP) #define blk0(i) (W[i] = data[i]) #define blk1(i) (W[i&15] = rotlFixed(W[(i+13)&15]^W[(i+8)&15]^W[(i+2)&15]^W[i&15],1)) -#ifndef CRYPTOPP_IMPORTS - void SHA::InitState(HashWordType *state) { state[0] = 0x67452301L; @@ -78,8 +79,6 @@ void SHA::Transform(word32 *state, const word32 *data) memset(W, 0, sizeof(W)); } -#endif // #ifndef CRYPTOPP_IMPORTS - // end of Steve Reid's code // ************************************************************* @@ -291,3 +290,5 @@ void SHA384::InitState(HashWordType *state) #endif NAMESPACE_END + +#endif // #ifndef CRYPTOPP_IMPORTS diff --git a/sha.h b/sha.h index e0ac2eac..2ef53af8 100644 --- a/sha.h +++ b/sha.h @@ -17,7 +17,7 @@ public: typedef SHA SHA1; //! implements the SHA-256 standard -class SHA256 : public IteratedHashWithStaticTransform +class CRYPTOPP_DLL SHA256 : public IteratedHashWithStaticTransform { public: static void InitState(HashWordType *state); @@ -29,7 +29,7 @@ protected: }; //! implements the SHA-224 standard -class SHA224 : public IteratedHashWithStaticTransform +class CRYPTOPP_DLL SHA224 : public IteratedHashWithStaticTransform { public: static void InitState(HashWordType *state); @@ -40,7 +40,7 @@ public: #ifdef WORD64_AVAILABLE //! implements the SHA-512 standard -class SHA512 : public IteratedHashWithStaticTransform +class CRYPTOPP_DLL SHA512 : public IteratedHashWithStaticTransform { public: static void InitState(HashWordType *state); @@ -52,7 +52,7 @@ protected: }; //! implements the SHA-384 standard -class SHA384 : public IteratedHashWithStaticTransform +class CRYPTOPP_DLL SHA384 : public IteratedHashWithStaticTransform { public: static void InitState(HashWordType *state);