diff --git a/cryptlib.cpp b/cryptlib.cpp index f202f539..cdb8fdcc 100644 --- a/cryptlib.cpp +++ b/cryptlib.cpp @@ -313,7 +313,7 @@ word32 RandomNumberGenerator::GenerateWord32(word32 min, word32 max) // Stack recursion below... GenerateIntoBufferedTransformation calls GenerateBlock, // and GenerateBlock calls GenerateIntoBufferedTransformation. Ad infinitum. Also -// see https://github.com/weidai11/cryptopp/issues/38. +// see http://github.com/weidai11/cryptopp/issues/38. // // According to Wei, RandomNumberGenerator is an interface, and it should not // be instantiable. Its now spilt milk, and we are going to CRYPTOPP_ASSERT it in Debug @@ -945,6 +945,15 @@ void AuthenticatedKeyAgreementDomain::GenerateEphemeralKeyPair(RandomNumberGener GenerateEphemeralPublicKey(rng, privateKey, publicKey); } +// Allow a distro or packager to override the build-time version +// http://github.com/weidai11/cryptopp/issues/371 +#ifndef CRYPTOPP_BUILD_VERSION +# define CRYPTOPP_BUILD_VERSION CRYPTOPP_VERSION +#endif +int BuildVersion() +{ + return CRYPTOPP_BUILD_VERSION; +} NAMESPACE_END #endif diff --git a/cryptlib.h b/cryptlib.h index 0e6011bc..dcb3ac3a 100644 --- a/cryptlib.h +++ b/cryptlib.h @@ -2914,6 +2914,76 @@ public: virtual void BEREncode(BufferedTransformation &bt) const {DEREncode(bt);} }; +//! \brief Specifies the build-time version of the library +//! \returns integer representing the build-time version +//! \details BuildVersion can help detect inadvertent mixing and matching of library +//! versions. When using Crypto++ distributed by a third party, BuildVersion() +//! records the version of the shared object that was built by the third party. +//! The BuildVersion() record resides in cryptlib.o on Unix compatibles +//! and cryptlib.obj on Windows. It does not change when an app links +//! to the library. +//! \details BuildVersion() is declared with C linkage (extern "C") within the +//! CryptoPP namespace to help programs locate the symbol. If the symbol is present, then +//! the library version is 5.7 or above. If it is missing, then the library version is +//! 5.6.5 or below. +//! \details The function could be used as shown below. +//!
+//!     if (BuildVersion() != RuntimeVersion())
+//!     {
+//!         cout << "Potential version mismatch" << endl;
+//!
+//!         const int bmaj = (BuildVersion() / 100U) % 10;
+//!         const int bmin = (BuildVersion() / 10U) % 10;
+//!         const int rmaj = (RuntimeVersion() / 100U) % 10;
+//!         const int rmin = (RuntimeVersion() / 10U) % 10;
+//!
+//!         if(bmaj != rmaj)
+//!             cout << "Major version mismatch" << endl;
+//!         else if(bmin != rmin)
+//!             cout << "Minor version mismatch" << endl;
+//!      }
+//! 
+//! \sa RuntimeVersion(), GitHub Issue 371. +//! \since Crypto++ 5.7 +extern "C" { + int BuildVersion(); +} // C linkage + +//! \brief Specifies the runtime version of the library +//! \returns integer representing the runtime version +//! \details RuntimeVersion() can help detect inadvertent mixing and matching of library +//! versions. When using Crypto++ distributed by a third party, RuntimeVersion() +//! records the version of the headers used by the app when the app is compiled. +//! \details RuntimeVersion() is declared with C linkage (extern "C") within the +//! CryptoPP namespace to help programs locate the symbol. If the symbol is present, then +//! the library version is 5.7 or above. If it is missing, then the library version is +//! 5.6.5 or below. +//! \details The function could be used as shown below. +//!
+//!     if (BuildVersion() != RuntimeVersion())
+//!     {
+//!         cout << "Potential version mismatch" << endl;
+//!
+//!         const int bmaj = (BuildVersion() / 100U) % 10;
+//!         const int bmin = (BuildVersion() / 10U) % 10;
+//!         const int rmaj = (RuntimeVersion() / 100U) % 10;
+//!         const int rmin = (RuntimeVersion() / 10U) % 10;
+//!
+//!         if(bmaj != rmaj)
+//!             cout << "Major version mismatch" << endl;
+//!         else if(bmin != rmin)
+//!             cout << "Minor version mismatch" << endl;
+//!      }
+//! 
+//! \sa BuildVersion(), GitHub Issue 371. +//! \since Crypto++ 5.7 +extern "C" { +inline int RuntimeVersion() +{ + return CRYPTOPP_VERSION; +} +} // C linkage + NAMESPACE_END #if CRYPTOPP_MSC_VERSION diff --git a/gfpcrypt.h b/gfpcrypt.h index 9cba973b..f4acbb83 100644 --- a/gfpcrypt.h +++ b/gfpcrypt.h @@ -399,7 +399,7 @@ private: //! \tparam T FieldElement type or class //! \details The Digital Signature Scheme ECGDSA does not define the algorithm over integers. Rather, the //! signature algorithm is only defined over elliptic curves. However, The library design is such that the -//! generic algorithm reside in \header gfpcrypt.h. +//! generic algorithm reside in gfpcrypt.h. //! \sa Erwin Hess, Marcus Schafheutle, and Pascale Serf //! The Digital Signature Scheme ECGDSA (October 24, 2006) template diff --git a/validat1.cpp b/validat1.cpp index 471502b7..91259ae7 100644 --- a/validat1.cpp +++ b/validat1.cpp @@ -225,6 +225,18 @@ bool TestSettings() pass = false; } + // App and library versions, http://github.com/weidai11/cryptopp/issues/371 + const int bver = BuildVersion(); + const int rver = RuntimeVersion(); + if(bver/10 == rver/10) + cout << "passed: "; + else + { + cout << "FAILED: "; + pass = false; + } + cout << "Build version (library): " << bver << ", runtime version (app): " << rver << "\n"; + #ifdef CRYPTOPP_ALLOW_UNALIGNED_DATA_ACCESS // Don't assert the alignment of testvals. That's what this test is for. byte testvals[10] = {1,2,2,3,3,3,3,2,2,1};