diff --git a/CryptoPP/License.txt b/CryptoPP/License.txt index 043e4b698..c5d3f34b1 100644 --- a/CryptoPP/License.txt +++ b/CryptoPP/License.txt @@ -1,4 +1,4 @@ -Compilation Copyright (c) 1995-2010 by Wei Dai. All rights reserved. +Compilation Copyright (c) 1995-2013 by Wei Dai. All rights reserved. This copyright applies only to this software distribution package as a compilation, and does not imply a copyright on any particular file in the package. @@ -21,42 +21,31 @@ Paulo Baretto - rijndael.cpp, skipjack.cpp, square.cpp Richard De Moliner - safer.cpp Matthew Skala - twofish.cpp Kevin Springle - camellia.cpp, shacal2.cpp, ttmac.cpp, whrlpool.cpp, ripemd.cpp +Ronny Van Keer - sha3.cpp -Permission to use, copy, modify, and distribute this compilation for -any purpose, including commercial applications, is hereby granted -without fee, subject to the following restrictions: +The Crypto++ Library (as a compilation) is currently licensed under the Boost +Software License 1.0 (http://www.boost.org/users/license.html). -1. Any copy or modification of this compilation in any form, except -in object code form as part of an application software, must include -the above copyright notice and this license. +Boost Software License - Version 1.0 - August 17th, 2003 -2. Users of this software agree that any modification or extension -they provide to Wei Dai will be considered public domain and not -copyrighted unless it includes an explicit copyright notice. +Permission is hereby granted, free of charge, to any person or organization +obtaining a copy of the software and accompanying documentation covered by +this license (the "Software") to use, reproduce, display, distribute, +execute, and transmit the Software, and to prepare derivative works of the +Software, and to permit third-parties to whom the Software is furnished to +do so, all subject to the following: -3. Wei Dai makes no warranty or representation that the operation of the -software in this compilation will be error-free, and Wei Dai is under no -obligation to provide any services, by way of maintenance, update, or -otherwise. THE SOFTWARE AND ANY DOCUMENTATION ARE PROVIDED "AS IS" -WITHOUT EXPRESS OR IMPLIED WARRANTY INCLUDING, BUT NOT LIMITED TO, -THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. IN NO EVENT WILL WEI DAI OR ANY OTHER CONTRIBUTOR BE LIABLE FOR -DIRECT, INCIDENTAL OR CONSEQUENTIAL DAMAGES, EVEN IF -ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. +The copyright notices in the Software and this entire statement, including +the above license grant, this restriction and the following disclaimer, +must be included in all copies of the Software, in whole or in part, and +all derivative works of the Software, unless such copies or derivative +works are solely in the form of machine-executable object code generated by +a source language processor. -4. Users will not use Wei Dai or any other contributor's name in any -publicity or advertising, without prior written consent in each case. - -5. Export of this software from the United States may require a -specific license from the United States Government. It is the -responsibility of any person or organization contemplating export -to obtain such a license before exporting. - -6. Certain parts of this software may be protected by patents. It -is the users' responsibility to obtain the appropriate -licenses before using those parts. - -If this compilation is used in object code form in an application -software, acknowledgement of the author is not required but would be -appreciated. The contribution of any useful modifications or extensions -to Wei Dai is not required but would also be appreciated. +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. \ No newline at end of file diff --git a/CryptoPP/Readme.txt b/CryptoPP/Readme.txt index 2f04e9f28..5f3b4525d 100644 --- a/CryptoPP/Readme.txt +++ b/CryptoPP/Readme.txt @@ -1,5 +1,5 @@ Crypto++: a C++ Class Library of Cryptographic Schemes -Version 5.6.2 (in development) +Version 5.6.2 - 2/20/2013 Crypto++ Library is a free C++ class library of cryptographic schemes. Currently the library contains the following algorithms: @@ -24,7 +24,7 @@ Currently the library contains the following algorithms: Two-Track-MAC SHA-1, SHA-2 (SHA-224, SHA-256, SHA-384, and - hash functions SHA-512), Tiger, WHIRLPOOL, RIPEMD-128, + hash functions SHA-512), SHA-3, Tiger, WHIRLPOOL, RIPEMD-128, RIPEMD-256, RIPEMD-160, RIPEMD-320 RSA, DSA, ElGamal, Nyberg-Rueppel (NR), @@ -441,4 +441,12 @@ the mailing list. - ported to MSVC 2010, GCC 4.5.1, Sun Studio 12u1, C++Builder 2010, Intel C++ Compiler 11.1 - renamed the MSVC DLL project to "cryptopp" for compatibility with MSVC 2010 +5.6.2 - changed license to Boost Software License 1.0 + - added SHA-3 (Keccak) + - updated DSA to FIPS 186-3 (see DSA2 class) + - fixed Blowfish minimum keylength to be 4 bytes (32 bits) + - fixed Salsa validation failure when compiling with GCC 4.6 + - fixed infinite recursion when on x64, assembly disabled, and no AESNI + - ported to MSVC 2012, GCC 4.7, Clang 3.2, Solaris Studio 12.3, Intel C++ Compiler 13.0 + Written by Wei Dai diff --git a/CryptoPP/algebra.cpp b/CryptoPP/algebra.cpp index b8818e6af..958e63701 100644 --- a/CryptoPP/algebra.cpp +++ b/CryptoPP/algebra.cpp @@ -14,42 +14,42 @@ NAMESPACE_BEGIN(CryptoPP) template const T& AbstractGroup::Double(const Element &a) const { - return Add(a, a); + return this->Add(a, a); } template const T& AbstractGroup::Subtract(const Element &a, const Element &b) const { // make copy of a in case Inverse() overwrites it Element a1(a); - return Add(a1, Inverse(b)); + return this->Add(a1, Inverse(b)); } template T& AbstractGroup::Accumulate(Element &a, const Element &b) const { - return a = Add(a, b); + return a = this->Add(a, b); } template T& AbstractGroup::Reduce(Element &a, const Element &b) const { - return a = Subtract(a, b); + return a = this->Subtract(a, b); } template const T& AbstractRing::Square(const Element &a) const { - return Multiply(a, a); + return this->Multiply(a, a); } template const T& AbstractRing::Divide(const Element &a, const Element &b) const { // make copy of a in case MultiplicativeInverse() overwrites it Element a1(a); - return Multiply(a1, MultiplicativeInverse(b)); + return this->Multiply(a1, this->MultiplicativeInverse(b)); } template const T& AbstractEuclideanDomain::Mod(const Element &a, const Element &b) const { Element q; - DivisionAlgorithm(result, q, a, b); + this->DivisionAlgorithm(result, q, a, b); return result; } @@ -60,7 +60,7 @@ template const T& AbstractEuclideanDomain::Gcd(const Element &a, co while (!this->Equal(g[i1], this->Identity())) { - g[i2] = Mod(g[i0], g[i1]); + g[i2] = this->Mod(g[i0], g[i1]); unsigned int t = i0; i0 = i1; i1 = i2; i2 = t; } @@ -74,7 +74,7 @@ template const typename QuotientRing::Element& QuotientRing::Mul Element y; unsigned int i0=0, i1=1, i2=2; - while (!Equal(g[i1], Identity())) + while (!this->Equal(g[i1], this->Identity())) { // y = g[i0] / g[i1]; // g[i2] = g[i0] % g[i1]; @@ -90,7 +90,7 @@ template const typename QuotientRing::Element& QuotientRing::Mul template T AbstractGroup::ScalarMultiply(const Element &base, const Integer &exponent) const { Element result; - SimultaneousMultiply(&result, base, &exponent, 1); + this->SimultaneousMultiply(&result, base, &exponent, 1); return result; } @@ -98,7 +98,7 @@ template T AbstractGroup::CascadeScalarMultiply(const Element &x, c { const unsigned expLen = STDMAX(e1.BitCount(), e2.BitCount()); if (expLen==0) - return Identity(); + return this->Identity(); const unsigned w = (expLen <= 46 ? 1 : (expLen <= 260 ? 2 : 3)); const unsigned tableSize = 1< T AbstractGroup::CascadeScalarMultiply(const Element &x, c powerTable[1] = x; powerTable[tableSize] = y; if (w==1) - powerTable[3] = Add(x,y); + powerTable[3] = this->Add(x,y); else { - powerTable[2] = Double(x); - powerTable[2*tableSize] = Double(y); + powerTable[2] = this->Double(x); + powerTable[2*tableSize] = this->Double(y); unsigned i, j; @@ -157,12 +157,12 @@ template T AbstractGroup::CascadeScalarMultiply(const Element &x, c else { while (squaresBefore--) - result = Double(result); + result = this->Double(result); if (power1 || power2) Accumulate(result, powerTable[(power2<Double(result); power1 = power2 = 0; } } diff --git a/CryptoPP/config.h b/CryptoPP/config.h index ba7c00110..edbfd00ef 100644 --- a/CryptoPP/config.h +++ b/CryptoPP/config.h @@ -348,7 +348,7 @@ NAMESPACE_END #define CRYPTOPP_ALLOW_UNALIGNED_DATA_ACCESS #endif -#define CRYPTOPP_VERSION 561 +#define CRYPTOPP_VERSION 562 // ***************** determine availability of OS features ******************** diff --git a/CryptoPP/cryptlib.h b/CryptoPP/cryptlib.h index 0ad18de80..406872232 100644 --- a/CryptoPP/cryptlib.h +++ b/CryptoPP/cryptlib.h @@ -4,7 +4,7 @@ classes that provide a uniform interface to this library. */ -/*! \mainpage Crypto++ Library 5.6.1 API Reference +/*! \mainpage Crypto++ Library 5.6.2 API Reference
Abstract Base Classes
cryptlib.h @@ -25,7 +25,7 @@
Public Key Cryptosystems
DLIES, ECIES, LUCES, RSAES, RabinES, LUC_IES
Public Key Signature Schemes
- DSA, GDSA, ECDSA, NR, ECNR, LUCSS, RSASS, RSASS_ISO, RabinSS, RWSS, ESIGN + DSA2, GDSA, ECDSA, NR, ECNR, LUCSS, RSASS, RSASS_ISO, RabinSS, RWSS, ESIGN
Key Agreement
#DH, DH2, #MQV, ECDH, ECMQV, XTR_DH
Algebraic Structures
diff --git a/CryptoPP/dsa.cpp b/CryptoPP/dsa.cpp index ac9e1f8c6..5aace4857 100644 --- a/CryptoPP/dsa.cpp +++ b/CryptoPP/dsa.cpp @@ -58,62 +58,6 @@ size_t DSAConvertSignatureFormat(byte *buffer, size_t bufferSize, DSASignatureFo return (size_t)sink.TotalPutLength(); } -bool DSA::GeneratePrimes(const byte *seedIn, unsigned int g, int &counter, - Integer &p, unsigned int L, Integer &q, bool useInputCounterValue) -{ - assert(g%8 == 0); - - SHA sha; - SecByteBlock seed(seedIn, g/8); - SecByteBlock U(SHA::DIGESTSIZE); - SecByteBlock temp(SHA::DIGESTSIZE); - SecByteBlock W(((L-1)/160+1) * SHA::DIGESTSIZE); - const int n = (L-1) / 160; - const int b = (L-1) % 160; - Integer X; - - sha.CalculateDigest(U, seed, g/8); - - for (int i=g/8-1, carry=true; i>=0 && carry; i--) - carry=!++seed[i]; - - sha.CalculateDigest(temp, seed, g/8); - xorbuf(U, temp, SHA::DIGESTSIZE); - - U[0] |= 0x80; - U[SHA::DIGESTSIZE-1] |= 1; - q.Decode(U, SHA::DIGESTSIZE); - - if (!IsPrime(q)) - return false; - - int counterEnd = useInputCounterValue ? counter+1 : 4096; - - for (int c = 0; c < counterEnd; c++) - { - for (int k=0; k<=n; k++) - { - for (int i=g/8-1, carry=true; i>=0 && carry; i--) - carry=!++seed[i]; - if (!useInputCounterValue || c == counter) - sha.CalculateDigest(W+(n-k)*SHA::DIGESTSIZE, seed, g/8); - } - if (!useInputCounterValue || c == counter) - { - W[SHA::DIGESTSIZE - 1 - b/8] |= 0x80; - X.Decode(W + SHA::DIGESTSIZE - 1 - b/8, L/8); - p = X-((X % (2*q))-1); - - if (p.GetBit(L-1) && IsPrime(p)) - { - counter = c; - return true; - } - } - } - return false; -} - NAMESPACE_END #endif diff --git a/CryptoPP/gfpcrypt.cpp b/CryptoPP/gfpcrypt.cpp index 6d9ffcebd..e293fc598 100644 --- a/CryptoPP/gfpcrypt.cpp +++ b/CryptoPP/gfpcrypt.cpp @@ -30,39 +30,37 @@ void DL_GroupParameters_DSA::GenerateRandom(RandomNumberGenerator &rng, const Na if (alg.GetValue("Modulus", p) && alg.GetValue("SubgroupGenerator", g)) { q = alg.GetValueWithDefault("SubgroupOrder", ComputeGroupOrder(p)/2); + Initialize(p, q, g); } else { - int modulusSize = 1024; + int modulusSize = 1024, defaultSubgroupOrderSize; alg.GetIntValue("ModulusSize", modulusSize) || alg.GetIntValue("KeySize", modulusSize); - if (!DSA::IsValidPrimeLength(modulusSize)) + switch (modulusSize) + { + case 1024: + defaultSubgroupOrderSize = 160; + break; + case 2048: + defaultSubgroupOrderSize = 224; + break; + case 3072: + defaultSubgroupOrderSize = 256; + break; + default: throw InvalidArgument("DSA: not a valid prime length"); + } - SecByteBlock seed(SHA::DIGESTSIZE); - Integer h; - int c; - - do - { - rng.GenerateBlock(seed, SHA::DIGESTSIZE); - } while (!DSA::GeneratePrimes(seed, SHA::DIGESTSIZE*8, c, p, modulusSize, q)); - - do - { - h.Randomize(rng, 2, p-2); - g = a_exp_b_mod_c(h, (p-1)/q, p); - } while (g <= 1); + DL_GroupParameters_GFP::GenerateRandom(rng, CombinedNameValuePairs(alg, MakeParameters(Name::SubgroupOrderSize(), defaultSubgroupOrderSize, false))); } - - Initialize(p, q, g); } bool DL_GroupParameters_DSA::ValidateGroup(RandomNumberGenerator &rng, unsigned int level) const { bool pass = DL_GroupParameters_GFP::ValidateGroup(rng, level); - pass = pass && DSA::IsValidPrimeLength(GetModulus().BitCount()); - pass = pass && GetSubgroupOrder().BitCount() == 160; + int pSize = GetModulus().BitCount(), qSize = GetSubgroupOrder().BitCount(); + pass = pass && ((pSize==1024 && qSize==160) || (pSize==2048 && qSize==224) || (pSize==2048 && qSize==256) || (pSize==3072 && qSize==256)); return pass; } diff --git a/CryptoPP/gfpcrypt.h b/CryptoPP/gfpcrypt.h index 5e9c635d6..7af993fb3 100644 --- a/CryptoPP/gfpcrypt.h +++ b/CryptoPP/gfpcrypt.h @@ -369,51 +369,43 @@ public: /*! parameters: (ModulusSize), or (Modulus, SubgroupOrder, SubgroupGenerator) */ /*! ModulusSize must be between DSA::MIN_PRIME_LENGTH and DSA::MAX_PRIME_LENGTH, and divisible by DSA::PRIME_LENGTH_MULTIPLE */ void GenerateRandom(RandomNumberGenerator &rng, const NameValuePairs &alg); + + static bool CRYPTOPP_API IsValidPrimeLength(unsigned int pbits) + {return pbits >= MIN_PRIME_LENGTH && pbits <= MAX_PRIME_LENGTH && pbits % PRIME_LENGTH_MULTIPLE == 0;} + + enum {MIN_PRIME_LENGTH = 1024, MAX_PRIME_LENGTH = 3072, PRIME_LENGTH_MULTIPLE = 1024}; }; -struct DSA; +template +class DSA2; //! DSA keys struct DL_Keys_DSA { typedef DL_PublicKey_GFP PublicKey; - typedef DL_PrivateKey_WithSignaturePairwiseConsistencyTest, DSA> PrivateKey; + typedef DL_PrivateKey_WithSignaturePairwiseConsistencyTest, DSA2 > PrivateKey; }; -//! DSA -struct CRYPTOPP_DLL DSA : public DL_SS< +//! DSA, as specified in FIPS 186-3 +// class named DSA2 instead of DSA for backwards compatibility (DSA was a non-template class) +template +class DSA2 : public DL_SS< DL_Keys_DSA, DL_Algorithm_GDSA, DL_SignatureMessageEncodingMethod_DSA, - SHA, - DSA> + H, + DSA2 > { - static const char * CRYPTOPP_API StaticAlgorithmName() {return "DSA";} - - //! Generate DSA primes according to NIST standard - /*! Both seedLength and primeLength are in bits, but seedLength should - be a multiple of 8. - If useInputCounterValue == true, the counter parameter is taken as input, otherwise it's used for output - */ - static bool CRYPTOPP_API GeneratePrimes(const byte *seed, unsigned int seedLength, int &counter, - Integer &p, unsigned int primeLength, Integer &q, bool useInputCounterValue = false); - - static bool CRYPTOPP_API IsValidPrimeLength(unsigned int pbits) - {return pbits >= MIN_PRIME_LENGTH && pbits <= MAX_PRIME_LENGTH && pbits % PRIME_LENGTH_MULTIPLE == 0;} - - //! FIPS 186-2 Change Notice 1 changed the minimum modulus length to 1024 - enum { -#if (DSA_1024_BIT_MODULUS_ONLY) - MIN_PRIME_LENGTH = 1024, -#else - MIN_PRIME_LENGTH = 512, -#endif - MAX_PRIME_LENGTH = 1024, PRIME_LENGTH_MULTIPLE = 64}; +public: + static std::string CRYPTOPP_API StaticAlgorithmName() {return "DSA/" + (std::string)H::StaticAlgorithmName();} }; +//! DSA with SHA-1, typedef'd for backwards compatibility +typedef DSA2 DSA; + CRYPTOPP_DLL_TEMPLATE_CLASS DL_PublicKey_GFP; CRYPTOPP_DLL_TEMPLATE_CLASS DL_PrivateKey_GFP; -CRYPTOPP_DLL_TEMPLATE_CLASS DL_PrivateKey_WithSignaturePairwiseConsistencyTest, DSA>; +CRYPTOPP_DLL_TEMPLATE_CLASS DL_PrivateKey_WithSignaturePairwiseConsistencyTest, DSA2 >; //! the XOR encryption method, for use with DL-based cryptosystems template diff --git a/CryptoPP/misc.h b/CryptoPP/misc.h index 7f32b860b..2b326dd60 100644 --- a/CryptoPP/misc.h +++ b/CryptoPP/misc.h @@ -141,7 +141,7 @@ const T & Singleton::Ref(CRYPTOPP_NOINLINE_DOTDOTDOT) const // ************** misc functions *************** -#if (!__STDC_WANT_SECURE_LIB__) +#if (!__STDC_WANT_SECURE_LIB__ && !defined(_MEMORY_S_DEFINED)) inline void memcpy_s(void *dest, size_t sizeInBytes, const void *src, size_t count) { if (count > sizeInBytes) diff --git a/CryptoPP/osrng.cpp b/CryptoPP/osrng.cpp index fa6dd36dd..76e486b4e 100644 --- a/CryptoPP/osrng.cpp +++ b/CryptoPP/osrng.cpp @@ -83,8 +83,22 @@ void NonblockingRng::GenerateBlock(byte *output, size_t size) if (!CryptGenRandom(m_Provider.GetProviderHandle(), (DWORD)size, output)) throw OS_RNG_Err("CryptGenRandom"); #else - if (read(m_fd, output, size) != size) - throw OS_RNG_Err("read /dev/urandom"); + while (size) + { + ssize_t len = read(m_fd, output, size); + + if (len < 0) + { + // /dev/urandom reads CAN give EAGAIN errors! (maybe EINTR as well) + if (errno != EINTR && errno != EAGAIN) + throw OS_RNG_Err("read /dev/urandom"); + + continue; + } + + output += len; + size -= len; + } #endif } @@ -119,10 +133,17 @@ void BlockingRng::GenerateBlock(byte *output, size_t size) while (size) { // on some systems /dev/random will block until all bytes - // are available, on others it will returns immediately + // are available, on others it returns immediately ssize_t len = read(m_fd, output, size); if (len < 0) - throw OS_RNG_Err("read " CRYPTOPP_BLOCKING_RNG_FILENAME); + { + // /dev/random reads CAN give EAGAIN errors! (maybe EINTR as well) + if (errno != EINTR && errno != EAGAIN) + throw OS_RNG_Err("read " CRYPTOPP_BLOCKING_RNG_FILENAME); + + continue; + } + size -= len; output += len; if (size) diff --git a/CryptoPP/queue.h b/CryptoPP/queue.h index 75f7807fd..ab89dbdf1 100644 --- a/CryptoPP/queue.h +++ b/CryptoPP/queue.h @@ -58,6 +58,7 @@ public: ByteQueue & operator=(const ByteQueue &rhs); bool operator==(const ByteQueue &rhs) const; + bool operator!=(const ByteQueue &rhs) const {return !operator==(rhs);} byte operator[](lword i) const; void swap(ByteQueue &rhs); diff --git a/CryptoPP/rw.h b/CryptoPP/rw.h index ec8b8507b..6820251e8 100644 --- a/CryptoPP/rw.h +++ b/CryptoPP/rw.h @@ -22,6 +22,11 @@ public: void BERDecode(BufferedTransformation &bt); void DEREncode(BufferedTransformation &bt) const; + void Save(BufferedTransformation &bt) const + {DEREncode(bt);} + void Load(BufferedTransformation &bt) + {BERDecode(bt);} + Integer ApplyFunction(const Integer &x) const; Integer PreimageBound() const {return ++(m_n>>1);} Integer ImageBound() const {return m_n;} @@ -52,6 +57,11 @@ public: void BERDecode(BufferedTransformation &bt); void DEREncode(BufferedTransformation &bt) const; + void Save(BufferedTransformation &bt) const + {DEREncode(bt);} + void Load(BufferedTransformation &bt) + {BERDecode(bt);} + Integer CalculateInverse(RandomNumberGenerator &rng, const Integer &x) const; // GeneratibleCryptoMaterial diff --git a/CryptoPP/validate.h b/CryptoPP/validate.h index 685340775..0ab23cba3 100644 --- a/CryptoPP/validate.h +++ b/CryptoPP/validate.h @@ -76,6 +76,6 @@ bool ValidateECDSA(); bool ValidateESIGN(); CryptoPP::RandomNumberGenerator & GlobalRNG(); -bool RunTestDataFile(const char *filename, const CryptoPP::NameValuePairs &overrideParameters=CryptoPP::g_nullNameValuePairs); +bool RunTestDataFile(const char *filename, const CryptoPP::NameValuePairs &overrideParameters=CryptoPP::g_nullNameValuePairs, bool thorough=true); #endif