diff options
-rw-r--r-- | Readme.txt | 5 | ||||
-rw-r--r-- | algparam.cpp | 2 | ||||
-rw-r--r-- | algparam.h | 9 | ||||
-rw-r--r-- | argnames.h | 1 | ||||
-rw-r--r-- | asn.h | 26 | ||||
-rw-r--r-- | config.h | 4 | ||||
-rw-r--r-- | cryptlib.cpp | 4 | ||||
-rw-r--r-- | cryptlib.h | 10 | ||||
-rw-r--r-- | cryptopp.rc | 37 | ||||
-rw-r--r-- | default.cpp | 4 | ||||
-rw-r--r-- | des.h | 4 | ||||
-rw-r--r-- | dll.cpp | 18 | ||||
-rw-r--r-- | dll.h | 11 | ||||
-rw-r--r-- | dlltest.cpp | 8 | ||||
-rw-r--r-- | elgamal.h | 22 | ||||
-rw-r--r-- | files.cpp | 2 | ||||
-rw-r--r-- | filters.cpp | 12 | ||||
-rw-r--r-- | filters.h | 9 | ||||
-rw-r--r-- | fips140.h | 12 | ||||
-rw-r--r-- | fipsalgt.cpp | 510 | ||||
-rw-r--r-- | fipstest.cpp | 89 | ||||
-rw-r--r-- | gf2n.h | 2 | ||||
-rw-r--r-- | gfpcrypt.h | 14 | ||||
-rw-r--r-- | integer.cpp | 163 | ||||
-rw-r--r-- | integer.h | 26 | ||||
-rw-r--r-- | iterhash.h | 2 | ||||
-rw-r--r-- | misc.h | 28 | ||||
-rw-r--r-- | modarith.h | 38 | ||||
-rw-r--r-- | modes.cpp | 14 | ||||
-rw-r--r-- | modes.h | 14 | ||||
-rw-r--r-- | nbtheory.h | 58 | ||||
-rw-r--r-- | oaep.h | 2 | ||||
-rw-r--r-- | osrng.h | 8 | ||||
-rw-r--r-- | pkcspad.cpp | 5 | ||||
-rw-r--r-- | pkcspad.h | 11 | ||||
-rw-r--r-- | polynomi.cpp | 4 | ||||
-rw-r--r-- | pssr.cpp | 26 | ||||
-rw-r--r-- | pssr.h | 44 | ||||
-rw-r--r-- | pubkey.cpp | 47 | ||||
-rw-r--r-- | pubkey.h | 103 | ||||
-rw-r--r-- | rabin.h | 8 | ||||
-rw-r--r-- | regtest.cpp | 1 | ||||
-rw-r--r-- | rijndael.h | 2 | ||||
-rw-r--r-- | rng.cpp | 21 | ||||
-rw-r--r-- | rng.h | 5 | ||||
-rw-r--r-- | rsa.cpp | 14 | ||||
-rw-r--r-- | rsa.h | 33 | ||||
-rw-r--r-- | rw.cpp | 29 | ||||
-rw-r--r-- | rw.h | 32 | ||||
-rw-r--r-- | secblock.h | 18 | ||||
-rw-r--r-- | seckey.h | 6 | ||||
-rw-r--r-- | sha.cpp | 4 | ||||
-rw-r--r-- | sha.h | 14 | ||||
-rw-r--r-- | simple.h | 2 | ||||
-rw-r--r-- | test.cpp | 10 | ||||
-rw-r--r-- | zdeflate.cpp | 2 | ||||
-rw-r--r-- | zinflate.cpp | 5 |
57 files changed, 997 insertions, 617 deletions
@@ -1,5 +1,5 @@ Crypto++: a C++ Class Library of Cryptographic Schemes -Version 5.2.2 (in development) +Version 5.2.3 (in development) This library includes: @@ -346,5 +346,8 @@ the mailing list. 5.2.2 - added SHA-224 - put SHA-256, SHA-384, SHA-512, RSASSA-PSS into DLL + +5.2.3 - fixed issues with FIPS algorithm test vectors + - put RSASSA-ISO into DLL Written by Wei Dai diff --git a/algparam.cpp b/algparam.cpp index aebe3c0f..3c556408 100644 --- a/algparam.cpp +++ b/algparam.cpp @@ -8,7 +8,7 @@ NAMESPACE_BEGIN(CryptoPP) -bool (*AssignIntToInteger)(const std::type_info &valueType, void *pInteger, const void *pInt) = NULL; +PAssignIntToInteger g_pAssignIntToInteger = NULL; bool CombinedNameValuePairs::GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const { @@ -237,10 +237,11 @@ AssignFromHelperClass<T, T> AssignFromHelper(T *pObject, const NameValuePairs &s // ******************************************************** -// This should allow the linker to discard Integer code if not needed. -CRYPTOPP_DLL extern bool (*AssignIntToInteger)(const std::type_info &valueType, void *pInteger, const void *pInt); +// to allow the linker to discard Integer code if not needed. +typedef bool (CRYPTOPP_API * PAssignIntToInteger)(const std::type_info &valueType, void *pInteger, const void *pInt); +CRYPTOPP_DLL extern PAssignIntToInteger g_pAssignIntToInteger; -CRYPTOPP_DLL const std::type_info & IntegerTypeId(); +CRYPTOPP_DLL const std::type_info & CRYPTOPP_API IntegerTypeId(); class CRYPTOPP_DLL AlgorithmParametersBase : public NameValuePairs { @@ -292,7 +293,7 @@ public: void AssignValue(const char *name, const std::type_info &valueType, void *pValue) const { // special case for retrieving an Integer parameter when an int was passed in - if (!(AssignIntToInteger != NULL && typeid(T) == typeid(int) && AssignIntToInteger(valueType, pValue, &m_value))) + if (!(g_pAssignIntToInteger != NULL && typeid(T) == typeid(int) && g_pAssignIntToInteger(valueType, pValue, &m_value))) { ThrowIfTypeMismatch(name, typeid(T), valueType); *reinterpret_cast<T *>(pValue) = m_value; @@ -42,6 +42,7 @@ CRYPTOPP_DEFINE_NAME_STRING(MultiplicativeInverseOfPrime2ModPrime1) //!< Integer CRYPTOPP_DEFINE_NAME_STRING(QuadraticResidueModPrime1) //!< Integer CRYPTOPP_DEFINE_NAME_STRING(QuadraticResidueModPrime2) //!< Integer CRYPTOPP_DEFINE_NAME_STRING(PutMessage) //!< bool +CRYPTOPP_DEFINE_NAME_STRING(TruncatedDigestSize) //!< int CRYPTOPP_DEFINE_NAME_STRING(HashVerificationFilterFlags) //!< word32 CRYPTOPP_DEFINE_NAME_STRING(SignatureVerificationFilterFlags) //!< word32 CRYPTOPP_DEFINE_NAME_STRING(InputBuffer) //!< ConstByteArrayParameter @@ -56,27 +56,27 @@ public: }; // unsigned int DERLengthEncode(unsigned int length, byte *output=0); -CRYPTOPP_DLL unsigned int DERLengthEncode(BufferedTransformation &out, unsigned int length); +CRYPTOPP_DLL unsigned int CRYPTOPP_API DERLengthEncode(BufferedTransformation &out, unsigned int length); // returns false if indefinite length -CRYPTOPP_DLL bool BERLengthDecode(BufferedTransformation &in, unsigned int &length); +CRYPTOPP_DLL bool CRYPTOPP_API BERLengthDecode(BufferedTransformation &in, unsigned int &length); -CRYPTOPP_DLL void DEREncodeNull(BufferedTransformation &out); -CRYPTOPP_DLL void BERDecodeNull(BufferedTransformation &in); +CRYPTOPP_DLL void CRYPTOPP_API DEREncodeNull(BufferedTransformation &out); +CRYPTOPP_DLL void CRYPTOPP_API BERDecodeNull(BufferedTransformation &in); -CRYPTOPP_DLL unsigned int DEREncodeOctetString(BufferedTransformation &out, const byte *str, unsigned int strLen); -CRYPTOPP_DLL unsigned int DEREncodeOctetString(BufferedTransformation &out, const SecByteBlock &str); -CRYPTOPP_DLL unsigned int BERDecodeOctetString(BufferedTransformation &in, SecByteBlock &str); -CRYPTOPP_DLL unsigned int BERDecodeOctetString(BufferedTransformation &in, BufferedTransformation &str); +CRYPTOPP_DLL unsigned int CRYPTOPP_API DEREncodeOctetString(BufferedTransformation &out, const byte *str, unsigned int strLen); +CRYPTOPP_DLL unsigned int CRYPTOPP_API DEREncodeOctetString(BufferedTransformation &out, const SecByteBlock &str); +CRYPTOPP_DLL unsigned int CRYPTOPP_API BERDecodeOctetString(BufferedTransformation &in, SecByteBlock &str); +CRYPTOPP_DLL unsigned int CRYPTOPP_API BERDecodeOctetString(BufferedTransformation &in, BufferedTransformation &str); // for UTF8_STRING, PRINTABLE_STRING, and IA5_STRING -CRYPTOPP_DLL unsigned int DEREncodeTextString(BufferedTransformation &out, const std::string &str, byte asnTag); -CRYPTOPP_DLL unsigned int BERDecodeTextString(BufferedTransformation &in, std::string &str, byte asnTag); +CRYPTOPP_DLL unsigned int CRYPTOPP_API DEREncodeTextString(BufferedTransformation &out, const std::string &str, byte asnTag); +CRYPTOPP_DLL unsigned int CRYPTOPP_API BERDecodeTextString(BufferedTransformation &in, std::string &str, byte asnTag); -CRYPTOPP_DLL unsigned int DEREncodeBitString(BufferedTransformation &out, const byte *str, unsigned int strLen, unsigned int unusedBits=0); -CRYPTOPP_DLL unsigned int BERDecodeBitString(BufferedTransformation &in, SecByteBlock &str, unsigned int &unusedBits); +CRYPTOPP_DLL unsigned int CRYPTOPP_API DEREncodeBitString(BufferedTransformation &out, const byte *str, unsigned int strLen, unsigned int unusedBits=0); +CRYPTOPP_DLL unsigned int CRYPTOPP_API BERDecodeBitString(BufferedTransformation &in, SecByteBlock &str, unsigned int &unusedBits); // BER decode from source and DER reencode into dest -CRYPTOPP_DLL void DERReencode(BufferedTransformation &source, BufferedTransformation &dest); +CRYPTOPP_DLL void CRYPTOPP_API DERReencode(BufferedTransformation &source, BufferedTransformation &dest); //! Object Identifier class CRYPTOPP_DLL OID @@ -273,14 +273,12 @@ NAMESPACE_END #define CRYPTOPP_DLL #endif -#define CRYPTOPP_API __stdcall -#define CRYPTOPP_CDECL __cdecl +#define CRYPTOPP_API __cdecl #else // CRYPTOPP_WIN32_AVAILABLE #define CRYPTOPP_DLL #define CRYPTOPP_API -#define CRYPTOPP_CDECL #endif // CRYPTOPP_WIN32_AVAILABLE diff --git a/cryptlib.cpp b/cryptlib.cpp index 4f2692fe..fc8a55df 100644 --- a/cryptlib.cpp +++ b/cryptlib.cpp @@ -474,7 +474,7 @@ unsigned int BufferedTransformation::PutWord32(word32 value, ByteOrder order, bo return ChannelPutWord32(NULL_CHANNEL, value, order, blocking); } -unsigned int BufferedTransformation::PeekWord16(word16 &value, ByteOrder order) +unsigned int BufferedTransformation::PeekWord16(word16 &value, ByteOrder order) const { byte buf[2] = {0, 0}; unsigned int len = Peek(buf, 2); @@ -487,7 +487,7 @@ unsigned int BufferedTransformation::PeekWord16(word16 &value, ByteOrder order) return len; } -unsigned int BufferedTransformation::PeekWord32(word32 &value, ByteOrder order) +unsigned int BufferedTransformation::PeekWord32(word32 &value, ByteOrder order) const { byte buf[4] = {0, 0, 0, 0}; unsigned int len = Peek(buf, 4); @@ -4,7 +4,7 @@ classes that provide a uniform interface to this library. */ -/*! \mainpage <a href="http://www.cryptopp.com">Crypto++</a><sup><small>®</small></sup> Library 5.2.2 Reference Manual +/*! \mainpage <a href="http://www.cryptopp.com">Crypto++</a><sup><small>®</small></sup> Library 5.2.3 Reference Manual <dl> <dt>Abstract Base Classes<dd> cryptlib.h @@ -283,7 +283,7 @@ public: {return GetValueWithDefault(name, defaultValue);} //! used by derived classes to check for type mismatch - CRYPTOPP_DLL static void ThrowIfTypeMismatch(const char *name, const std::type_info &stored, const std::type_info &retrieving) + CRYPTOPP_DLL static void CRYPTOPP_API ThrowIfTypeMismatch(const char *name, const std::type_info &stored, const std::type_info &retrieving) {if (stored != retrieving) throw ValueTypeMismatch(name, stored, retrieving);} template <class T> @@ -653,7 +653,7 @@ public: }; //! returns a reference that can be passed to functions that ask for a RNG but doesn't actually use it -CRYPTOPP_DLL RandomNumberGenerator & NullRNG(); +CRYPTOPP_DLL RandomNumberGenerator & CRYPTOPP_API NullRNG(); class WaitObjectContainer; @@ -823,9 +823,9 @@ public: unsigned int GetWord32(word32 &value, ByteOrder order=BIG_ENDIAN_ORDER); //! try to peek at a 16-bit word - unsigned int PeekWord16(word16 &value, ByteOrder order=BIG_ENDIAN_ORDER); + unsigned int PeekWord16(word16 &value, ByteOrder order=BIG_ENDIAN_ORDER) const; //! try to peek at a 32-bit word - unsigned int PeekWord32(word32 &value, ByteOrder order=BIG_ENDIAN_ORDER); + unsigned int PeekWord32(word32 &value, ByteOrder order=BIG_ENDIAN_ORDER) const; //! move transferMax bytes of the buffered output to target as input unsigned long TransferTo(BufferedTransformation &target, unsigned long transferMax=ULONG_MAX, const std::string &channel=NULL_CHANNEL) diff --git a/cryptopp.rc b/cryptopp.rc index 06f52893..4570f669 100644 --- a/cryptopp.rc +++ b/cryptopp.rc @@ -1,4 +1,4 @@ -//Microsoft Developer Studio generated resource script. +// Microsoft Visual C++ generated resource script. // #include "resource.h" @@ -21,15 +21,14 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US #pragma code_page(1252) #endif //_WIN32 -#ifndef _MAC ///////////////////////////////////////////////////////////////////////////// // // Version // VS_VERSION_INFO VERSIONINFO - FILEVERSION 5,2,0,0 - PRODUCTVERSION 5,2,0,0 + FILEVERSION 5,2,3,0 + PRODUCTVERSION 5,2,3,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -44,18 +43,16 @@ BEGIN BEGIN BLOCK "040904b0" BEGIN - VALUE "Comments", "free crypto library, more information available at www.cryptopp.com\0" - VALUE "CompanyName", "Wei Dai\0" - VALUE "FileDescription", "Crypto++® Library DLL\0" - VALUE "FileVersion", "5, 2, 0, 0\0" - VALUE "InternalName", "cryptopp\0" - VALUE "LegalCopyright", "Copyright © 1995-2003 by Wei Dai\0" - VALUE "LegalTrademarks", "Crypto++®\0" - VALUE "OriginalFilename", "cryptopp.dll\0" - VALUE "PrivateBuild", "\0" - VALUE "ProductName", "Crypto++® Library\0" - VALUE "ProductVersion", "5, 2, 0, 0\0" - VALUE "SpecialBuild", "\0" + VALUE "Comments", "free crypto library, more information available at www.cryptopp.com" + VALUE "CompanyName", "Wei Dai" + VALUE "FileDescription", "Crypto++® Library DLL" + VALUE "FileVersion", "5, 2, 3, 0" + VALUE "InternalName", "cryptopp" + VALUE "LegalCopyright", "Copyright © 1995-2004 by Wei Dai" + VALUE "LegalTrademarks", "Crypto++®" + VALUE "OriginalFilename", "cryptopp.dll" + VALUE "ProductName", "Crypto++® Library" + VALUE "ProductVersion", "5, 2, 3, 0" END END BLOCK "VarFileInfo" @@ -64,8 +61,6 @@ BEGIN END END -#endif // !_MAC - #ifdef APSTUDIO_INVOKED ///////////////////////////////////////////////////////////////////////////// @@ -73,18 +68,18 @@ END // TEXTINCLUDE // -1 TEXTINCLUDE DISCARDABLE +1 TEXTINCLUDE BEGIN "resource.h\0" END -2 TEXTINCLUDE DISCARDABLE +2 TEXTINCLUDE BEGIN "#include ""afxres.h""\r\n" "\0" END -3 TEXTINCLUDE DISCARDABLE +3 TEXTINCLUDE BEGIN "\r\n" "\0" diff --git a/default.cpp b/default.cpp index ca99414f..a54232b5 100644 --- a/default.cpp +++ b/default.cpp @@ -33,7 +33,7 @@ static void Mash(const byte *in, word16 inLen, byte *out, word16 outLen, int ite unsigned int i; for(i=0; i<outLen; i+=DefaultHashModule::DIGESTSIZE) { - b[0] = (byte) i >> 8; + b[0] = (byte) (i >> 8); b[1] = (byte) i; hash.Update(b, 2); hash.Update(in, inLen); @@ -45,7 +45,7 @@ static void Mash(const byte *in, word16 inLen, byte *out, word16 outLen, int ite memcpy(buf, outBuf, bufSize); for (i=0; i<bufSize; i+=DefaultHashModule::DIGESTSIZE) { - b[0] = (byte) i >> 8; + b[0] = (byte) (i >> 8); b[1] = (byte) i; hash.Update(b, 2); hash.Update(buf, bufSize); @@ -54,7 +54,7 @@ public: //! _ struct DES_EDE2_Info : public FixedBlockSize<8>, public FixedKeyLength<16> { - CRYPTOPP_DLL static const char * StaticAlgorithmName() {return "DES-EDE2";} + CRYPTOPP_DLL static const char * CRYPTOPP_API StaticAlgorithmName() {return "DES-EDE2";} }; /// <a href="http://www.weidai.com/scan-mirror/cs.html#DESede">DES-EDE2</a> @@ -78,7 +78,7 @@ public: //! _ struct DES_EDE3_Info : public FixedBlockSize<8>, public FixedKeyLength<24> { - CRYPTOPP_DLL static const char * StaticAlgorithmName() {return "DES-EDE3";} + CRYPTOPP_DLL static const char * CRYPTOPP_API StaticAlgorithmName() {return "DES-EDE3";} }; /// <a href="http://www.weidai.com/scan-mirror/cs.html#DESede">DES-EDE3</a> @@ -37,8 +37,11 @@ CRYPTOPP_DLL_TEMPLATE_CLASS AdditiveCipherTemplate<AbstractPolicyHolder<Additive CRYPTOPP_DLL_TEMPLATE_CLASS AbstractEuclideanDomain<Integer>; #endif -template<> const byte PKCS_DigestDecoration<SHA>::decoration[] = {0x30,0x21,0x30,0x09,0x06,0x05,0x2B,0x0E,0x03,0x02,0x1A,0x05,0x00,0x04,0x14}; -template<> const unsigned int PKCS_DigestDecoration<SHA>::length = sizeof(PKCS_DigestDecoration<SHA>::decoration); +template<> const byte PKCS_DigestDecoration<SHA1>::decoration[] = {0x30,0x21,0x30,0x09,0x06,0x05,0x2B,0x0E,0x03,0x02,0x1A,0x05,0x00,0x04,0x14}; +template<> const unsigned int PKCS_DigestDecoration<SHA1>::length = sizeof(PKCS_DigestDecoration<SHA1>::decoration); + +template<> const byte PKCS_DigestDecoration<SHA224>::decoration[] = {0x30,0x2d,0x30,0x0d,0x06,0x09,0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x04,0x05,0x00,0x04,0x1c}; +template<> const unsigned int PKCS_DigestDecoration<SHA224>::length = sizeof(PKCS_DigestDecoration<SHA224>::decoration); template<> const byte PKCS_DigestDecoration<SHA256>::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<SHA256>::length = sizeof(PKCS_DigestDecoration<SHA256>::decoration); @@ -50,6 +53,7 @@ template<> const byte PKCS_DigestDecoration<SHA512>::decoration[] = {0x30,0x51,0 template<> const unsigned int PKCS_DigestDecoration<SHA512>::length = sizeof(PKCS_DigestDecoration<SHA512>::decoration); template<> const byte EMSA2HashId<SHA>::id = 0x33; +template<> const byte EMSA2HashId<SHA224>::id = 0x38; template<> const byte EMSA2HashId<SHA256>::id = 0x34; template<> const byte EMSA2HashId<SHA384>::id = 0x36; template<> const byte EMSA2HashId<SHA512>::id = 0x35; @@ -69,7 +73,7 @@ using std::set_new_handler; static PNew s_pNew = NULL; static PDelete s_pDelete = NULL; -static void * CRYPTOPP_CDECL New (size_t size) +static void * New (size_t size) { void *p; while (!(p = malloc(size))) @@ -129,7 +133,7 @@ static void SetNewAndDeleteFunctionPointers() throw 0; } -void * CRYPTOPP_CDECL operator new (size_t size) +void * operator new (size_t size) { if (!s_pNew) SetNewAndDeleteFunctionPointers(); @@ -137,17 +141,17 @@ void * CRYPTOPP_CDECL operator new (size_t size) return s_pNew(size); } -void CRYPTOPP_CDECL operator delete (void * p) +void operator delete (void * p) { s_pDelete(p); } -void * CRYPTOPP_CDECL operator new [] (size_t size) +void * operator new [] (size_t size) { return operator new (size); } -void CRYPTOPP_CDECL operator delete [] (void * p) +void operator delete [] (void * p) { operator delete (p); } @@ -29,6 +29,7 @@ #include "pssr.h" #include "randpool.h" #include "rsa.h" +#include "rw.h" #include "sha.h" #include "skipjack.h" #include "trdlocal.h" @@ -56,11 +57,11 @@ NAMESPACE_BEGIN(CryptoPP) using std::new_handler; #endif -typedef void * (CRYPTOPP_CDECL * PNew)(size_t); -typedef void (CRYPTOPP_CDECL * PDelete)(void *); -typedef void (CRYPTOPP_CDECL * PGetNewAndDelete)(PNew &, PDelete &); -typedef new_handler (CRYPTOPP_CDECL * PSetNewHandler)(new_handler); -typedef void (CRYPTOPP_CDECL * PSetNewAndDelete)(PNew, PDelete, PSetNewHandler); +typedef void * (CRYPTOPP_API * PNew)(size_t); +typedef void (CRYPTOPP_API * PDelete)(void *); +typedef void (CRYPTOPP_API * PGetNewAndDelete)(PNew &, PDelete &); +typedef new_handler (CRYPTOPP_API * PSetNewHandler)(new_handler); +typedef void (CRYPTOPP_API * PSetNewAndDelete)(PNew, PDelete, PSetNewHandler); NAMESPACE_END diff --git a/dlltest.cpp b/dlltest.cpp index 149d27d9..85b8bdd6 100644 --- a/dlltest.cpp +++ b/dlltest.cpp @@ -177,18 +177,18 @@ void FIPS140_SampleApplication() static PNew s_pNew = NULL; static PDelete s_pDelete = NULL; -extern "C" __declspec(dllexport) void CRYPTOPP_CDECL SetNewAndDeleteFromCryptoPP(PNew pNew, PDelete pDelete, PSetNewHandler pSetNewHandler) +extern "C" __declspec(dllexport) void __cdecl SetNewAndDeleteFromCryptoPP(PNew pNew, PDelete pDelete, PSetNewHandler pSetNewHandler) { s_pNew = pNew; s_pDelete = pDelete; } -void * CRYPTOPP_CDECL operator new (size_t size) +void * __cdecl operator new (size_t size) { return s_pNew(size); } -void CRYPTOPP_CDECL operator delete (void * p) +void __cdecl operator delete (void * p) { s_pDelete(p); } @@ -197,7 +197,7 @@ void CRYPTOPP_CDECL operator delete (void * p) #ifdef CRYPTOPP_DLL_ONLY -int CRYPTOPP_CDECL main() +int __cdecl main() { FIPS140_SampleApplication(); return 0; @@ -75,7 +75,7 @@ public: }; template <class BASE, class SCHEME_OPTIONS, class KEY> -class CRYPTOPP_NO_VTABLE ElGamalObjectImpl : public DL_ObjectImplBase<BASE, SCHEME_OPTIONS, KEY>, public ElGamalBase +class ElGamalObjectImpl : public DL_ObjectImplBase<BASE, SCHEME_OPTIONS, KEY>, public ElGamalBase { public: unsigned int FixedMaxPlaintextLength() const {return MaxPlaintextLength(FixedCiphertextLength());} @@ -106,27 +106,11 @@ struct ElGamal static const char * StaticAlgorithmName() {return "ElgamalEnc/Crypto++Padding";} - class EncryptorImpl : public ElGamalObjectImpl<DL_EncryptorBase<Integer>, SchemeOptions, SchemeOptions::PublicKey>, public PublicKeyCopier<SchemeOptions> - { - public: - void CopyKeyInto(SchemeOptions::PublicKey &key) const - {key = GetKey();} - }; - - class DecryptorImpl : public ElGamalObjectImpl<DL_DecryptorBase<Integer>, SchemeOptions, SchemeOptions::PrivateKey>, public PrivateKeyCopier<SchemeOptions> - { - public: - void CopyKeyInto(SchemeOptions::PublicKey &key) const - {GetKey().MakePublicKey(key);} - void CopyKeyInto(SchemeOptions::PrivateKey &key) const - {key = GetKey();} - }; - typedef SchemeOptions::GroupParameters GroupParameters; //! implements PK_Encryptor interface - typedef PK_FinalTemplate<EncryptorImpl> Encryptor; + typedef PK_FinalTemplate<ElGamalObjectImpl<DL_EncryptorBase<Integer>, SchemeOptions, SchemeOptions::PublicKey> > Encryptor; //! implements PK_Decryptor interface - typedef PK_FinalTemplate<DecryptorImpl> Decryptor; + typedef PK_FinalTemplate<ElGamalObjectImpl<DL_DecryptorBase<Integer>, SchemeOptions, SchemeOptions::PrivateKey> > Decryptor; }; typedef ElGamal::Encryptor ElGamalEncryptor; @@ -95,7 +95,7 @@ unsigned int FileStore::CopyRangeTo2(BufferedTransformation &target, unsigned lo if (begin == 0 && end == 1) { int result = m_stream->peek(); - if (result == EOF) // GCC workaround: 2.95.2 doesn't have char_traits<char>::eof() + if (result == char_traits<char>::eof()) return 0; else { diff --git a/filters.cpp b/filters.cpp index ee372bbe..1806d412 100644 --- a/filters.cpp +++ b/filters.cpp @@ -656,6 +656,7 @@ void StreamTransformationFilter::LastPut(const byte *inString, unsigned int leng void HashFilter::IsolatedInitialize(const NameValuePairs ¶meters) { m_putMessage = parameters.GetValueWithDefault(Name::PutMessage(), false); + m_truncatedDigestSize = parameters.GetIntValueWithDefault(Name::TruncatedDigestSize(), -1); m_hashModule.Restart(); } @@ -668,11 +669,14 @@ unsigned int HashFilter::Put2(const byte *inString, unsigned int length, int mes if (messageEnd) { { - unsigned int size, digestSize = m_hashModule.DigestSize(); - m_space = HelpCreatePutSpace(*AttachedTransformation(), NULL_CHANNEL, digestSize, digestSize, size = digestSize); - m_hashModule.Final(m_space); + unsigned int size; + m_digestSize = m_hashModule.DigestSize(); + if (m_truncatedDigestSize >= 0 && (unsigned int)m_truncatedDigestSize < m_digestSize) + m_digestSize = m_truncatedDigestSize; + m_space = HelpCreatePutSpace(*AttachedTransformation(), NULL_CHANNEL, m_digestSize, m_digestSize, size = m_digestSize); + m_hashModule.TruncatedFinal(m_space, m_digestSize); } - FILTER_OUTPUT(2, m_space, m_hashModule.DigestSize(), messageEnd); + FILTER_OUTPUT(2, m_space, m_digestSize, messageEnd); } FILTER_END_NO_MESSAGE_END; } @@ -214,7 +214,8 @@ private: class CRYPTOPP_DLL FilterWithInputQueue : public Filter { public: - FilterWithInputQueue(BufferedTransformation *attachment) : Filter(attachment) {} + FilterWithInputQueue(BufferedTransformation *attachment=NULL) : Filter(attachment) {} + unsigned int Put2(const byte *inString, unsigned int length, int messageEnd, bool blocking) { if (!blocking) @@ -267,8 +268,8 @@ typedef StreamTransformationFilter StreamCipherFilter; class CRYPTOPP_DLL HashFilter : public Bufferless<Filter>, private FilterPutSpaceHelper { public: - HashFilter(HashTransformation &hm, BufferedTransformation *attachment = NULL, bool putMessage=false) - : m_hashModule(hm), m_putMessage(putMessage) {Detach(attachment);} + HashFilter(HashTransformation &hm, BufferedTransformation *attachment = NULL, bool putMessage=false, int truncatedDigestSize=-1) + : m_hashModule(hm), m_putMessage(putMessage), m_truncatedDigestSize(truncatedDigestSize) {Detach(attachment);} void IsolatedInitialize(const NameValuePairs ¶meters); unsigned int Put2(const byte *begin, unsigned int length, int messageEnd, bool blocking); @@ -278,7 +279,9 @@ public: private: HashTransformation &m_hashModule; bool m_putMessage; + int m_truncatedDigestSize; byte *m_space; + unsigned int m_digestSize; }; //! Filter Wrapper for HashTransformation @@ -18,19 +18,19 @@ public: }; //! returns whether FIPS 140-2 compliance features were enabled at compile time -CRYPTOPP_DLL bool FIPS_140_2_ComplianceEnabled(); +CRYPTOPP_DLL bool CRYPTOPP_API FIPS_140_2_ComplianceEnabled(); //! enum values representing status of the power-up self test enum PowerUpSelfTestStatus {POWER_UP_SELF_TEST_NOT_DONE, POWER_UP_SELF_TEST_FAILED, POWER_UP_SELF_TEST_PASSED}; //! perform the power-up self test, and set the self test status -CRYPTOPP_DLL void DoPowerUpSelfTest(const char *moduleFilename, const byte *expectedModuleMac); +CRYPTOPP_DLL void CRYPTOPP_API DoPowerUpSelfTest(const char *moduleFilename, const byte *expectedModuleMac); //! perform the power-up self test using the filename of this DLL and the embedded module MAC -CRYPTOPP_DLL void DoDllPowerUpSelfTest(); +CRYPTOPP_DLL void CRYPTOPP_API DoDllPowerUpSelfTest(); //! set the power-up self test status to POWER_UP_SELF_TEST_FAILED -CRYPTOPP_DLL void SimulatePowerUpSelfTestFailure(); +CRYPTOPP_DLL void CRYPTOPP_API SimulatePowerUpSelfTestFailure(); //! return the current power-up self test status CRYPTOPP_DLL PowerUpSelfTestStatus CRYPTOPP_API GetPowerUpSelfTestStatus(); @@ -41,9 +41,9 @@ CRYPTOPP_DLL const byte * CRYPTOPP_API GetActualMacAndLocation(unsigned int &mac typedef const byte * (CRYPTOPP_API * PGetActualMacAndLocation)(unsigned int &macSize, unsigned int &fileLocation); -CRYPTOPP_DLL MessageAuthenticationCode * NewIntegrityCheckingMAC(); +CRYPTOPP_DLL MessageAuthenticationCode * CRYPTOPP_API NewIntegrityCheckingMAC(); -CRYPTOPP_DLL bool IntegrityCheckModule(const char *moduleFilename, const byte *expectedModuleMac, SecByteBlock *pActualMac = NULL, unsigned long *pMacFileLocation = NULL); +CRYPTOPP_DLL bool CRYPTOPP_API IntegrityCheckModule(const char *moduleFilename, const byte *expectedModuleMac, SecByteBlock *pActualMac = NULL, unsigned long *pMacFileLocation = NULL); // this is used by Algorithm constructor to allow Algorithm objects to be constructed for the self test bool PowerUpSelfTestInProgressOnThisThread(); diff --git a/fipsalgt.cpp b/fipsalgt.cpp index 6a62d1be..1f9d671a 100644 --- a/fipsalgt.cpp +++ b/fipsalgt.cpp @@ -4,7 +4,11 @@ // They're preserved here (commented out) in case Crypto++ needs to be revalidated. #if 0 +#ifndef CRYPTOPP_IMPORTS +#define CRYPTOPP_DEFAULT_NO_DLL +#endif #include "dll.h" +#include "oids.h" USING_NAMESPACE(CryptoPP) USING_NAMESPACE(std) @@ -13,7 +17,7 @@ class LineBreakParser : public AutoSignaling<Bufferless<Filter> > { public: LineBreakParser(BufferedTransformation *attachment=NULL, byte lineEnd='\n') - : AutoSignaling<Bufferless<Filter> >(attachment), m_lineEnd(lineEnd) {} + : m_lineEnd(lineEnd) {Detach(attachment);} unsigned int Put2(const byte *begin, unsigned int length, int messageEnd, bool blocking) { @@ -51,14 +55,16 @@ public: enum DataType {OTHER, COUNT, KEY_T, IV, INPUT, OUTPUT}; TestDataParser(std::string algorithm, std::string test, std::string mode, unsigned int feedbackSize, bool encrypt, BufferedTransformation *attachment) - : Unflushable<FilterWithInputQueue>(attachment) - , m_algorithm(algorithm), m_test(test), m_mode(mode), m_feedbackSize(feedbackSize) + : m_algorithm(algorithm), m_test(test), m_mode(mode), m_feedbackSize(feedbackSize) , m_firstLine(true), m_blankLineTransition(0) { + Detach(attachment); + m_nameToType["COUNT"] = COUNT; m_nameToType["KEY"] = KEY_T; m_nameToType["KEYs"] = KEY_T; m_nameToType["key"] = KEY_T; + m_nameToType["Key"] = KEY_T; m_nameToType["IV"] = IV; m_nameToType["IV1"] = IV; m_nameToType["CV"] = IV; @@ -66,6 +72,10 @@ public: m_nameToType["IB"] = IV; m_nameToType["TEXT"] = INPUT; m_nameToType["RESULT"] = OUTPUT; + m_nameToType["Msg"] = INPUT; + m_nameToType["Seed"] = INPUT; + m_nameToType["V"] = INPUT; + m_nameToType["DT"] = IV; SetEncrypt(encrypt); if (m_algorithm == "DSS") @@ -83,6 +93,25 @@ public: else if (m_test == "verpqg") m_trigger = "c"; } + else if (m_algorithm == "HMAC") + m_trigger = "Msg"; + else if (m_algorithm == "SHA2") + m_trigger = (m_test == "MONTE") ? "Seed" : "Msg"; + else if (m_algorithm == "ECDSA") + { + if (m_test == "PKV") + m_trigger = "Qy"; + else if (m_test == "KeyPair") + m_trigger = "N"; + else if (m_test == "SigGen") + m_trigger = "Msg"; + else if (m_test == "SigVer") + m_trigger = "S"; + } + else if (m_algorithm == "RNG") + m_trigger = "V"; + else if (m_algorithm == "RSA") + m_trigger = (m_test == "Ver") ? "S" : "Msg"; } void SetEncrypt(bool encrypt) @@ -103,7 +132,7 @@ public: m_nameToType["CT"] = INPUT; } - if (m_algorithm == "AES") + if (m_algorithm == "AES" || m_algorithm == "TDES") { if (encrypt) { @@ -141,9 +170,16 @@ protected: output += "\n"; } - void OutputData(std::string &output, const std::string &key, const Integer &data) + void OutputData(std::string &output, const std::string &key, const Integer &data, int size=-1) { - SecByteBlock s(data.MinEncodedSize()); + SecByteBlock s(size < 0 ? data.MinEncodedSize() : size); + data.Encode(s, s.size()); + OutputData(output, key, s); + } + + void OutputData(std::string &output, const std::string &key, const PolynomialMod2 &data, int size=-1) + { + SecByteBlock s(size < 0 ? data.MinEncodedSize() : size); data.Encode(s, s.size()); OutputData(output, key, s); } @@ -267,6 +303,128 @@ protected: z.Assign(x, K/8); } + template <class EC> + void EC_KeyPair(string &output, int n, const OID &oid) + { + DL_GroupParameters_EC<EC> params(oid); + for (int i=0; i<n; i++) + { + DL_PrivateKey_EC<EC> priv; + DL_PublicKey_EC<EC> pub; + priv.Initialize(m_rng, params); + priv.MakePublicKey(pub); + + OutputData(output, "d ", priv.GetPrivateExponent()); + OutputData(output, "Qx ", pub.GetPublicElement().x, params.GetCurve().GetField().MaxElementByteLength()); + OutputData(output, "Qy ", pub.GetPublicElement().y, params.GetCurve().GetField().MaxElementByteLength()); + } + } + + template <class EC> + void EC_SigGen(string &output, const OID &oid) + { + DL_GroupParameters_EC<EC> params(oid); + ECDSA<EC, SHA1>::PrivateKey priv; + ECDSA<EC, SHA1>::PublicKey pub; + priv.Initialize(m_rng, params); + priv.MakePublicKey(pub); + + ECDSA<EC, SHA1>::Signer signer(priv); + SecByteBlock sig(signer.SignatureLength()); + StringSource(m_data["Msg"], true, new HexDecoder(new SignerFilter(m_rng, signer, new ArraySink(sig, sig.size())))); + SecByteBlock R(sig, sig.size()/2), S(sig+sig.size()/2, sig.size()/2); + + OutputData(output, "Qx ", pub.GetPublicElement().x, params.GetCurve().GetField().MaxElementByteLength()); + OutputData(output, "Qy ", pub.GetPublicElement().y, params.GetCurve().GetField().MaxElementByteLength()); + OutputData(output, "R ", R); + OutputData(output, "S ", S); + } + + template <class EC> + void EC_SigVer(string &output, const OID &oid) + { + SecByteBlock x(DecodeHex(m_data["Qx"])); + SecByteBlock y(DecodeHex(m_data["Qy"])); + Integer r((m_data["R"]+"h").c_str()); + Integer s((m_data["S"]+"h").c_str()); + + EC::FieldElement Qx(x, x.size()); + EC::FieldElement Qy(y, y.size()); + EC::Element Q(Qx, Qy); + + DL_GroupParameters_EC<EC> params(oid); + ECDSA<EC, SHA1>::PublicKey pub; + pub.Initialize(params, Q); + ECDSA<EC, SHA1>::Verifier verifier(pub); + + SecByteBlock sig(verifier.SignatureLength()); + r.Encode(sig, sig.size()/2); + s.Encode(sig+sig.size()/2, sig.size()/2); + + SignatureVerificationFilter filter(verifier); + filter.Put(sig, sig.size()); + StringSource(m_data["Msg"], true, new HexDecoder(new Redirector(filter, Redirector::DATA_ONLY))); + filter.MessageEnd(); + byte b; + filter.Get(b); + OutputData(output, "Result ", b ? "P" : "F"); + } + + template <class EC> + static bool EC_PKV(RandomNumberGenerator &rng, const SecByteBlock &x, const SecByteBlock &y, const OID &oid) + { + EC::FieldElement Qx(x, x.size()); + EC::FieldElement Qy(y, y.size()); + EC::Element Q(Qx, Qy); + + DL_GroupParameters_EC<EC> params(oid); + ECDSA<EC, SHA1>::PublicKey pub; + pub.Initialize(params, Q); + return pub.Validate(rng, 3); + } + + template <class H, class Result> + Result * CreateRSA2(const std::string &standard) + { + if (typeid(Result) == typeid(PK_Verifier)) + { + if (standard == "R") + return (Result *) new RSASS_ISO<H>::Verifier; + else if (standard == "P") + return (Result *) new RSASS<PSS, H>::Verifier; + else if (standard == "1") + return (Result *) new RSASS<PKCS1v15, H>::Verifier; + } + else if (typeid(Result) == typeid(PK_Signer)) + { + if (standard == "R") + return (Result *) new RSASS_ISO<H>::Signer; + else if (standard == "P") + return (Result *) new RSASS<PSS, H>::Signer; + else if (standard == "1") + return (Result *) new RSASS<PKCS1v15, H>::Signer; + } + + return NULL; + } + + template <class Result> + Result * CreateRSA(const std::string &standard, const std::string &hash) + { + if (hash == "1") + return CreateRSA2<SHA1, Result>(standard); + else if (hash == "224") + return CreateRSA2<SHA224, Result>(standard); + else if (hash == "256") + return CreateRSA2<SHA256, Result>(standard); + else if (hash == "384") + return CreateRSA2<SHA384, Result>(standard); + else if (hash == "512") + return CreateRSA2<SHA512, Result>(standard); + else + return NULL; + } + virtual void DoTest() { std::string output; @@ -351,7 +509,7 @@ protected: OutputData(output, "Q", q); OutputData(output, "G", g); OutputData(output, "Seed", seed); - OutputData(output, "H", h); + OutputData(output, "H", h, p.ByteCount()); OutputData(output, "c", counter); AttachedTransformation()->Put((byte *)output.data(), output.size()); output.resize(0); @@ -397,8 +555,8 @@ protected: DSA::Verifier verifier(p, q, g, y); HexDecoder filter(new SignatureVerificationFilter(verifier)); - StringSource(m_data["Sig"], true, new Redirector(filter, false)); - StringSource(m_data["Msg"], true, new Redirector(filter, false)); + StringSource(m_data["Sig"], true, new Redirector(filter, Redirector::DATA_ONLY)); + StringSource(m_data["Msg"], true, new Redirector(filter, Redirector::DATA_ONLY)); filter.MessageEnd(); byte b; filter.Get(b); @@ -429,6 +587,173 @@ protected: return; } + if (m_algorithm == "ECDSA") + { + std::map<std::string, OID> name2oid; + name2oid["P-192"] = ASN1::secp192r1(); + name2oid["P-224"] = ASN1::secp224r1(); + name2oid["P-256"] = ASN1::secp256r1(); + name2oid["P-384"] = ASN1::secp384r1(); + name2oid["P-521"] = ASN1::secp521r1(); + name2oid["K-163"] = ASN1::sect163k1(); + name2oid["K-233"] = ASN1::sect233k1(); + name2oid["K-283"] = ASN1::sect283k1(); + name2oid["K-409"] = ASN1::sect409k1(); + name2oid["K-571"] = ASN1::sect571k1(); + name2oid["B-163"] = ASN1::sect163r2(); + name2oid["B-233"] = ASN1::sect233r1(); + name2oid["B-283"] = ASN1::sect283r1(); + name2oid["B-409"] = ASN1::sect409r1(); + name2oid["B-571"] = ASN1::sect571r1(); + + if (m_test == "PKV") + { + bool pass; + if (m_bracketString[0] == 'P') + pass = EC_PKV<ECP>(m_rng, DecodeHex(m_data["Qx"]), DecodeHex(m_data["Qy"]), name2oid[m_bracketString]); + else + pass = EC_PKV<EC2N>(m_rng, DecodeHex(m_data["Qx"]), DecodeHex(m_data["Qy"]), name2oid[m_bracketString]); + + OutputData(output, "Result ", pass ? "P" : "F"); + } + else if (m_test == "KeyPair") + { + if (m_bracketString[0] == 'P') + EC_KeyPair<ECP>(output, atol(m_data["N"].c_str()), name2oid[m_bracketString]); + else + EC_KeyPair<EC2N>(output, atol(m_data["N"].c_str()), name2oid[m_bracketString]); + } + else if (m_test == "SigGen") + { + if (m_bracketString[0] == 'P') + EC_SigGen<ECP>(output, name2oid[m_bracketString]); + else + EC_SigGen<EC2N>(output, name2oid[m_bracketString]); + } + else if (m_test == "SigVer") + { + if (m_bracketString[0] == 'P') + EC_SigVer<ECP>(output, name2oid[m_bracketString]); + else + EC_SigVer<EC2N>(output, name2oid[m_bracketString]); + } + + AttachedTransformation()->Put((byte *)output.data(), output.size()); + output.resize(0); + return; + } + + if (m_algorithm == "RSA") + { + std::string shaAlg = m_data["SHAAlg"].substr(3); + + if (m_test == "Ver") + { + Integer n((m_data["n"] + "h").c_str()); + Integer e((m_data["e"] + "h").c_str()); + RSA::PublicKey pub; + pub.Initialize(n, e); + + member_ptr<PK_Verifier> pV(CreateRSA<PK_Verifier>(m_mode, shaAlg)); + pV->AccessMaterial().AssignFrom(pub); + + HexDecoder filter(new SignatureVerificationFilter(*pV)); + for (unsigned int i=m_data["S"].size(); i<pV->SignatureLength()*2; i++) + filter.Put('0'); + StringSource(m_data["S"], true, new Redirector(filter, Redirector::DATA_ONLY)); + StringSource(m_data["Msg"], true, new Redirector(filter, Redirector::DATA_ONLY)); + filter.MessageEnd(); + byte b; + filter.Get(b); + OutputData(output, "Result ", b ? "P" : "F"); + } + else + { + assert(m_test == "Gen"); + int modLen = atol(m_bracketString.substr(6).c_str()); + std::string &encodedKey = m_data["PrivKey"]; + RSA::PrivateKey priv; + + if (!encodedKey.empty()) + { + StringStore s(encodedKey); + priv.BERDecode(s); + if (priv.GetModulus().BitCount() != modLen) + encodedKey.clear(); + } + + if (encodedKey.empty()) + { + priv.Initialize(m_rng, modLen); + StringSink s(encodedKey); + priv.DEREncode(s); + OutputData(output, "n ", priv.GetModulus()); + OutputData(output, "e ", priv.GetPublicExponent(), modLen/8); + } + + member_ptr<PK_Signer> pS(CreateRSA<PK_Signer>(m_mode, shaAlg)); + pS->AccessMaterial().AssignFrom(priv); + + SecByteBlock sig(pS->SignatureLength()); + StringSource(m_data["Msg"], true, new HexDecoder(new SignerFilter(m_rng, *pS, new ArraySink(sig, sig.size())))); + OutputData(output, "SHAAlg ", m_data["SHAAlg"]); + OutputData(output, "Msg ", m_data["Msg"]); + OutputData(output, "S ", sig); + } + + AttachedTransformation()->Put((byte *)output.data(), output.size()); + output.resize(0); + return; + } + + if (m_algorithm == "SHA2") + { + member_ptr<HashFunction> pHF; + + if (m_mode == "224") + pHF.reset(new SHA224); + else if (m_mode == "256") + pHF.reset(new SHA256); + else if (m_mode == "384") + pHF.reset(new SHA384); + else if (m_mode == "512") + pHF.reset(new SHA512); + + if (m_test == "MONTE") + { + SecByteBlock seed = m_data2[INPUT]; + SecByteBlock MD[1003]; + int i,j; + + for (j=0; j<100; j++) + { + MD[0] = MD[1] = MD[2] = seed; + for (i=3; i<1003; i++) + { + SecByteBlock Mi = MD[i-3] + MD[i-2] + MD[i-1]; + MD[i].resize(pHF->DigestSize()); + pHF->CalculateDigest(MD[i], Mi, Mi.size()); + } + seed = MD[1002]; + OutputData(output, "COUNT ", j); + OutputData(output, "MD ", seed); + AttachedTransformation()->Put((byte *)output.data(), output.size()); + output.resize(0); + } + } + else + { + SecByteBlock tag(pHF->DigestSize()); + SecByteBlock &msg(m_data2[INPUT]); + int len = atol(m_data["Len"].c_str()); + StringSource(msg.begin(), len/8, true, new HashFilter(*pHF, new ArraySink(tag, tag.size()))); + OutputData(output, "MD ", tag); + AttachedTransformation()->Put((byte *)output.data(), output.size()); + output.resize(0); + } + return; + } + SecByteBlock &key = m_data2[KEY_T]; if (m_algorithm == "TDES") @@ -453,6 +778,59 @@ protected: } } + if (m_algorithm == "RNG") + { + key.resize(16); + HexDecoder hexDec(new ArraySink(key, key.size())); + StringSource(m_data["Key1"], true, new Redirector(hexDec)); + StringSource(m_data["Key2"], true, new Redirector(hexDec)); + + SecByteBlock seed(m_data2[INPUT]), dt(m_data2[IV]), r(8); + X917RNG rng(new DES_EDE2::Encryption(key), seed, dt); + + if (m_test == "MCT") + { + for (int i=0; i<10000; i++) + rng.GenerateBlock(r, r.size()); + } + else + { + rng.GenerateBlock(r, r.size()); + } + + OutputData(output, "R ", r); + AttachedTransformation()->Put((byte *)output.data(), output.size()); + output.resize(0); + return; + } + + if (m_algorithm == "HMAC") + { + member_ptr<MessageAuthenticationCode> pMAC; + + if (m_bracketString == "L=20") + pMAC.reset(new HMAC<SHA1>); + else if (m_bracketString == "L=28") + pMAC.reset(new HMAC<SHA224>); + else if (m_bracketString == "L=32") + pMAC.reset(new HMAC<SHA256>); + else if (m_bracketString == "L=48") + pMAC.reset(new HMAC<SHA384>); + else if (m_bracketString == "L=64") + pMAC.reset(new HMAC<SHA512>); + else + throw Exception(Exception::OTHER_ERROR, "TestDataParser: unexpected HMAC bracket string: " + m_bracketString); + + pMAC->SetKey(key, key.size()); + int Tlen = atol(m_data["Tlen"].c_str()); + SecByteBlock tag(Tlen); + StringSource(m_data["Msg"], true, new HexDecoder(new HashFilter(*pMAC, new ArraySink(tag, Tlen), false, Tlen))); + OutputData(output, "Mac ", tag); + AttachedTransformation()->Put((byte *)output.data(), output.size()); + output.resize(0); + return; + } + member_ptr<BlockCipher> pBT; if (m_algorithm == "DES") pBT.reset(NewBT((DES*)0)); @@ -509,8 +887,8 @@ protected: CV[0] = IB[0] = iv; TXT[0] = GetData("TEXT"); - unsigned int outerCount = (m_algorithm == "AES") ? 100 : 400; - unsigned int innerCount = (m_algorithm == "AES") ? 1000 : 10000; + int outerCount = (m_algorithm == "AES") ? 100 : 400; + int innerCount = (m_algorithm == "AES") ? 1000 : 10000; for (int i=0; i<outerCount; i++) { @@ -592,7 +970,7 @@ protected: throw Exception(Exception::OTHER_ERROR, "TestDataParser: unexpected mode: " + m_mode); } - OutputData(output, COUNT, i); + OutputData(output, "COUNT ", i); OutputData(output, KEY_T, KEY[i]); if (m_mode == "CBC") OutputData(output, IV, CV[0]); @@ -643,7 +1021,7 @@ protected: for (int i=0; i<100; i++) { - pCipher->SetKey(KEY[i], keySize, MakeParameters(Name::IV(), (const byte *)ivs[i])(Name::FeedbackSize(), (int)K/8)); + pCipher->SetKey(KEY[i], keySize, MakeParameters(Name::IV(), (const byte *)ivs[i])(Name::FeedbackSize(), (int)K/8, false)); for (int j=0; j<1000; j++) { @@ -709,7 +1087,7 @@ protected: { std::vector<std::string> result; std::string s; - for (int i=0; i<line.size(); i++) + for (unsigned int i=0; i<line.size(); i++) { if (isalnum(line[i]) || line[i] == '^') s += line[i]; @@ -776,7 +1154,7 @@ protected: if (m_algorithm == "DSS" && m_test == "sha") { - for (int i = 0; i < tokens.size(); i++) + for (unsigned int i = 0; i < tokens.size(); i++) { if (tokens[i] == "^") DoTest(); @@ -786,13 +1164,14 @@ protected: } else { - if (!m_line.empty() && m_algorithm == "DSS" && m_test != "pqg") + if (!m_line.empty() && ((m_algorithm == "RSA" && m_test != "Gen") || m_algorithm == "RNG" || m_algorithm == "HMAC" || m_algorithm == "SHA2" || (m_algorithm == "ECDSA" && m_test != "KeyPair") || (m_algorithm == "DSS" && m_test != "pqg"))) { + // copy input to output std::string output = m_line + '\n'; AttachedTransformation()->Put((byte *)output.data(), output.size()); } - for (int i = 0; i < tokens.size(); i++) + for (unsigned int i = 0; i < tokens.size(); i++) { if (m_firstLine && m_algorithm != "DSS") { @@ -816,9 +1195,7 @@ protected: data = tokens[i+1]; DataType t = m_nameToType[key]; m_typeToName[t] = key; - SecByteBlock data2(data.size() / 2); - StringSource(data, true, new HexDecoder(new ArraySink(data2, data2.size()))); - m_data2[t] = data2; + m_data2[t] = DecodeHex(data); if (key == m_trigger || (t == OUTPUT && !m_data2[INPUT].empty())) DoTest(); @@ -836,6 +1213,13 @@ protected: return m_data2[m_nameToType[key]]; } + static SecByteBlock DecodeHex(const std::string &data) + { + SecByteBlock data2(data.size() / 2); + StringSource(data, true, new HexDecoder(new ArraySink(data2, data2.size()))); + return data2; + } + std::string m_algorithm, m_test, m_mode, m_line, m_bracketString, m_trigger; unsigned int m_feedbackSize, m_blankLineTransition; bool m_encrypt, m_firstLine; @@ -855,45 +1239,65 @@ protected: std::vector<unsigned int> m_compactString; }; -int main (int argc, char **argv) +int FIPS_140_AlgorithmTest(int argc, char **argv) { + argc--; + argv++; + std::string algorithm = argv[1]; std::string pathname = argv[2]; - int i = pathname.find_last_of("\\/"); + unsigned int i = pathname.find_last_of("\\/"); std::string filename = pathname.substr(i == std::string::npos ? 0 : i+1); - std::string mode; - if (filename[0] == 'S' || filename[0] == 'T') - mode = filename.substr(1, 3); - else - mode = filename.substr(0, 3); - for (i = 0; i<mode.size(); i++) - mode[i] = toupper(mode[i]); - unsigned int feedbackSize = mode == "CFB" ? atoi(filename.substr(filename.find_first_of("0123456789")).c_str()) : 0; - std::string test; - if (algorithm == "DSS") - test = filename.substr(0, filename.size() - 4); - else if (filename.find("Monte") != std::string::npos) - test = "MONTE"; - else if (filename.find("MCT") != std::string::npos) - test = "MCT"; - else - test = "KAT"; - bool encrypt = (filename.find("vrct") == std::string::npos); - - BufferedTransformation *pSink = NULL; - - if (argc > 3) + try { - std::string outDir = argv[3]; - if (*outDir.rbegin() != '\\' && *outDir.rbegin() != '/') - outDir += '/'; - std::string outPathname = outDir + filename.substr(0, filename.size() - 3) + "rsp"; - pSink = new FileSink(outPathname.c_str(), false); - } - else - pSink = new FileSink(cout); + std::string mode; + if (algorithm == "SHA2") + mode = filename.substr(3, 3); + else if (algorithm == "RSA") + mode = filename.substr(6, 1); + else if (filename[0] == 'S' || filename[0] == 'T') + mode = filename.substr(1, 3); + else + mode = filename.substr(0, 3); + for (i = 0; i<mode.size(); i++) + mode[i] = toupper(mode[i]); + unsigned int feedbackSize = mode == "CFB" ? atoi(filename.substr(filename.find_first_of("0123456789")).c_str()) : 0; + std::string test; + if (algorithm == "DSS" || algorithm == "ECDSA") + test = filename.substr(0, filename.size() - 4); + else if (algorithm == "RSA") + test = filename.substr(3, 3); + else if (filename.find("Monte") != std::string::npos) + test = "MONTE"; + else if (filename.find("MCT") != std::string::npos) + test = "MCT"; + else + test = "KAT"; + bool encrypt = (filename.find("vrct") == std::string::npos); + + BufferedTransformation *pSink = NULL; - FileSource(pathname.c_str(), true, new LineBreakParser(new TestDataParser(algorithm, test, mode, feedbackSize, encrypt, pSink)), false); + if (argc > 3) + { + std::string outDir = argv[3]; + if (*outDir.rbegin() != '\\' && *outDir.rbegin() != '/') + outDir += '/'; + std::string outPathname = outDir + filename.substr(0, filename.size() - 3) + "rsp"; + pSink = new FileSink(outPathname.c_str(), false); + } + else + pSink = new FileSink(cout); + + FileSource(pathname.c_str(), true, new LineBreakParser(new TestDataParser(algorithm, test, mode, feedbackSize, encrypt, pSink)), false); + } + catch (...) + { + cout << "file: " << filename << endl; + throw; + } return 0; } + +extern int (*AdhocTest)(int argc, char *argv[]); +static int s_i = (AdhocTest = &FIPS_140_AlgorithmTest, 0); #endif diff --git a/fipstest.cpp b/fipstest.cpp index 7a3f1a59..a9245c84 100644 --- a/fipstest.cpp +++ b/fipstest.cpp @@ -39,17 +39,18 @@ template <class CIPHER> void X917RNG_KnownAnswerTest( const char *key, const char *seed, + const char *deterministicTimeVector, const char *output, - unsigned int deterministicTimeVector, CIPHER *dummy = NULL) { #ifdef OS_RNG_AVAILABLE - std::string decodedKey, decodedSeed; + std::string decodedKey, decodedSeed, decodedDeterministicTimeVector; StringSource(key, true, new HexDecoder(new StringSink(decodedKey))); StringSource(seed, true, new HexDecoder(new StringSink(decodedSeed))); + StringSource(deterministicTimeVector, true, new HexDecoder(new StringSink(decodedDeterministicTimeVector))); AutoSeededX917RNG<CIPHER> rng; - rng.Reseed((const byte *)decodedKey.data(), decodedKey.size(), (const byte *)decodedSeed.data(), deterministicTimeVector); + rng.Reseed((const byte *)decodedKey.data(), decodedKey.size(), (const byte *)decodedSeed.data(), (const byte *)decodedDeterministicTimeVector.data()); KnownAnswerTest(rng, output); #else throw 0; @@ -360,19 +361,9 @@ void DoPowerUpSelfTest(const char *moduleFilename, const byte *expectedModuleMac X917RNG_KnownAnswerTest<DES_EDE3>( "48851090B4992453E83CDA86416534E53EA2FCE1A0B3A40C", // key "7D00BD0A79F6B0F5", // seed - "22B590B08B53363AEB89AD65F81A5B6FB83F326CE06BF35751E6C41B43B729C4", // output - 1489728269); // time vector - -/* SymmetricEncryptionKnownAnswerTest<DES>( - "0123456789abcdef", // key - "1234567890abcdef", // IV - "4e6f77206973207468652074696d6520666f7220616c6c20", // plaintext - "3fa40e8a984d48156a271787ab8883f9893d51ec4b563b53", // ecb - "E5C7CDDE872BF27C43E934008C389C0F683788499A7C05F6", // cbc - "F3096249C7F46E51A69E839B1A92F78403467133898EA622", // cfb - "f3096249c7f46e5135f24a242eeb3d3f3d6d5be3255af8c3", // ofb - "F3096249C7F46E51163A8CA0FFC94C27FA2F80F480B86F75");// ctr -*/ + "0000000000000001", // time vector + "fdc31a6dd6b43aca81dfe8a696a2f9cf661955a44124a05033b7fff71b5b0341"); // output + SymmetricEncryptionKnownAnswerTest<DES_EDE3>( "385D7189A5C3D485E1370AA5D408082B5CCCCB5E19F2D90E", "C141B5FCCD28DC8A", @@ -414,10 +405,14 @@ void DoPowerUpSelfTest(const char *moduleFilename, const byte *expectedModuleMac "874d6191b620e3261bef6864990db6ce9806f66b7970fdff8617187bb9fffdff5ae4df3edbd5d35e5b4f09020db03eab1e031dda2fbe03d1792170a0f3009cee"); // ctr - SecureHashKnownAnswerTest<SHA>( + SecureHashKnownAnswerTest<SHA1>( "abc", "A9993E364706816ABA3E25717850C26C9CD0D89D"); -/* + + SecureHashKnownAnswerTest<SHA224>( + "abc", + "23097d223405d8228642a477bda255b32aadbce4bda0b3f7e36c9da7"); + SecureHashKnownAnswerTest<SHA256>( "abc", "ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad"); @@ -429,46 +424,62 @@ void DoPowerUpSelfTest(const char *moduleFilename, const byte *expectedModuleMac SecureHashKnownAnswerTest<SHA512>( "abc", "ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f"); -*/ - MAC_KnownAnswerTest<HMAC<SHA> >( + + MAC_KnownAnswerTest<HMAC<SHA1> >( "303132333435363738393a3b3c3d3e3f40414243", "Sample #2", "0922d3405faa3d194f82a45830737d5cc6c75d24"); -/* - MAC_KnownAnswerTest<HMAC<SHA256> >( - "303132333435363738393a3b3c3d3e3f40414243", - "abc", - "D28363F335B2DAE468793A38680DEA9F7FB8BE1DCEDA197CDB3B1CB59A9F6422"); - MAC_KnownAnswerTest<HMAC<SHA384> >( - "303132333435363738393a3b3c3d3e3f40414243", - "abc", - "E7740C592F1414C969190EFACF51FC8BE1CB52F5DC5E686200D2CA1773D151DB19C59112371CE374165A6BF72AEF69D0"); - - MAC_KnownAnswerTest<HMAC<SHA512> >( - "303132333435363738393a3b3c3d3e3f40414243", - "abc", - "BF07864E733B995862F3C2D432C7FF2F5EB073FFFC4F880CD94D5D21086476B7428F27BE694A9D9CB3BB500FE1255852BAFCBAF4042390B3706CDF02421B51AC"); -*/ - SignatureKnownAnswerTest<RSASS<PKCS1v15, SHA> >( + const char *keyRSA1 = "30820150020100300d06092a864886f70d01010105000482013a3082013602010002400a66791dc6988168de7ab77419bb7fb0" "c001c62710270075142942e19a8d8c51d053b3e3782a1de5dc5af4ebe99468170114a1dfe67cdc9a9af55d655620bbab0203010001" "02400123c5b61ba36edb1d3679904199a89ea80c09b9122e1400c09adcf7784676d01d23356a7d44d6bd8bd50e94bfc723fa" "87d8862b75177691c11d757692df8881022033d48445c859e52340de704bcdda065fbb4058d740bd1d67d29e9c146c11cf61" "0220335e8408866b0fd38dc7002d3f972c67389a65d5d8306566d5c4f2a5aa52628b0220045ec90071525325d3d46db79695e9af" "acc4523964360e02b119baa366316241022015eb327360c7b60d12e5e2d16bdcd97981d17fba6b70db13b20b436e24eada590220" - "2ca6366d72781dfa24d34a9a24cbc2ae927a9958af426563ff63fb11658a461d", + "2ca6366d72781dfa24d34a9a24cbc2ae927a9958af426563ff63fb11658a461d"; + + const char *keyRSA2 = + "30820273020100300D06092A864886F70D01010105000482025D3082025902010002818100D40AF9" + "A2B713034249E5780056D70FC7DE75D76E44565AA6A6B8ED9646F3C19F9E254D72D7DE6E49DB2264" + "0C1D05AB9E2A5F901D8F3FE1F7AE02CEE2ECCE54A40ABAE55A004692752E70725AEEE7CDEA67628A" + "82A9239B4AB660C2BC56D9F01E90CBAAB9BF0FC8E17173CEFC5709A29391A7DDF3E0B758691AAF30" + "725B292F4F020111027F18C0BA087D082C45D75D3594E0767E4820818EB35612B80CEAB8C880ACA5" + "44B6876DFFEF85A576C0D45B551AFAA1FD63209CD745DF75C5A0F0B580296EA466CD0338207E4752" + "FF4E7DB724D8AE18CE5CF4153BB94C27869FBB50E64F02546E4B02997A0B8623E64017CC770759C6" + "695DB649EEFD829D688D441BCC4E7348F1024100EF86DD7AF3F32CDE8A9F6564E43A559A0C9F8BAD" + "36CC25330548B347AC158A345631FA90F7B873C36EFFAE2F7823227A3F580B5DD18304D5932751E7" + "43E9234F024100E2A039854B55688740E32A51DF4AF88613D91A371CF8DDD95D780A89D7CF2119A9" + "54F1AC0F3DCDB2F6959926E6D9D37D8BC07A4C634DE6F16315BD5F0DAC340102407ECEEDB9903572" + "1B76909F174BA6698DCA72953D957B22C0A871C8531EDE3A1BB52984A719BC010D1CA57A555DB83F" + "6DE54CBAB932AEC652F38D497A6F3F30CF024100854F30E4FF232E6DADB2CD99926855F484255AB7" + "01FBCDCB27EC426F33A7046972AA700ADBCA008763DF87440F52F4E070531AC385B55AAC1C2AE7DD" + "8F9278F1024100C313F4AF9E4A9DE1253C21080CE524251560C111550772FD08690F13FBE658342E" + "BD2D41C9DCB12374E871B1839E26CAE252E1AE3DAAD5F1EE1F42B4D0EE7581"; + + SignatureKnownAnswerTest<RSASS<PKCS1v15, SHA1> >( + keyRSA1, "Everyone gets Friday off.", "0610761F95FFD1B8F29DA34212947EC2AA0E358866A722F03CC3C41487ADC604A48FF54F5C6BEDB9FB7BD59F82D6E55D8F3174BA361B2214B2D74E8825E04E81"); + SignatureKnownAnswerTest<RSASS_ISO<SHA1> >( + keyRSA2, + "test", + "32F6BA41C8930DE71EE67F2627172CC539EDE04267FDE03AC295E3C50311F26C3B275D3AF513AC96" + "8EE493BAB7DA3A754661D1A7C4A0D1A2B7EE8B313AACD8CB8BFBC5C15EFB0EF15C86A9334A1E87AD" + "291EB961B5CA0E84930429B28780816AA94F96FC2367B71E2D2E4866FA966795B147F00600E5207E" + "2F189C883B37477C"); + SignaturePairwiseConsistencyTest<DSA>( "3082014A0201003082012B06072A8648CE3804013082011E02818100F468699A6F6EBCC0120D3B34C8E007F125EC7D81F763B8D0F33869AE3BD6B9F2ECCC7DF34DF84C0307449E9B85D30D57194BCCEB310F48141914DD13A077AAF9B624A6CBE666BBA1D7EBEA95B5BA6F54417FD5D4E4220C601E071D316A24EA814E8B0122DBF47EE8AEEFD319EBB01DD95683F10DBB4FEB023F8262A07EAEB7FD02150082AD4E034DA6EEACDFDAE68C36F2BAD614F9E53B02818071AAF73361A26081529F7D84078ADAFCA48E031DB54AD57FB1A833ADBD8672328AABAA0C756247998D7A5B10DACA359D231332CE8120B483A784FE07D46EEBFF0D7D374A10691F78653E6DC29E27CCB1B174923960DFE5B959B919B2C3816C19251832AFD8E35D810E598F82877ABF7D40A041565168BD7F0E21E3FE2A8D8C1C0416021426EBA66E846E755169F84A1DA981D86502405DDF"); - SignaturePairwiseConsistencyTest<ECDSA<EC2N, SHA> >( + SignaturePairwiseConsistencyTest<ECDSA<EC2N, SHA1> >( "302D020100301006072A8648CE3D020106052B8104000404163014020101040F0070337065E1E196980A9D00E37211"); - SignaturePairwiseConsistencyTest<ECDSA<ECP, SHA> >( + SignaturePairwiseConsistencyTest<ECDSA<ECP, SHA1> >( "3039020100301306072A8648CE3D020106082A8648CE3D030101041F301D02010104182BB8A13C8B867010BD9471D9E81FDB01ABD0538C64D6249A"); + + SignaturePairwiseConsistencyTest<RSASS<PSS, SHA1> >(keyRSA1); } catch (...) { @@ -353,7 +353,7 @@ private: }; // construct new GF2NP from the ASN.1 sequence Characteristic-two -CRYPTOPP_DLL GF2NP * BERDecodeGF2NP(BufferedTransformation &bt); +CRYPTOPP_DLL GF2NP * CRYPTOPP_API BERDecodeGF2NP(BufferedTransformation &bt); NAMESPACE_END @@ -57,7 +57,7 @@ public: Integer ConvertElementToInteger(const Element &element) const {return element;} Integer GetMaxExponent() const; - static std::string StaticAlgorithmNamePrefix() {return "";} + static std::string CRYPTOPP_API StaticAlgorithmNamePrefix() {return "";} OID GetAlgorithmID() const; @@ -152,7 +152,7 @@ template <class T> class DL_Algorithm_GDSA : public DL_ElgamalLikeSignatureAlgorithm<T> { public: - static const char * StaticAlgorithmName() {return "DSA-1363";} + static const char * CRYPTOPP_API StaticAlgorithmName() {return "DSA-1363";} void Sign(const DL_GroupParameters<T> ¶ms, const Integer &x, const Integer &k, const Integer &e, Integer &r, Integer &s) const { @@ -184,7 +184,7 @@ template <class T> class DL_Algorithm_NR : public DL_ElgamalLikeSignatureAlgorithm<T> { public: - static const char * StaticAlgorithmName() {return "NR";} + static const char * CRYPTOPP_API StaticAlgorithmName() {return "NR";} void Sign(const DL_GroupParameters<T> ¶ms, const Integer &x, const Integer &k, const Integer &e, Integer &r, Integer &s) const { @@ -388,17 +388,17 @@ struct CRYPTOPP_DLL DSA : public DL_SS< SHA, DSA> { - static std::string StaticAlgorithmName() {return std::string("DSA");} + 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 GeneratePrimes(const byte *seed, unsigned int seedLength, int &counter, + 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 IsValidPrimeLength(unsigned int pbits) + 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 @@ -528,7 +528,7 @@ struct DLIES DL_EncryptionAlgorithm_Xor<HMAC<SHA1>, DHAES_MODE>, DLIES<> > { - static std::string StaticAlgorithmName() {return "DLIES";} // TODO: fix this after name is standardized + static std::string CRYPTOPP_API StaticAlgorithmName() {return "DLIES";} // TODO: fix this after name is standardized }; NAMESPACE_END diff --git a/integer.cpp b/integer.cpp index ff62879d..8ba4fe51 100644 --- a/integer.cpp +++ b/integer.cpp @@ -38,7 +38,7 @@ NAMESPACE_BEGIN(CryptoPP) -bool FunctionAssignIntToInteger(const std::type_info &valueType, void *pInteger, const void *pInt) +bool AssignIntToInteger(const std::type_info &valueType, void *pInteger, const void *pInt) { if (valueType != typeid(Integer)) return false; @@ -46,7 +46,7 @@ bool FunctionAssignIntToInteger(const std::type_info &valueType, void *pInteger, return true; } -static const char s_RunAtStartup = (AssignIntToInteger = FunctionAssignIntToInteger, 0); +static const char s_RunAtStartup = (g_pAssignIntToInteger = AssignIntToInteger, 0); #ifdef SSE2_INTRINSICS_AVAILABLE template <class T> @@ -983,27 +983,27 @@ static bool IsP4() class PentiumOptimized : public Portable { public: - static word CRYPTOPP_CDECL Add(word *C, const word *A, const word *B, unsigned int N); - static word CRYPTOPP_CDECL Subtract(word *C, const word *A, const word *B, unsigned int N); - static void CRYPTOPP_CDECL Multiply4(word *C, const word *A, const word *B); - static void CRYPTOPP_CDECL Multiply8(word *C, const word *A, const word *B); - static void CRYPTOPP_CDECL Multiply8Bottom(word *C, const word *A, const word *B); + static word Add(word *C, const word *A, const word *B, unsigned int N); + static word Subtract(word *C, const word *A, const word *B, unsigned int N); + static void Multiply4(word *C, const word *A, const word *B); + static void Multiply8(word *C, const word *A, const word *B); + static void Multiply8Bottom(word *C, const word *A, const word *B); }; class P4Optimized { public: - static word CRYPTOPP_CDECL Add(word *C, const word *A, const word *B, unsigned int N); - static word CRYPTOPP_CDECL Subtract(word *C, const word *A, const word *B, unsigned int N); + static word Add(word *C, const word *A, const word *B, unsigned int N); + static word Subtract(word *C, const word *A, const word *B, unsigned int N); #ifdef SSE2_INTRINSICS_AVAILABLE - static void CRYPTOPP_CDECL Multiply4(word *C, const word *A, const word *B); - static void CRYPTOPP_CDECL Multiply8(word *C, const word *A, const word *B); - static void CRYPTOPP_CDECL Multiply8Bottom(word *C, const word *A, const word *B); + static void Multiply4(word *C, const word *A, const word *B); + static void Multiply8(word *C, const word *A, const word *B); + static void Multiply8Bottom(word *C, const word *A, const word *B); #endif }; -typedef word (CRYPTOPP_CDECL * PAddSub)(word *C, const word *A, const word *B, unsigned int N); -typedef void (CRYPTOPP_CDECL * PMul)(word *C, const word *A, const word *B); +typedef word (* PAddSub)(word *C, const word *A, const word *B, unsigned int N); +typedef void (* PMul)(word *C, const word *A, const word *B); static PAddSub s_pAdd, s_pSub; #ifdef SSE2_INTRINSICS_AVAILABLE @@ -2947,7 +2947,6 @@ static Integer StringToInteger(const T *str) { word radix; // GCC workaround - // std::char_traits doesn't exist in GCC 2.x // std::char_traits<wchar_t>::length() not defined in GCC 3.2 and STLport 4.5.3 unsigned int length; for (length = 0; str[length] != 0; length++) {} @@ -3989,16 +3988,16 @@ ModularArithmetic::ModularArithmetic(BufferedTransformation &bt) OID oid(seq); if (oid != ASN1::prime_field()) BERDecodeError(); - modulus.BERDecode(seq); + m_modulus.BERDecode(seq); seq.MessageEnd(); - result.reg.resize(modulus.reg.size()); + m_result.reg.resize(m_modulus.reg.size()); } void ModularArithmetic::DEREncode(BufferedTransformation &bt) const { DERSequenceEncoder seq(bt); ASN1::prime_field().DEREncode(seq); - modulus.DEREncode(seq); + m_modulus.DEREncode(seq); seq.MessageEnd(); } @@ -4014,50 +4013,50 @@ void ModularArithmetic::BERDecodeElement(BufferedTransformation &in, Element &a) const Integer& ModularArithmetic::Half(const Integer &a) const { - if (a.reg.size()==modulus.reg.size()) + if (a.reg.size()==m_modulus.reg.size()) { - CryptoPP::DivideByPower2Mod(result.reg.begin(), a.reg, 1, modulus.reg, a.reg.size()); - return result; + CryptoPP::DivideByPower2Mod(m_result.reg.begin(), a.reg, 1, m_modulus.reg, a.reg.size()); + return m_result; } else - return result1 = (a.IsEven() ? (a >> 1) : ((a+modulus) >> 1)); + return m_result1 = (a.IsEven() ? (a >> 1) : ((a+m_modulus) >> 1)); } const Integer& ModularArithmetic::Add(const Integer &a, const Integer &b) const { - if (a.reg.size()==modulus.reg.size() && b.reg.size()==modulus.reg.size()) + if (a.reg.size()==m_modulus.reg.size() && b.reg.size()==m_modulus.reg.size()) { - if (CryptoPP::Add(result.reg.begin(), a.reg, b.reg, a.reg.size()) - || Compare(result.reg, modulus.reg, a.reg.size()) >= 0) + if (CryptoPP::Add(m_result.reg.begin(), a.reg, b.reg, a.reg.size()) + || Compare(m_result.reg, m_modulus.reg, a.reg.size()) >= 0) { - CryptoPP::Subtract(result.reg.begin(), result.reg, modulus.reg, a.reg.size()); + CryptoPP::Subtract(m_result.reg.begin(), m_result.reg, m_modulus.reg, a.reg.size()); } - return result; + return m_result; } else { - result1 = a+b; - if (result1 >= modulus) - result1 -= modulus; - return result1; + m_result1 = a+b; + if (m_result1 >= m_modulus) + m_result1 -= m_modulus; + return m_result1; } } Integer& ModularArithmetic::Accumulate(Integer &a, const Integer &b) const { - if (a.reg.size()==modulus.reg.size() && b.reg.size()==modulus.reg.size()) + if (a.reg.size()==m_modulus.reg.size() && b.reg.size()==m_modulus.reg.size()) { if (CryptoPP::Add(a.reg, a.reg, b.reg, a.reg.size()) - || Compare(a.reg, modulus.reg, a.reg.size()) >= 0) + || Compare(a.reg, m_modulus.reg, a.reg.size()) >= 0) { - CryptoPP::Subtract(a.reg, a.reg, modulus.reg, a.reg.size()); + CryptoPP::Subtract(a.reg, a.reg, m_modulus.reg, a.reg.size()); } } else { a+=b; - if (a>=modulus) - a-=modulus; + if (a>=m_modulus) + a-=m_modulus; } return a; @@ -4065,33 +4064,33 @@ Integer& ModularArithmetic::Accumulate(Integer &a, const Integer &b) const const Integer& ModularArithmetic::Subtract(const Integer &a, const Integer &b) const { - if (a.reg.size()==modulus.reg.size() && b.reg.size()==modulus.reg.size()) + if (a.reg.size()==m_modulus.reg.size() && b.reg.size()==m_modulus.reg.size()) { - if (CryptoPP::Subtract(result.reg.begin(), a.reg, b.reg, a.reg.size())) - CryptoPP::Add(result.reg.begin(), result.reg, modulus.reg, a.reg.size()); - return result; + if (CryptoPP::Subtract(m_result.reg.begin(), a.reg, b.reg, a.reg.size())) + CryptoPP::Add(m_result.reg.begin(), m_result.reg, m_modulus.reg, a.reg.size()); + return m_result; } else { - result1 = a-b; - if (result1.IsNegative()) - result1 += modulus; - return result1; + m_result1 = a-b; + if (m_result1.IsNegative()) + m_result1 += m_modulus; + return m_result1; } } Integer& ModularArithmetic::Reduce(Integer &a, const Integer &b) const { - if (a.reg.size()==modulus.reg.size() && b.reg.size()==modulus.reg.size()) + if (a.reg.size()==m_modulus.reg.size() && b.reg.size()==m_modulus.reg.size()) { if (CryptoPP::Subtract(a.reg, a.reg, b.reg, a.reg.size())) - CryptoPP::Add(a.reg, a.reg, modulus.reg, a.reg.size()); + CryptoPP::Add(a.reg, a.reg, m_modulus.reg, a.reg.size()); } else { a-=b; if (a.IsNegative()) - a+=modulus; + a+=m_modulus; } return a; @@ -4102,18 +4101,18 @@ const Integer& ModularArithmetic::Inverse(const Integer &a) const if (!a) return a; - CopyWords(result.reg.begin(), modulus.reg, modulus.reg.size()); - if (CryptoPP::Subtract(result.reg.begin(), result.reg, a.reg, a.reg.size())) - Decrement(result.reg.begin()+a.reg.size(), 1, modulus.reg.size()-a.reg.size()); + CopyWords(m_result.reg.begin(), m_modulus.reg, m_modulus.reg.size()); + if (CryptoPP::Subtract(m_result.reg.begin(), m_result.reg, a.reg, a.reg.size())) + Decrement(m_result.reg.begin()+a.reg.size(), 1, m_modulus.reg.size()-a.reg.size()); - return result; + return m_result; } Integer ModularArithmetic::CascadeExponentiate(const Integer &x, const Integer &e1, const Integer &y, const Integer &e2) const { - if (modulus.IsOdd()) + if (m_modulus.IsOdd()) { - MontgomeryRepresentation dr(modulus); + MontgomeryRepresentation dr(m_modulus); return dr.ConvertOut(dr.CascadeExponentiate(dr.ConvertIn(x), e1, dr.ConvertIn(y), e2)); } else @@ -4122,9 +4121,9 @@ Integer ModularArithmetic::CascadeExponentiate(const Integer &x, const Integer & void ModularArithmetic::SimultaneousExponentiate(Integer *results, const Integer &base, const Integer *exponents, unsigned int exponentsCount) const { - if (modulus.IsOdd()) + if (m_modulus.IsOdd()) { - MontgomeryRepresentation dr(modulus); + MontgomeryRepresentation dr(m_modulus); dr.SimultaneousExponentiate(results, dr.ConvertIn(base), exponents, exponentsCount); for (unsigned int i=0; i<exponentsCount; i++) results[i] = dr.ConvertOut(results[i]); @@ -4135,75 +4134,75 @@ void ModularArithmetic::SimultaneousExponentiate(Integer *results, const Integer MontgomeryRepresentation::MontgomeryRepresentation(const Integer &m) // modulus must be odd : ModularArithmetic(m), - u((word)0, modulus.reg.size()), - workspace(5*modulus.reg.size()) + m_u((word)0, m_modulus.reg.size()), + m_workspace(5*m_modulus.reg.size()) { - if (!modulus.IsOdd()) + if (!m_modulus.IsOdd()) throw InvalidArgument("MontgomeryRepresentation: Montgomery representation requires an odd modulus"); - RecursiveInverseModPower2(u.reg, workspace, modulus.reg, modulus.reg.size()); + RecursiveInverseModPower2(m_u.reg, m_workspace, m_modulus.reg, m_modulus.reg.size()); } const Integer& MontgomeryRepresentation::Multiply(const Integer &a, const Integer &b) const { - word *const T = workspace.begin(); - word *const R = result.reg.begin(); - const unsigned int N = modulus.reg.size(); + word *const T = m_workspace.begin(); + word *const R = m_result.reg.begin(); + const unsigned int N = m_modulus.reg.size(); assert(a.reg.size()<=N && b.reg.size()<=N); AsymmetricMultiply(T, T+2*N, a.reg, a.reg.size(), b.reg, b.reg.size()); SetWords(T+a.reg.size()+b.reg.size(), 0, 2*N-a.reg.size()-b.reg.size()); - MontgomeryReduce(R, T+2*N, T, modulus.reg, u.reg, N); - return result; + MontgomeryReduce(R, T+2*N, T, m_modulus.reg, m_u.reg, N); + return m_result; } const Integer& MontgomeryRepresentation::Square(const Integer &a) const { - word *const T = workspace.begin(); - word *const R = result.reg.begin(); - const unsigned int N = modulus.reg.size(); + word *const T = m_workspace.begin(); + word *const R = m_result.reg.begin(); + const unsigned int N = m_modulus.reg.size(); assert(a.reg.size()<=N); CryptoPP::Square(T, T+2*N, a.reg, a.reg.size()); SetWords(T+2*a.reg.size(), 0, 2*N-2*a.reg.size()); - MontgomeryReduce(R, T+2*N, T, modulus.reg, u.reg, N); - return result; + MontgomeryReduce(R, T+2*N, T, m_modulus.reg, m_u.reg, N); + return m_result; } Integer MontgomeryRepresentation::ConvertOut(const Integer &a) const { - word *const T = workspace.begin(); - word *const R = result.reg.begin(); - const unsigned int N = modulus.reg.size(); + word *const T = m_workspace.begin(); + word *const R = m_result.reg.begin(); + const unsigned int N = m_modulus.reg.size(); assert(a.reg.size()<=N); CopyWords(T, a.reg, a.reg.size()); SetWords(T+a.reg.size(), 0, 2*N-a.reg.size()); - MontgomeryReduce(R, T+2*N, T, modulus.reg, u.reg, N); - return result; + MontgomeryReduce(R, T+2*N, T, m_modulus.reg, m_u.reg, N); + return m_result; } const Integer& MontgomeryRepresentation::MultiplicativeInverse(const Integer &a) const { // return (EuclideanMultiplicativeInverse(a, modulus)<<(2*WORD_BITS*modulus.reg.size()))%modulus; - word *const T = workspace.begin(); - word *const R = result.reg.begin(); - const unsigned int N = modulus.reg.size(); + word *const T = m_workspace.begin(); + word *const R = m_result.reg.begin(); + const unsigned int N = m_modulus.reg.size(); assert(a.reg.size()<=N); CopyWords(T, a.reg, a.reg.size()); SetWords(T+a.reg.size(), 0, 2*N-a.reg.size()); - MontgomeryReduce(R, T+2*N, T, modulus.reg, u.reg, N); - unsigned k = AlmostInverse(R, T, R, N, modulus.reg, N); + MontgomeryReduce(R, T+2*N, T, m_modulus.reg, m_u.reg, N); + unsigned k = AlmostInverse(R, T, R, N, m_modulus.reg, N); // cout << "k=" << k << " N*32=" << 32*N << endl; if (k>N*WORD_BITS) - DivideByPower2Mod(R, R, k-N*WORD_BITS, modulus.reg, N); + DivideByPower2Mod(R, R, k-N*WORD_BITS, m_modulus.reg, N); else - MultiplyByPower2Mod(R, R, N*WORD_BITS-k, modulus.reg, N); + MultiplyByPower2Mod(R, R, N*WORD_BITS-k, m_modulus.reg, N); - return result; + return m_result; } NAMESPACE_END @@ -62,7 +62,7 @@ NAMESPACE_BEGIN(CryptoPP) typedef SecWordBlock SecAlignedWordBlock; #endif -void CRYPTOPP_DLL DisableSSE2(); +void CRYPTOPP_DLL CRYPTOPP_API DisableSSE2(); //! multiple precision integer and basic arithmetics /*! This class can represent positive and negative integers @@ -144,11 +144,11 @@ public: Integer(RandomNumberGenerator &rng, unsigned int bitcount); //! avoid calling constructors for these frequently used integers - static const Integer &Zero(); + static const Integer & CRYPTOPP_API Zero(); //! avoid calling constructors for these frequently used integers - static const Integer &One(); + static const Integer & CRYPTOPP_API One(); //! avoid calling constructors for these frequently used integers - static const Integer &Two(); + static const Integer & CRYPTOPP_API Two(); //! create a random integer of special type /*! Ideally, the random integer created should be uniformly distributed @@ -164,7 +164,7 @@ public: Integer(RandomNumberGenerator &rng, const Integer &min, const Integer &max, RandomNumberType rnType=ANY, const Integer &equiv=Zero(), const Integer &mod=One()); //! return the integer 2**e - static Integer Power2(unsigned int e); + static Integer CRYPTOPP_API Power2(unsigned int e); //@} //! \name ENCODE/DECODE @@ -380,20 +380,20 @@ public: Integer MultiplicativeInverse() const; //! modular multiplication - CRYPTOPP_DLL friend Integer a_times_b_mod_c(const Integer &x, const Integer& y, const Integer& m); + CRYPTOPP_DLL friend Integer CRYPTOPP_API a_times_b_mod_c(const Integer &x, const Integer& y, const Integer& m); //! modular exponentiation - CRYPTOPP_DLL friend Integer a_exp_b_mod_c(const Integer &x, const Integer& e, const Integer& m); + CRYPTOPP_DLL friend Integer CRYPTOPP_API a_exp_b_mod_c(const Integer &x, const Integer& e, const Integer& m); //! calculate r and q such that (a == d*q + r) && (0 <= r < abs(d)) - static void Divide(Integer &r, Integer &q, const Integer &a, const Integer &d); + static void CRYPTOPP_API Divide(Integer &r, Integer &q, const Integer &a, const Integer &d); //! use a faster division algorithm when divisor is short - static void Divide(word &r, Integer &q, const Integer &a, word d); + static void CRYPTOPP_API Divide(word &r, Integer &q, const Integer &a, word d); //! returns same result as Divide(r, q, a, Power2(n)), but faster - static void DivideByPowerOf2(Integer &r, Integer &q, const Integer &a, unsigned int n); + static void CRYPTOPP_API DivideByPowerOf2(Integer &r, Integer &q, const Integer &a, unsigned int n); //! greatest common divisor - static Integer Gcd(const Integer &a, const Integer &n); + static Integer CRYPTOPP_API Gcd(const Integer &a, const Integer &n); //! calculate multiplicative inverse of *this mod n Integer InverseMod(const Integer &n) const; //! @@ -403,9 +403,9 @@ public: //! \name INPUT/OUTPUT //@{ //! - friend CRYPTOPP_DLL std::istream& operator>>(std::istream& in, Integer &a); + friend CRYPTOPP_DLL std::istream& CRYPTOPP_API operator>>(std::istream& in, Integer &a); //! - friend CRYPTOPP_DLL std::ostream& operator<<(std::ostream& out, const Integer &a); + friend CRYPTOPP_DLL std::ostream& CRYPTOPP_API operator<<(std::ostream& out, const Integer &a); //@} private: @@ -23,7 +23,7 @@ class CRYPTOPP_NO_VTABLE IteratedHashBase : public BASE public: typedef T HashWordType; - IteratedHashBase() : m_countHi(0), m_countLo(0) {} + IteratedHashBase() : m_countLo(0), m_countHi(0) {} unsigned int BlockSize() const {return m_data.size() * sizeof(T);} unsigned int OptimalBlockSize() const {return BlockSize();} unsigned int OptimalDataAlignment() const {return sizeof(T);} @@ -135,10 +135,10 @@ template <class T> inline const T& STDMAX(const T& a, const T& b) // #define GETBYTE(x, y) (unsigned int)(((x)>>(8*(y)))&255) // #define GETBYTE(x, y) (((byte *)&(x))[y]) -CRYPTOPP_DLL unsigned int Parity(unsigned long); -CRYPTOPP_DLL unsigned int BytePrecision(unsigned long); -CRYPTOPP_DLL unsigned int BitPrecision(unsigned long); -CRYPTOPP_DLL unsigned long Crop(unsigned long, unsigned int size); +CRYPTOPP_DLL unsigned int CRYPTOPP_API Parity(unsigned long); +CRYPTOPP_DLL unsigned int CRYPTOPP_API BytePrecision(unsigned long); +CRYPTOPP_DLL unsigned int CRYPTOPP_API BitPrecision(unsigned long); +CRYPTOPP_DLL unsigned long CRYPTOPP_API Crop(unsigned long, unsigned int size); inline unsigned int BitsToBytes(unsigned int bitCount) { @@ -160,8 +160,8 @@ inline unsigned int BitsToDwords(unsigned int bitCount) return ((bitCount+2*WORD_BITS-1)/(2*WORD_BITS)); } -CRYPTOPP_DLL void xorbuf(byte *buf, const byte *mask, unsigned int count); -CRYPTOPP_DLL void xorbuf(byte *output, const byte *input, const byte *mask, unsigned int count); +CRYPTOPP_DLL void CRYPTOPP_API xorbuf(byte *buf, const byte *mask, unsigned int count); +CRYPTOPP_DLL void CRYPTOPP_API xorbuf(byte *output, const byte *input, const byte *mask, unsigned int count); template <class T> inline bool IsPowerOf2(T n) @@ -227,7 +227,7 @@ inline bool NativeByteOrderIs(ByteOrder order) return order == GetNativeByteOrder(); } -template <class T> // can't use <sstream> because GCC 2.95.2 doesn't have it +template <class T> std::string IntToString(T a, unsigned int base = 10) { if (a == 0) @@ -266,6 +266,20 @@ inline CipherDir GetCipherDir(const T &obj) void CallNewHandler(); +inline void IncrementCounterByOne(byte *inout, unsigned int s) +{ + for (int i=s-1, carry=1; i>=0 && carry; i--) + carry = !++inout[i]; +} + +inline void IncrementCounterByOne(byte *output, const byte *input, unsigned int s) +{ + int i, carry; + for (i=s-1, carry=1; i>=0 && carry; i--) + carry = !(output[i] = input[i]+1); + memcpy(output, input, i+1); +} + // ************** rotate functions *************** template <class T> inline T rotlFixed(T x, unsigned int y) @@ -24,10 +24,10 @@ public: typedef Integer Element; ModularArithmetic(const Integer &modulus = Integer::One()) - : modulus(modulus), result((word)0, modulus.reg.size()) {} + : m_modulus(modulus), m_result((word)0, modulus.reg.size()) {} ModularArithmetic(const ModularArithmetic &ma) - : modulus(ma.modulus), result((word)0, modulus.reg.size()) {} + : m_modulus(ma.m_modulus), m_result((word)0, m_modulus.reg.size()) {} ModularArithmetic(BufferedTransformation &bt); // construct from BER encoded parameters @@ -38,13 +38,13 @@ public: void DEREncodeElement(BufferedTransformation &out, const Element &a) const; void BERDecodeElement(BufferedTransformation &in, Element &a) const; - const Integer& GetModulus() const {return modulus;} - void SetModulus(const Integer &newModulus) {modulus = newModulus; result.reg.resize(modulus.reg.size());} + const Integer& GetModulus() const {return m_modulus;} + void SetModulus(const Integer &newModulus) {m_modulus = newModulus; m_result.reg.resize(m_modulus.reg.size());} virtual bool IsMontgomeryRepresentation() const {return false;} virtual Integer ConvertIn(const Integer &a) const - {return a%modulus;} + {return a%m_modulus;} virtual Integer ConvertOut(const Integer &a) const {return a;} @@ -74,16 +74,16 @@ public: {return Integer::One();} const Integer& Multiply(const Integer &a, const Integer &b) const - {return result1 = a*b%modulus;} + {return m_result1 = a*b%m_modulus;} const Integer& Square(const Integer &a) const - {return result1 = a.Squared()%modulus;} + {return m_result1 = a.Squared()%m_modulus;} bool IsUnit(const Integer &a) const - {return Integer::Gcd(a, modulus).IsUnit();} + {return Integer::Gcd(a, m_modulus).IsUnit();} const Integer& MultiplicativeInverse(const Integer &a) const - {return result1 = a.InverseMod(modulus);} + {return m_result1 = a.InverseMod(m_modulus);} const Integer& Divide(const Integer &a, const Integer &b) const {return Multiply(a, MultiplicativeInverse(b));} @@ -93,25 +93,25 @@ public: void SimultaneousExponentiate(Element *results, const Element &base, const Integer *exponents, unsigned int exponentsCount) const; unsigned int MaxElementBitLength() const - {return (modulus-1).BitCount();} + {return (m_modulus-1).BitCount();} unsigned int MaxElementByteLength() const - {return (modulus-1).ByteCount();} + {return (m_modulus-1).ByteCount();} Element RandomElement( RandomNumberGenerator &rng , const RandomizationParameter &ignore_for_now = 0 ) const // left RandomizationParameter arg as ref in case RandomizationParameter becomes a more complicated struct { - return Element( rng , Integer( (long) 0) , modulus - Integer( (long) 1 ) ) ; + return Element( rng , Integer( (long) 0) , m_modulus - Integer( (long) 1 ) ) ; } bool operator==(const ModularArithmetic &rhs) const - {return modulus == rhs.modulus;} + {return m_modulus == rhs.m_modulus;} static const RandomizationParameter DefaultRandomizationParameter ; protected: - Integer modulus; - mutable Integer result, result1; + Integer m_modulus; + mutable Integer m_result, m_result1; }; @@ -129,12 +129,12 @@ public: bool IsMontgomeryRepresentation() const {return true;} Integer ConvertIn(const Integer &a) const - {return (a<<(WORD_BITS*modulus.reg.size()))%modulus;} + {return (a<<(WORD_BITS*m_modulus.reg.size()))%m_modulus;} Integer ConvertOut(const Integer &a) const; const Integer& MultiplicativeIdentity() const - {return result1 = Integer::Power2(WORD_BITS*modulus.reg.size())%modulus;} + {return m_result1 = Integer::Power2(WORD_BITS*m_modulus.reg.size())%m_modulus;} const Integer& Multiply(const Integer &a, const Integer &b) const; @@ -149,8 +149,8 @@ public: {AbstractRing<Integer>::SimultaneousExponentiate(results, base, exponents, exponentsCount);} private: - Integer u; - mutable SecAlignedWordBlock workspace; + Integer m_u; + mutable SecAlignedWordBlock m_workspace; }; NAMESPACE_END @@ -50,20 +50,6 @@ void CTR_ModePolicy::SeekToIteration(lword iterationCount) } } -static inline void IncrementCounterByOne(byte *inout, unsigned int s) -{ - for (int i=s-1, carry=1; i>=0 && carry; i--) - carry = !++inout[i]; -} - -static inline void IncrementCounterByOne(byte *output, const byte *input, unsigned int s) -{ - int i, carry; - for (i=s-1, carry=1; i>=0 && carry; i--) - carry = !(output[i] = input[i]+1); - memcpy(output, input, i+1); -} - void CTR_ModePolicy::GetNextIV(byte *IV) { IncrementCounterByOne(IV, m_counterArray, BlockSize()); @@ -82,7 +82,7 @@ class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE CFB_ModePolicy : public ModePolicyCommonTe { public: IV_Requirement IVRequirement() const {return RANDOM_IV;} - static const char *StaticAlgorithmName() {return "CFB";} + static const char * CRYPTOPP_API StaticAlgorithmName() {return "CFB";} protected: unsigned int GetBytesPerIteration() const {return m_feedbackSize;} @@ -127,7 +127,7 @@ class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE OFB_ModePolicy : public ModePolicyCommonTe public: bool IsRandomAccess() const {return false;} IV_Requirement IVRequirement() const {return STRUCTURED_IV;} - static const char *StaticAlgorithmName() {return "OFB";} + static const char * CRYPTOPP_API StaticAlgorithmName() {return "OFB";} private: unsigned int GetBytesPerIteration() const {return BlockSize();} @@ -150,7 +150,7 @@ public: bool IsRandomAccess() const {return true;} IV_Requirement IVRequirement() const {return STRUCTURED_IV;} void GetNextIV(byte *IV); - static const char *StaticAlgorithmName() {return "Counter-BE";} + static const char * CRYPTOPP_API StaticAlgorithmName() {return "Counter-BE";} private: unsigned int GetBytesPerIteration() const {return BlockSize();} @@ -197,7 +197,7 @@ public: unsigned int OptimalBlockSize() const {return BlockSize() * m_cipher->OptimalNumberOfParallelBlocks();} void ProcessBlocks(byte *outString, const byte *inString, unsigned int numberOfBlocks) {m_cipher->ProcessAndXorMultipleBlocks(inString, NULL, outString, numberOfBlocks);} - static const char *StaticAlgorithmName() {return "ECB";} + static const char * CRYPTOPP_API StaticAlgorithmName() {return "ECB";} }; class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE CBC_ModeBase : public BlockOrientedCipherModeBase @@ -206,7 +206,7 @@ public: IV_Requirement IVRequirement() const {return UNPREDICTABLE_RANDOM_IV;} bool RequireAlignedInput() const {return false;} unsigned int MinLastBlockSize() const {return 0;} - static const char *StaticAlgorithmName() {return "CBC";} + static const char * CRYPTOPP_API StaticAlgorithmName() {return "CBC";} }; class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE CBC_Encryption : public CBC_ModeBase @@ -221,7 +221,7 @@ public: void SetStolenIV(byte *iv) {m_stolenIV = iv;} unsigned int MinLastBlockSize() const {return BlockSize()+1;} void ProcessLastBlock(byte *outString, const byte *inString, unsigned int length); - static const char *StaticAlgorithmName() {return "CBC/CTS";} + static const char * CRYPTOPP_API StaticAlgorithmName() {return "CBC/CTS";} protected: void UncheckedSetKey(const NameValuePairs ¶ms, const byte *key, unsigned int length, const byte *iv) @@ -280,7 +280,7 @@ public: this->SetKey(key, length, MakeParameters(Name::IV(), iv)(Name::FeedbackSize(), feedbackSize)); } - static std::string StaticAlgorithmName() + static std::string CRYPTOPP_API StaticAlgorithmName() {return CIPHER::StaticAlgorithmName() + "/" + BASE::StaticAlgorithmName();} }; @@ -9,41 +9,41 @@ NAMESPACE_BEGIN(CryptoPP) // obtain pointer to small prime table and get its size -CRYPTOPP_DLL const word16 * GetPrimeTable(unsigned int &size); +CRYPTOPP_DLL const word16 * CRYPTOPP_API GetPrimeTable(unsigned int &size); // ************ primality testing **************** // generate a provable prime -CRYPTOPP_DLL Integer MaurerProvablePrime(RandomNumberGenerator &rng, unsigned int bits); -CRYPTOPP_DLL Integer MihailescuProvablePrime(RandomNumberGenerator &rng, unsigned int bits); +CRYPTOPP_DLL Integer CRYPTOPP_API MaurerProvablePrime(RandomNumberGenerator &rng, unsigned int bits); +CRYPTOPP_DLL Integer CRYPTOPP_API MihailescuProvablePrime(RandomNumberGenerator &rng, unsigned int bits); -CRYPTOPP_DLL bool IsSmallPrime(const Integer &p); +CRYPTOPP_DLL bool CRYPTOPP_API IsSmallPrime(const Integer &p); // returns true if p is divisible by some prime less than bound // bound not be greater than the largest entry in the prime table -CRYPTOPP_DLL bool TrialDivision(const Integer &p, unsigned bound); +CRYPTOPP_DLL bool CRYPTOPP_API TrialDivision(const Integer &p, unsigned bound); // returns true if p is NOT divisible by small primes -CRYPTOPP_DLL bool SmallDivisorsTest(const Integer &p); +CRYPTOPP_DLL bool CRYPTOPP_API SmallDivisorsTest(const Integer &p); // These is no reason to use these two, use the ones below instead -CRYPTOPP_DLL bool IsFermatProbablePrime(const Integer &n, const Integer &b); -CRYPTOPP_DLL bool IsLucasProbablePrime(const Integer &n); +CRYPTOPP_DLL bool CRYPTOPP_API IsFermatProbablePrime(const Integer &n, const Integer &b); +CRYPTOPP_DLL bool CRYPTOPP_API IsLucasProbablePrime(const Integer &n); -CRYPTOPP_DLL bool IsStrongProbablePrime(const Integer &n, const Integer &b); -CRYPTOPP_DLL bool IsStrongLucasProbablePrime(const Integer &n); +CRYPTOPP_DLL bool CRYPTOPP_API IsStrongProbablePrime(const Integer &n, const Integer &b); +CRYPTOPP_DLL bool CRYPTOPP_API IsStrongLucasProbablePrime(const Integer &n); // Rabin-Miller primality test, i.e. repeating the strong probable prime test // for several rounds with random bases -CRYPTOPP_DLL bool RabinMillerTest(RandomNumberGenerator &rng, const Integer &w, unsigned int rounds); +CRYPTOPP_DLL bool CRYPTOPP_API RabinMillerTest(RandomNumberGenerator &rng, const Integer &w, unsigned int rounds); // primality test, used to generate primes -CRYPTOPP_DLL bool IsPrime(const Integer &p); +CRYPTOPP_DLL bool CRYPTOPP_API IsPrime(const Integer &p); // more reliable than IsPrime(), used to verify primes generated by others -CRYPTOPP_DLL bool VerifyPrime(RandomNumberGenerator &rng, const Integer &p, unsigned int level = 1); +CRYPTOPP_DLL bool CRYPTOPP_API VerifyPrime(RandomNumberGenerator &rng, const Integer &p, unsigned int level = 1); -class PrimeSelector +class CRYPTOPP_DLL PrimeSelector { public: const PrimeSelector *GetSelectorPointer() const {return this;} @@ -52,12 +52,12 @@ public: // use a fast sieve to find the first probable prime in {x | p<=x<=max and x%mod==equiv} // returns true iff successful, value of p is undefined if no such prime exists -CRYPTOPP_DLL bool FirstPrime(Integer &p, const Integer &max, const Integer &equiv, const Integer &mod, const PrimeSelector *pSelector); +CRYPTOPP_DLL bool CRYPTOPP_API FirstPrime(Integer &p, const Integer &max, const Integer &equiv, const Integer &mod, const PrimeSelector *pSelector); -CRYPTOPP_DLL unsigned int PrimeSearchInterval(const Integer &max); +CRYPTOPP_DLL unsigned int CRYPTOPP_API PrimeSearchInterval(const Integer &max); CRYPTOPP_DLL AlgorithmParameters<AlgorithmParameters<AlgorithmParameters<NullNameValuePairs, Integer::RandomNumberType>, Integer>, Integer> - MakeParametersForTwoPrimesOfEqualSize(unsigned int productBitLength); + CRYPTOPP_API MakeParametersForTwoPrimesOfEqualSize(unsigned int productBitLength); // ********** other number theoretic functions ************ @@ -71,39 +71,39 @@ inline Integer EuclideanMultiplicativeInverse(const Integer &a, const Integer &b {return a.InverseMod(b);} // use Chinese Remainder Theorem to calculate x given x mod p and x mod q -CRYPTOPP_DLL Integer CRT(const Integer &xp, const Integer &p, const Integer &xq, const Integer &q); +CRYPTOPP_DLL Integer CRYPTOPP_API CRT(const Integer &xp, const Integer &p, const Integer &xq, const Integer &q); // use this one if u = inverse of p mod q has been precalculated -CRYPTOPP_DLL Integer CRT(const Integer &xp, const Integer &p, const Integer &xq, const Integer &q, const Integer &u); +CRYPTOPP_DLL Integer CRYPTOPP_API CRT(const Integer &xp, const Integer &p, const Integer &xq, const Integer &q, const Integer &u); // if b is prime, then Jacobi(a, b) returns 0 if a%b==0, 1 if a is quadratic residue mod b, -1 otherwise // check a number theory book for what Jacobi symbol means when b is not prime -CRYPTOPP_DLL int Jacobi(const Integer &a, const Integer &b); +CRYPTOPP_DLL int CRYPTOPP_API Jacobi(const Integer &a, const Integer &b); // calculates the Lucas function V_e(p, 1) mod n -CRYPTOPP_DLL Integer Lucas(const Integer &e, const Integer &p, const Integer &n); +CRYPTOPP_DLL Integer CRYPTOPP_API Lucas(const Integer &e, const Integer &p, const Integer &n); // calculates x such that m==Lucas(e, x, p*q), p q primes -CRYPTOPP_DLL Integer InverseLucas(const Integer &e, const Integer &m, const Integer &p, const Integer &q); +CRYPTOPP_DLL Integer CRYPTOPP_API InverseLucas(const Integer &e, const Integer &m, const Integer &p, const Integer &q); // use this one if u=inverse of p mod q has been precalculated -CRYPTOPP_DLL Integer InverseLucas(const Integer &e, const Integer &m, const Integer &p, const Integer &q, const Integer &u); +CRYPTOPP_DLL Integer CRYPTOPP_API InverseLucas(const Integer &e, const Integer &m, const Integer &p, const Integer &q, const Integer &u); inline Integer ModularExponentiation(const Integer &a, const Integer &e, const Integer &m) {return a_exp_b_mod_c(a, e, m);} // returns x such that x*x%p == a, p prime -CRYPTOPP_DLL Integer ModularSquareRoot(const Integer &a, const Integer &p); +CRYPTOPP_DLL Integer CRYPTOPP_API ModularSquareRoot(const Integer &a, const Integer &p); // returns x such that a==ModularExponentiation(x, e, p*q), p q primes, // and e relatively prime to (p-1)*(q-1) -CRYPTOPP_DLL Integer ModularRoot(const Integer &a, const Integer &e, const Integer &p, const Integer &q); +CRYPTOPP_DLL Integer CRYPTOPP_API ModularRoot(const Integer &a, const Integer &e, const Integer &p, const Integer &q); // use this one if dp=d%(p-1), dq=d%(q-1), (d is inverse of e mod (p-1)*(q-1)) // and u=inverse of p mod q have been precalculated -CRYPTOPP_DLL Integer ModularRoot(const Integer &a, const Integer &dp, const Integer &dq, const Integer &p, const Integer &q, const Integer &u); +CRYPTOPP_DLL Integer CRYPTOPP_API ModularRoot(const Integer &a, const Integer &dp, const Integer &dq, const Integer &p, const Integer &q, const Integer &u); // find r1 and r2 such that ax^2 + bx + c == 0 (mod p) for x in {r1, r2}, p prime // returns true if solutions exist -CRYPTOPP_DLL bool SolveModularQuadraticEquation(Integer &r1, Integer &r2, const Integer &a, const Integer &b, const Integer &c, const Integer &p); +CRYPTOPP_DLL bool CRYPTOPP_API SolveModularQuadraticEquation(Integer &r1, Integer &r2, const Integer &a, const Integer &b, const Integer &c, const Integer &p); // returns log base 2 of estimated number of operations to calculate discrete log or factor a number -CRYPTOPP_DLL unsigned int DiscreteLogWorkFactor(unsigned int bitlength); -CRYPTOPP_DLL unsigned int FactoringWorkFactor(unsigned int bitlength); +CRYPTOPP_DLL unsigned int CRYPTOPP_API DiscreteLogWorkFactor(unsigned int bitlength); +CRYPTOPP_DLL unsigned int CRYPTOPP_API FactoringWorkFactor(unsigned int bitlength); // ******************************************************** @@ -26,7 +26,7 @@ template <class H, class MGF=P1363_MGF1> class OAEP : public OAEP_Base, public EncryptionStandard { public: - static std::string StaticAlgorithmName() {return std::string("OAEP-") + MGF::StaticAlgorithmName() + "(" + H::StaticAlgorithmName() + ")";} + static std::string CRYPTOPP_API StaticAlgorithmName() {return std::string("OAEP-") + MGF::StaticAlgorithmName() + "(" + H::StaticAlgorithmName() + ")";} typedef OAEP<H, MGF> EncryptionMessageEncodingMethod; protected: @@ -78,7 +78,7 @@ protected: #endif -CRYPTOPP_DLL void OS_GenerateRandomBlock(bool blocking, byte *output, unsigned int size); +CRYPTOPP_DLL void CRYPTOPP_API OS_GenerateRandomBlock(bool blocking, byte *output, unsigned int size); //! Automaticly Seeded Randomness Pool /*! This class seeds itself using an operating system provided RNG. */ @@ -101,7 +101,7 @@ public: {Reseed(blocking);} void Reseed(bool blocking = false); // exposed for testing - void Reseed(const byte *key, unsigned int keylength, const byte *seed, unsigned long timeVector); + void Reseed(const byte *key, unsigned int keylength, const byte *seed, const byte *timeVector); byte GenerateByte(); @@ -115,7 +115,7 @@ private: CRYPTOPP_DLL_TEMPLATE_CLASS AutoSeededX917RNG<DES_EDE3>; template <class BLOCK_CIPHER> -void AutoSeededX917RNG<BLOCK_CIPHER>::Reseed(const byte *key, unsigned int keylength, const byte *seed, unsigned long timeVector) +void AutoSeededX917RNG<BLOCK_CIPHER>::Reseed(const byte *key, unsigned int keylength, const byte *seed, const byte *timeVector) { m_rng.reset(new X917RNG(new typename BLOCK_CIPHER::Encryption(key, keylength), seed, timeVector)); @@ -138,7 +138,7 @@ void AutoSeededX917RNG<BLOCK_CIPHER>::Reseed(bool blocking) } // check that seed and key don't have same value while (memcmp(key, seed, STDMIN((unsigned int)BLOCK_CIPHER::BLOCKSIZE, (unsigned int)BLOCK_CIPHER::DEFAULT_KEYLENGTH)) == 0); - Reseed(key, BLOCK_CIPHER::DEFAULT_KEYLENGTH, seed, 0); + Reseed(key, BLOCK_CIPHER::DEFAULT_KEYLENGTH, seed, NULL); } template <class BLOCK_CIPHER> diff --git a/pkcspad.cpp b/pkcspad.cpp index a51858cc..78232fdb 100644 --- a/pkcspad.cpp +++ b/pkcspad.cpp @@ -88,9 +88,7 @@ void PKCS1v15_SignatureMessageEncodingMethod::ComputeMessageRepresentative(Rando HashTransformation &hash, HashIdentifier hashIdentifier, bool messageEmpty, byte *representative, unsigned int representativeBitLength) const { - unsigned int digestSize = hash.DigestSize(); - if (digestSize + hashIdentifier.second + 10 > representativeBitLength/8) - throw PK_Signer::KeyTooShort(); + assert(representativeBitLength >= MinRepresentativeBitLength(hashIdentifier.second, hash.DigestSize())); unsigned int pkcsBlockLen = representativeBitLength; // convert from bit length to byte length @@ -103,6 +101,7 @@ void PKCS1v15_SignatureMessageEncodingMethod::ComputeMessageRepresentative(Rando representative[0] = 1; // block type 1 + unsigned int digestSize = hash.DigestSize(); byte *pPadding = representative + 1; byte *pDigest = representative + pkcsBlockLen - digestSize; byte *pHashId = pDigest - hashIdentifier.second; @@ -30,18 +30,20 @@ public: // PKCS_DigestDecoration can be instantiated with the following // classes as specified in PKCS#1 v2.0 and P1363a -class SHA; +class SHA1; class MD2; class MD5; class RIPEMD160; class Tiger; +class SHA224; class SHA256; class SHA384; class SHA512; // end of list #ifdef CRYPTOPP_IS_DLL -CRYPTOPP_DLL_TEMPLATE_CLASS PKCS_DigestDecoration<SHA>; +CRYPTOPP_DLL_TEMPLATE_CLASS PKCS_DigestDecoration<SHA1>; +CRYPTOPP_DLL_TEMPLATE_CLASS PKCS_DigestDecoration<SHA224>; CRYPTOPP_DLL_TEMPLATE_CLASS PKCS_DigestDecoration<SHA256>; CRYPTOPP_DLL_TEMPLATE_CLASS PKCS_DigestDecoration<SHA384>; CRYPTOPP_DLL_TEMPLATE_CLASS PKCS_DigestDecoration<SHA512>; @@ -51,7 +53,10 @@ CRYPTOPP_DLL_TEMPLATE_CLASS PKCS_DigestDecoration<SHA512>; class CRYPTOPP_DLL PKCS1v15_SignatureMessageEncodingMethod : public PK_DeterministicSignatureMessageEncodingMethod { public: - static const char * StaticAlgorithmName() {return "EMSA-PKCS1-v1_5";} + static const char * CRYPTOPP_API StaticAlgorithmName() {return "EMSA-PKCS1-v1_5";} + + unsigned int MinRepresentativeBitLength(unsigned int hashIdentifierSize, unsigned int digestSize) const + {return 8 * (digestSize + hashIdentifierSize + 10);} void ComputeMessageRepresentative(RandomNumberGenerator &rng, const byte *recoverableMessage, unsigned int recoverableMessageLength, diff --git a/polynomi.cpp b/polynomi.cpp index be39bce4..cca20732 100644 --- a/polynomi.cpp +++ b/polynomi.cpp @@ -7,7 +7,7 @@ #include "polynomi.h" #include "secblock.h" -#include <strstream> // can't use <sstream> because GCC 2.95.2 doesn't have it +#include <sstream> #include <iostream> NAMESPACE_BEGIN(CryptoPP) @@ -23,7 +23,7 @@ void PolynomialOver<T>::Randomize(RandomNumberGenerator &rng, const Randomizatio template <class T> void PolynomialOver<T>::FromStr(const char *str, const Ring &ring) { - std::istrstream in((char *)str); + std::istringstream in((char *)str); bool positive = true; CoefficientType coef; unsigned int power; @@ -12,14 +12,17 @@ template<> const byte EMSA2HashId<Whirlpool>::id = 0x37; #ifndef CRYPTOPP_IMPORTS +unsigned int PSSR_MEM_Base::MinRepresentativeBitLength(unsigned int hashIdentifierLength, unsigned int digestLength) const +{ + unsigned int saltLen = SaltLen(digestLength); + unsigned int minPadLen = MinPadLen(digestLength); + return 9 + 8*(minPadLen + saltLen + digestLength + hashIdentifierLength); +} + unsigned int PSSR_MEM_Base::MaxRecoverableLength(unsigned int representativeBitLength, unsigned int hashIdentifierLength, unsigned int digestLength) const { if (AllowRecovery()) - { - unsigned int saltLen = SaltLen(digestLength); - unsigned int minPadLen = MinPadLen(digestLength); - return SaturatingSubtract(representativeBitLength, 8*(minPadLen + saltLen + digestLength + hashIdentifierLength) + 9) / 8; - } + return SaturatingSubtract(representativeBitLength, MinRepresentativeBitLength(hashIdentifierLength, digestLength)) / 8; return 0; } @@ -43,6 +46,8 @@ void PSSR_MEM_Base::ComputeMessageRepresentative(RandomNumberGenerator &rng, HashTransformation &hash, HashIdentifier hashIdentifier, bool messageEmpty, byte *representative, unsigned int representativeBitLength) const { + assert(representativeBitLength >= MinRepresentativeBitLength(hashIdentifier.second, hash.DigestSize())); + const unsigned int u = hashIdentifier.second + 1; const unsigned int representativeByteLength = BitsToBytes(representativeBitLength); const unsigned int digestSize = hash.DigestSize(); @@ -80,6 +85,8 @@ DecodingResult PSSR_MEM_Base::RecoverMessageFromRepresentative( byte *representative, unsigned int representativeBitLength, byte *recoverableMessage) const { + assert(representativeBitLength >= MinRepresentativeBitLength(hashIdentifier.second, hash.DigestSize())); + const unsigned int u = hashIdentifier.second + 1; const unsigned int representativeByteLength = BitsToBytes(representativeBitLength); const unsigned int digestSize = hash.DigestSize(); @@ -103,13 +110,18 @@ DecodingResult PSSR_MEM_Base::RecoverMessageFromRepresentative( // extract salt and recoverableMessage from DB = 00 ... || 01 || M || salt byte *salt = representative + representativeByteLength - u - digestSize - saltSize; byte *M = std::find_if(representative, salt-1, std::bind2nd(std::not_equal_to<byte>(), 0)); - if (*M == 0x01 && (unsigned int)(M - representative - (representativeBitLength % 8 != 0)) >= MinPadLen(digestSize)) + recoverableMessageLength = salt-M-1; + if (*M == 0x01 + && (unsigned int)(M - representative - (representativeBitLength % 8 != 0)) >= MinPadLen(digestSize) + && recoverableMessageLength <= MaxRecoverableLength(representativeBitLength, hashIdentifier.second, digestSize)) { - recoverableMessageLength = salt-M-1; memcpy(recoverableMessage, M+1, recoverableMessageLength); } else + { + recoverableMessageLength = 0; valid = false; + } // verify H = hash of M' byte c[8]; @@ -2,7 +2,7 @@ #define CRYPTOPP_PSSR_H #include "pubkey.h" -#include <functional> +#include "emsa2.h" #ifdef CRYPTOPP_IS_DLL #include "sha.h" @@ -18,6 +18,7 @@ class CRYPTOPP_DLL PSSR_MEM_Base : public PK_RecoverableSignatureMessageEncoding virtual const MaskGeneratingFunction & GetMGF() const =0; public: + unsigned int MinRepresentativeBitLength(unsigned int hashIdentifierLength, unsigned int digestLength) const; unsigned int MaxRecoverableLength(unsigned int representativeBitLength, unsigned int hashIdentifierLength, unsigned int digestLength) const; bool IsProbabilistic() const; bool AllowNonrecoverablePart() const; @@ -32,45 +33,6 @@ public: byte *recoverableMessage) const; }; -template <class H> class EMSA2HashId -{ -public: - static const byte id; -}; - -// EMSA2HashId can be instantiated with the following classes. -class SHA; -class RIPEMD160; -class RIPEMD128; -class SHA256; -class SHA384; -class SHA512; -class Whirlpool; -// end of list - -#ifdef CRYPTOPP_IS_DLL -CRYPTOPP_DLL_TEMPLATE_CLASS EMSA2HashId<SHA>; -CRYPTOPP_DLL_TEMPLATE_CLASS EMSA2HashId<SHA256>; -CRYPTOPP_DLL_TEMPLATE_CLASS EMSA2HashId<SHA384>; -CRYPTOPP_DLL_TEMPLATE_CLASS EMSA2HashId<SHA512>; -#endif - -template <class BASE> -class EMSA2HashIdLookup : public BASE -{ -public: - struct HashIdentifierLookup - { - template <class H> struct HashIdentifierLookup2 - { - static HashIdentifier Lookup() - { - return HashIdentifier(&EMSA2HashId<H>::id, 1); - } - }; - }; -}; - template <bool USE_HASH_ID> class PSSR_MEM_BaseWithHashId; template<> class PSSR_MEM_BaseWithHashId<true> : public EMSA2HashIdLookup<PSSR_MEM_Base> {}; template<> class PSSR_MEM_BaseWithHashId<false> : public PSSR_MEM_Base {}; @@ -84,7 +46,7 @@ class PSSR_MEM : public PSSR_MEM_BaseWithHashId<USE_HASH_ID> virtual const MaskGeneratingFunction & GetMGF() const {static MGF mgf; return mgf;} public: - static std::string StaticAlgorithmName() {return std::string(ALLOW_RECOVERY ? "PSSR-" : "PSS-") + MGF::StaticAlgorithmName();} + static std::string CRYPTOPP_API StaticAlgorithmName() {return std::string(ALLOW_RECOVERY ? "PSSR-" : "PSS-") + MGF::StaticAlgorithmName();} }; //! <a href="http://www.weidai.com/scan-mirror/sig.html#sem_PSSR-MGF1">PSSR-MGF1</a> @@ -44,8 +44,13 @@ bool PK_RecoverableSignatureMessageEncodingMethod::VerifyMessageRepresentative( void TF_SignerBase::InputRecoverableMessage(PK_MessageAccumulator &messageAccumulator, const byte *recoverableMessage, unsigned int recoverableMessageLength) const { PK_MessageAccumulatorBase &ma = static_cast<PK_MessageAccumulatorBase &>(messageAccumulator); - const MessageEncodingInterface &mei = GetMessageEncodingInterface(); - unsigned int maxRecoverableLength = mei.MaxRecoverableLength(MessageRepresentativeBitLength(), GetHashIdentifier().second, ma.AccessHash().DigestSize()); + HashIdentifier id = GetHashIdentifier(); + const MessageEncodingInterface &encoding = GetMessageEncodingInterface(); + + if (MessageRepresentativeBitLength() < encoding.MinRepresentativeBitLength(id.second, ma.AccessHash().DigestSize())) + throw PK_SignatureScheme::KeyTooShort(); + + unsigned int maxRecoverableLength = encoding.MaxRecoverableLength(MessageRepresentativeBitLength(), GetHashIdentifier().second, ma.AccessHash().DigestSize()); if (maxRecoverableLength == 0) {throw NotImplemented("TF_SignerBase: this algorithm does not support messsage recovery or the key is too short");} @@ -53,7 +58,7 @@ void TF_SignerBase::InputRecoverableMessage(PK_MessageAccumulator &messageAccumu throw InvalidArgument("TF_SignerBase: the recoverable message part is too long for the given key and algorithm"); ma.m_recoverableMessage.Assign(recoverableMessage, recoverableMessageLength); - mei.ProcessRecoverableMessage( + encoding.ProcessRecoverableMessage( ma.AccessHash(), recoverableMessage, recoverableMessageLength, NULL, 0, ma.m_semisignature); @@ -62,10 +67,16 @@ void TF_SignerBase::InputRecoverableMessage(PK_MessageAccumulator &messageAccumu unsigned int TF_SignerBase::SignAndRestart(RandomNumberGenerator &rng, PK_MessageAccumulator &messageAccumulator, byte *signature, bool restart) const { PK_MessageAccumulatorBase &ma = static_cast<PK_MessageAccumulatorBase &>(messageAccumulator); + HashIdentifier id = GetHashIdentifier(); + const MessageEncodingInterface &encoding = GetMessageEncodingInterface(); + + if (MessageRepresentativeBitLength() < encoding.MinRepresentativeBitLength(id.second, ma.AccessHash().DigestSize())) + throw PK_SignatureScheme::KeyTooShort(); + SecByteBlock representative(MessageRepresentativeLength()); - GetMessageEncodingInterface().ComputeMessageRepresentative(rng, + encoding.ComputeMessageRepresentative(rng, ma.m_recoverableMessage, ma.m_recoverableMessage.size(), - ma.AccessHash(), GetHashIdentifier(), ma.m_empty, + ma.AccessHash(), id, ma.m_empty, representative, MessageRepresentativeBitLength()); ma.m_empty = true; @@ -78,6 +89,12 @@ unsigned int TF_SignerBase::SignAndRestart(RandomNumberGenerator &rng, PK_Messag void TF_VerifierBase::InputSignature(PK_MessageAccumulator &messageAccumulator, const byte *signature, unsigned int signatureLength) const { PK_MessageAccumulatorBase &ma = static_cast<PK_MessageAccumulatorBase &>(messageAccumulator); + HashIdentifier id = GetHashIdentifier(); + const MessageEncodingInterface &encoding = GetMessageEncodingInterface(); + + if (MessageRepresentativeBitLength() < encoding.MinRepresentativeBitLength(id.second, ma.AccessHash().DigestSize())) + throw PK_SignatureScheme::KeyTooShort(); + ma.m_representative.New(MessageRepresentativeLength()); Integer x = GetTrapdoorFunctionInterface().ApplyFunction(Integer(signature, signatureLength)); if (x.BitCount() > MessageRepresentativeBitLength()) @@ -88,8 +105,14 @@ void TF_VerifierBase::InputSignature(PK_MessageAccumulator &messageAccumulator, bool TF_VerifierBase::VerifyAndRestart(PK_MessageAccumulator &messageAccumulator) const { PK_MessageAccumulatorBase &ma = static_cast<PK_MessageAccumulatorBase &>(messageAccumulator); - bool result = GetMessageEncodingInterface().VerifyMessageRepresentative( - ma.AccessHash(), GetHashIdentifier(), ma.m_empty, ma.m_representative, MessageRepresentativeBitLength()); + HashIdentifier id = GetHashIdentifier(); + const MessageEncodingInterface &encoding = GetMessageEncodingInterface(); + + if (MessageRepresentativeBitLength() < encoding.MinRepresentativeBitLength(id.second, ma.AccessHash().DigestSize())) + throw PK_SignatureScheme::KeyTooShort(); + + bool result = encoding.VerifyMessageRepresentative( + ma.AccessHash(), id, ma.m_empty, ma.m_representative, MessageRepresentativeBitLength()); ma.m_empty = true; return result; } @@ -97,8 +120,14 @@ bool TF_VerifierBase::VerifyAndRestart(PK_MessageAccumulator &messageAccumulator DecodingResult TF_VerifierBase::RecoverAndRestart(byte *recoveredMessage, PK_MessageAccumulator &messageAccumulator) const { PK_MessageAccumulatorBase &ma = static_cast<PK_MessageAccumulatorBase &>(messageAccumulator); - DecodingResult result = GetMessageEncodingInterface().RecoverMessageFromRepresentative( - ma.AccessHash(), GetHashIdentifier(), ma.m_empty, ma.m_representative, MessageRepresentativeBitLength(), recoveredMessage); + HashIdentifier id = GetHashIdentifier(); + const MessageEncodingInterface &encoding = GetMessageEncodingInterface(); + + if (MessageRepresentativeBitLength() < encoding.MinRepresentativeBitLength(id.second, ma.AccessHash().DigestSize())) + throw PK_SignatureScheme::KeyTooShort(); + + DecodingResult result = encoding.RecoverMessageFromRepresentative( + ma.AccessHash(), id, ma.m_empty, ma.m_representative, MessageRepresentativeBitLength(), recoveredMessage); ma.m_empty = true; return result; } @@ -186,6 +186,8 @@ class CRYPTOPP_NO_VTABLE PK_SignatureMessageEncodingMethod public: virtual ~PK_SignatureMessageEncodingMethod() {} + virtual unsigned int MinRepresentativeBitLength(unsigned int hashIdentifierLength, unsigned int digestLength) const + {return 0;} virtual unsigned int MaxRecoverableLength(unsigned int representativeBitLength, unsigned int hashIdentifierLength, unsigned int digestLength) const {return 0;} @@ -236,7 +238,7 @@ public: { template <class H> struct HashIdentifierLookup2 { - static HashIdentifier Lookup() + static HashIdentifier CRYPTOPP_API Lookup() { return HashIdentifier(NULL, 0); } @@ -367,31 +369,12 @@ struct TF_SignatureSchemeOptions : public TF_CryptoSchemeOptions<T1, T2, T3> }; //! _ -template <class KEYS> -class CRYPTOPP_NO_VTABLE PublicKeyCopier -{ -public: - typedef typename KEYS::PublicKey KeyClass; - virtual void CopyKeyInto(typename KEYS::PublicKey &key) const =0; -}; - -//! _ -template <class KEYS> -class CRYPTOPP_NO_VTABLE PrivateKeyCopier -{ -public: - typedef typename KEYS::PrivateKey KeyClass; - virtual void CopyKeyInto(typename KEYS::PublicKey &key) const =0; - virtual void CopyKeyInto(typename KEYS::PrivateKey &key) const =0; -}; - -//! _ -template <class BASE, class SCHEME_OPTIONS, class KEY> +template <class BASE, class SCHEME_OPTIONS, class KEY_CLASS> class CRYPTOPP_NO_VTABLE TF_ObjectImplBase : public AlgorithmImpl<BASE, typename SCHEME_OPTIONS::AlgorithmInfo> { public: typedef SCHEME_OPTIONS SchemeOptions; - typedef KEY KeyClass; + typedef KEY_CLASS KeyClass; PublicKey & AccessPublicKey() {return AccessKey();} const PublicKey & GetPublicKey() const {return GetKey();} @@ -450,43 +433,40 @@ private: }; //! _ -template <class BASE, class SCHEME_OPTIONS, class KEY_COPIER> -class CRYPTOPP_NO_VTABLE TF_ObjectImpl : public TF_ObjectImplBase<TwoBases<BASE, KEY_COPIER>, SCHEME_OPTIONS, typename KEY_COPIER::KeyClass> +template <class BASE, class SCHEME_OPTIONS, class KEY_CLASS> +class CRYPTOPP_NO_VTABLE TF_ObjectImpl : public TF_ObjectImplBase<BASE, SCHEME_OPTIONS, KEY_CLASS> { public: - typedef typename KEY_COPIER::KeyClass KeyClass; + typedef KEY_CLASS KeyClass; const KeyClass & GetKey() const {return m_trapdoorFunction;} KeyClass & AccessKey() {return m_trapdoorFunction;} - void CopyKeyInto(typename SCHEME_OPTIONS::PrivateKey &key) const {key = GetKey();} - void CopyKeyInto(typename SCHEME_OPTIONS::PublicKey &key) const {key = GetKey();} - private: KeyClass m_trapdoorFunction; }; //! _ template <class SCHEME_OPTIONS> -class TF_DecryptorImpl : public TF_ObjectImpl<TF_DecryptorBase, SCHEME_OPTIONS, PrivateKeyCopier<typename SCHEME_OPTIONS::Keys> > +class TF_DecryptorImpl : public TF_ObjectImpl<TF_DecryptorBase, SCHEME_OPTIONS, typename SCHEME_OPTIONS::PrivateKey> { }; //! _ template <class SCHEME_OPTIONS> -class TF_EncryptorImpl : public TF_ObjectImpl<TF_EncryptorBase, SCHEME_OPTIONS, PublicKeyCopier<typename SCHEME_OPTIONS::Keys> > +class TF_EncryptorImpl : public TF_ObjectImpl<TF_EncryptorBase, SCHEME_OPTIONS, typename SCHEME_OPTIONS::PublicKey> { }; //! _ template <class SCHEME_OPTIONS> -class TF_SignerImpl : public TF_ObjectImpl<TF_SignerBase, SCHEME_OPTIONS, PrivateKeyCopier<typename SCHEME_OPTIONS::Keys> > +class TF_SignerImpl : public TF_ObjectImpl<TF_SignerBase, SCHEME_OPTIONS, typename SCHEME_OPTIONS::PrivateKey> { }; //! _ template <class SCHEME_OPTIONS> -class TF_VerifierImpl : public TF_ObjectImpl<TF_VerifierBase, SCHEME_OPTIONS, PublicKeyCopier<typename SCHEME_OPTIONS::Keys> > +class TF_VerifierImpl : public TF_ObjectImpl<TF_VerifierBase, SCHEME_OPTIONS, typename SCHEME_OPTIONS::PublicKey> { }; @@ -500,13 +480,13 @@ public: virtual void GenerateAndMask(HashTransformation &hash, byte *output, unsigned int outputLength, const byte *input, unsigned int inputLength, bool mask = true) const =0; }; -CRYPTOPP_DLL void P1363_MGF1KDF2_Common(HashTransformation &hash, byte *output, unsigned int outputLength, const byte *input, unsigned int inputLength, const byte *derivationParams, unsigned int derivationParamsLength, bool mask, unsigned int counterStart); +CRYPTOPP_DLL void CRYPTOPP_API P1363_MGF1KDF2_Common(HashTransformation &hash, byte *output, unsigned int outputLength, const byte *input, unsigned int inputLength, const byte *derivationParams, unsigned int derivationParamsLength, bool mask, unsigned int counterStart); //! _ class P1363_MGF1 : public MaskGeneratingFunction { public: - static const char * StaticAlgorithmName() {return "MGF1";} + static const char * CRYPTOPP_API StaticAlgorithmName() {return "MGF1";} void GenerateAndMask(HashTransformation &hash, byte *output, unsigned int outputLength, const byte *input, unsigned int inputLength, bool mask = true) const { P1363_MGF1KDF2_Common(hash, output, outputLength, input, inputLength, NULL, 0, mask, 0); @@ -520,7 +500,7 @@ template <class H> class P1363_KDF2 { public: - static void DeriveKey(byte *output, unsigned int outputLength, const byte *input, unsigned int inputLength, const byte *derivationParams, unsigned int derivationParamsLength) + static void CRYPTOPP_API DeriveKey(byte *output, unsigned int outputLength, const byte *input, unsigned int inputLength, const byte *derivationParams, unsigned int derivationParamsLength) { H h; P1363_MGF1KDF2_Common(h, output, outputLength, input, inputLength, derivationParams, derivationParamsLength, false, 1); @@ -1338,28 +1318,8 @@ protected: }; //! _ -template <class BASE, class SCHEME_OPTIONS> -class CRYPTOPP_NO_VTABLE DL_PublicObjectImpl : public DL_ObjectImpl<BASE, SCHEME_OPTIONS, typename SCHEME_OPTIONS::PublicKey>, public PublicKeyCopier<SCHEME_OPTIONS> -{ -public: - void CopyKeyInto(typename SCHEME_OPTIONS::PublicKey &key) const - {key = this->GetKey();} -}; - -//! _ -template <class BASE, class SCHEME_OPTIONS> -class CRYPTOPP_NO_VTABLE DL_PrivateObjectImpl : public DL_ObjectImpl<BASE, SCHEME_OPTIONS, typename SCHEME_OPTIONS::PrivateKey>, public PrivateKeyCopier<SCHEME_OPTIONS> -{ -public: - void CopyKeyInto(typename SCHEME_OPTIONS::PublicKey &key) const - {this->GetKey().MakePublicKey(key);} - void CopyKeyInto(typename SCHEME_OPTIONS::PrivateKey &key) const - {key = this->GetKey();} -}; - -//! _ template <class SCHEME_OPTIONS> -class DL_SignerImpl : public DL_PrivateObjectImpl<DL_SignerBase<typename SCHEME_OPTIONS::Element>, SCHEME_OPTIONS> +class DL_SignerImpl : public DL_ObjectImpl<DL_SignerBase<typename SCHEME_OPTIONS::Element>, SCHEME_OPTIONS, typename SCHEME_OPTIONS::PrivateKey> { public: PK_MessageAccumulator * NewSignatureAccumulator(RandomNumberGenerator &rng) const @@ -1372,7 +1332,7 @@ public: //! _ template <class SCHEME_OPTIONS> -class DL_VerifierImpl : public DL_PublicObjectImpl<DL_VerifierBase<typename SCHEME_OPTIONS::Element>, SCHEME_OPTIONS> +class DL_VerifierImpl : public DL_ObjectImpl<DL_VerifierBase<typename SCHEME_OPTIONS::Element>, SCHEME_OPTIONS, typename SCHEME_OPTIONS::PublicKey> { public: PK_MessageAccumulator * NewVerificationAccumulator() const @@ -1383,13 +1343,13 @@ public: //! _ template <class SCHEME_OPTIONS> -class DL_EncryptorImpl : public DL_PublicObjectImpl<DL_EncryptorBase<typename SCHEME_OPTIONS::Element>, SCHEME_OPTIONS> +class DL_EncryptorImpl : public DL_ObjectImpl<DL_EncryptorBase<typename SCHEME_OPTIONS::Element>, SCHEME_OPTIONS, typename SCHEME_OPTIONS::PublicKey> { }; //! _ template <class SCHEME_OPTIONS> -class DL_DecryptorImpl : public DL_PrivateObjectImpl<DL_DecryptorBase<typename SCHEME_OPTIONS::Element>, SCHEME_OPTIONS> +class DL_DecryptorImpl : public DL_ObjectImpl<DL_DecryptorBase<typename SCHEME_OPTIONS::Element>, SCHEME_OPTIONS, typename SCHEME_OPTIONS::PrivateKey> { }; @@ -1460,7 +1420,7 @@ class DL_KeyAgreementAlgorithm_DH : public DL_KeyAgreementAlgorithm<ELEMENT> public: typedef ELEMENT Element; - static const char *StaticAlgorithmName() + static const char * CRYPTOPP_API StaticAlgorithmName() {return COFACTOR_OPTION::ToEnum() == INCOMPATIBLE_COFACTOR_MULTIPLICTION ? "DHC" : "DH";} Element AgreeWithEphemeralPrivateKey(const DL_GroupParameters<Element> ¶ms, const DL_FixedBasePrecomputation<Element> &publicPrecomputation, const Integer &privateExponent) const @@ -1514,20 +1474,17 @@ class CRYPTOPP_NO_VTABLE PK_FinalTemplate : public BASE public: PK_FinalTemplate() {} - PK_FinalTemplate(const Integer &v1) - {this->AccessKey().Initialize(v1);} + PK_FinalTemplate(const CryptoMaterial &key) + {this->AccessKey().AssignFrom(key);} - PK_FinalTemplate(const typename BASE::KeyClass &key) {this->AccessKey().operator=(key);} + PK_FinalTemplate(BufferedTransformation &bt) + {this->AccessKey().BERDecode(bt);} - template <class T> - PK_FinalTemplate(const PublicKeyCopier<T> &key) - {key.CopyKeyInto(this->AccessKey());} + PK_FinalTemplate(const AsymmetricAlgorithm &algorithm) + {this->AccessKey().AssignFrom(algorithm.GetMaterial());} - template <class T> - PK_FinalTemplate(const PrivateKeyCopier<T> &key) - {key.CopyKeyInto(this->AccessKey());} - - PK_FinalTemplate(BufferedTransformation &bt) {this->AccessKey().BERDecode(bt);} + PK_FinalTemplate(const Integer &v1) + {this->AccessKey().Initialize(v1);} #if (defined(_MSC_VER) && _MSC_VER < 1300) @@ -1640,7 +1597,7 @@ public: typedef STANDARD Standard; typedef TF_CryptoSchemeOptions<ALG_INFO, KEYS, MessageEncodingMethod> SchemeOptions; - static std::string StaticAlgorithmName() {return KEYS::StaticAlgorithmName() + "/" + MessageEncodingMethod::StaticAlgorithmName();} + static std::string CRYPTOPP_API StaticAlgorithmName() {return std::string(KEYS::StaticAlgorithmName()) + "/" + MessageEncodingMethod::StaticAlgorithmName();} //! implements PK_Decryptor interface typedef PK_FinalTemplate<TF_DecryptorImpl<SchemeOptions> > Decryptor; @@ -1661,7 +1618,7 @@ public: typedef typename Standard::SignatureMessageEncodingMethod MessageEncodingMethod; typedef TF_SignatureSchemeOptions<ALG_INFO, KEYS, MessageEncodingMethod, H> SchemeOptions; - static std::string StaticAlgorithmName() {return KEYS::StaticAlgorithmName() + "/" + MessageEncodingMethod::StaticAlgorithmName() + "(" + H::StaticAlgorithmName() + ")";} + static std::string CRYPTOPP_API StaticAlgorithmName() {return std::string(KEYS::StaticAlgorithmName()) + "/" + MessageEncodingMethod::StaticAlgorithmName() + "(" + H::StaticAlgorithmName() + ")";} //! implements PK_Signer interface typedef PK_FinalTemplate<TF_SignerImpl<SchemeOptions> > Signer; @@ -97,12 +97,10 @@ struct RabinSS : public TF_SS<STANDARD, H, Rabin> { }; -class SHA; - // More typedefs for backwards compatibility - -typedef RabinES<OAEP<SHA> >::Decryptor RabinDecryptor; -typedef RabinES<OAEP<SHA> >::Encryptor RabinEncryptor; +class SHA1; +typedef RabinES<OAEP<SHA1> >::Decryptor RabinDecryptor; +typedef RabinES<OAEP<SHA1> >::Encryptor RabinEncryptor; NAMESPACE_END diff --git a/regtest.cpp b/regtest.cpp index 7f140468..b6cd3d9b 100644 --- a/regtest.cpp +++ b/regtest.cpp @@ -17,6 +17,7 @@ #include "shacal2.h" #include "tea.h" #include "panama.h" +#include "pssr.h" USING_NAMESPACE(CryptoPP) @@ -12,7 +12,7 @@ NAMESPACE_BEGIN(CryptoPP) //! _ struct Rijndael_Info : public FixedBlockSize<16>, public VariableKeyLength<16, 16, 32, 8> { - CRYPTOPP_DLL static const char * StaticAlgorithmName() {return "Rijndael";} + CRYPTOPP_DLL static const char * CRYPTOPP_API StaticAlgorithmName() {return "Rijndael";} }; /// <a href="http://www.weidai.com/scan-mirror/cs.html#Rijndael">Rijndael</a> @@ -54,21 +54,16 @@ byte LC_RNG::GenerateByte() #ifndef CRYPTOPP_IMPORTS -X917RNG::X917RNG(BlockTransformation *c, const byte *seed, unsigned long deterministicTimeVector) +X917RNG::X917RNG(BlockTransformation *c, const byte *seed, const byte *deterministicTimeVector) : cipher(c), S(cipher->BlockSize()), dtbuf(S), randseed(seed, S), randbuf(S), randbuf_counter(0), - m_deterministicTimeVector(deterministicTimeVector) + m_deterministicTimeVector(deterministicTimeVector, deterministicTimeVector ? S : 0) { - if (m_deterministicTimeVector) - { - memset(dtbuf, 0, S); - memcpy(dtbuf, (byte *)&m_deterministicTimeVector, STDMIN((int)sizeof(m_deterministicTimeVector), S)); - } - else + if (!deterministicTimeVector) { time_t tstamp1 = time(0); xorbuf(dtbuf, (byte *)&tstamp1, STDMIN((int)sizeof(tstamp1), S)); @@ -84,17 +79,17 @@ byte X917RNG::GenerateByte() if (randbuf_counter==0) { // calculate new enciphered timestamp - if (m_deterministicTimeVector) + if (m_deterministicTimeVector.size()) { - xorbuf(dtbuf, (byte *)&m_deterministicTimeVector, STDMIN((int)sizeof(m_deterministicTimeVector), S)); - while (++m_deterministicTimeVector == 0) {} // skip 0 + cipher->ProcessBlock(m_deterministicTimeVector, dtbuf); + IncrementCounterByOne(m_deterministicTimeVector, S); } else { clock_t tstamp = clock(); xorbuf(dtbuf, (byte *)&tstamp, STDMIN((int)sizeof(tstamp), S)); + cipher->ProcessBlock(dtbuf); } - cipher->ProcessBlock(dtbuf); // combine enciphered timestamp with seed xorbuf(randseed, dtbuf, S); @@ -109,7 +104,7 @@ byte X917RNG::GenerateByte() randbuf_counter=S; } - return(randbuf[--randbuf_counter]); + return(randbuf[S-randbuf_counter--]); } #endif @@ -35,7 +35,7 @@ class CRYPTOPP_DLL X917RNG : public RandomNumberGenerator, public NotCopyable { public: // cipher will be deleted by destructor, deterministicTimeVector = 0 means obtain time vector from system - X917RNG(BlockTransformation *cipher, const byte *seed, unsigned long deterministicTimeVector = 0); + X917RNG(BlockTransformation *cipher, const byte *seed, const byte *deterministicTimeVector = 0); byte GenerateByte(); @@ -43,9 +43,8 @@ private: member_ptr<BlockTransformation> cipher; const int S; // blocksize of cipher SecByteBlock dtbuf; // buffer for enciphered timestamp - SecByteBlock randseed, randbuf; + SecByteBlock randseed, randbuf, m_deterministicTimeVector; int randbuf_counter; // # of unused bytes left in randbuf - unsigned long m_deterministicTimeVector; }; /** This class implements Maurer's Universal Statistical Test for Random Bit Generators @@ -285,6 +285,20 @@ void InvertibleRSAFunction::AssignFrom(const NameValuePairs &source) ; } +// ***************************************************************************** + +Integer RSAFunction_ISO::ApplyFunction(const Integer &x) const +{ + Integer t = RSAFunction::ApplyFunction(x); + return t % 16 == 12 ? t : m_n - t; +} + +Integer InvertibleRSAFunction_ISO::CalculateInverse(RandomNumberGenerator &rng, const Integer &x) const +{ + Integer t = InvertibleRSAFunction::CalculateInverse(rng, x); + return STDMIN(t, m_n-t); +} + NAMESPACE_END #endif @@ -6,10 +6,11 @@ ciphers and signature schemes as defined in PKCS #1 v2.0. */ +#include "pubkey.h" +#include "asn.h" #include "pkcspad.h" #include "oaep.h" -#include "integer.h" -#include "asn.h" +#include "emsa2.h" NAMESPACE_BEGIN(CryptoPP) @@ -97,10 +98,24 @@ protected: Integer m_d, m_p, m_q, m_dp, m_dq, m_u; }; +class CRYPTOPP_DLL RSAFunction_ISO : public RSAFunction +{ +public: + Integer ApplyFunction(const Integer &x) const; + Integer PreimageBound() const {return ++(m_n>>1);} +}; + +class CRYPTOPP_DLL InvertibleRSAFunction_ISO : public InvertibleRSAFunction +{ +public: + Integer CalculateInverse(RandomNumberGenerator &rng, const Integer &x) const; + Integer PreimageBound() const {return ++(m_n>>1);} +}; + //! RSA struct CRYPTOPP_DLL RSA { - static std::string StaticAlgorithmName() {return "RSA";} + static const char * CRYPTOPP_API StaticAlgorithmName() {return "RSA";} typedef RSAFunction PublicKey; typedef InvertibleRSAFunction PrivateKey; }; @@ -118,6 +133,18 @@ struct RSASS : public TF_SS<STANDARD, H, RSA> { }; +struct CRYPTOPP_DLL RSA_ISO +{ + static const char * CRYPTOPP_API StaticAlgorithmName() {return "RSA-ISO";} + typedef RSAFunction_ISO PublicKey; + typedef InvertibleRSAFunction_ISO PrivateKey; +}; + +template <class H> +struct RSASS_ISO : public TF_SS<P1363_EMSA2, H, RSA_ISO> +{ +}; + // The two RSA encryption schemes defined in PKCS #1 v2.0 typedef RSAES<PKCS1v15>::Decryptor RSAES_PKCS1v15_Decryptor; typedef RSAES<PKCS1v15>::Encryptor RSAES_PKCS1v15_Encryptor; @@ -5,32 +5,9 @@ #include "nbtheory.h" #include "asn.h" -NAMESPACE_BEGIN(CryptoPP) - -void EMSA2Pad::ComputeMessageRepresentative(RandomNumberGenerator &rng, - const byte *recoverableMessage, unsigned int recoverableMessageLength, - HashTransformation &hash, HashIdentifier hashIdentifier, bool messageEmpty, - byte *representative, unsigned int representativeBitLength) const -{ - if (representativeBitLength % 8 != 7) - throw PK_SignatureScheme::InvalidKeyLength("EMSA2: EMSA2 requires a key length that is a multiple of 8"); - - unsigned int digestSize = hash.DigestSize(); - if (representativeBitLength < 8*digestSize + 31) - throw PK_SignatureScheme::KeyTooShort(); - - unsigned int representativeByteLength = BitsToBytes(representativeBitLength); - - representative[0] = messageEmpty ? 0x4b : 0x6b; - memset(representative+1, 0xbb, representativeByteLength-digestSize-4); // pad with 0xbb - byte *afterP2 = representative+representativeByteLength-digestSize-3; - afterP2[0] = 0xba; - hash.Final(afterP2+1); - representative[representativeByteLength-2] = *hashIdentifier.first; - representative[representativeByteLength-1] = 0xcc; -} +#ifndef CRYPTOPP_IMPORTS -// ***************************************************************************** +NAMESPACE_BEGIN(CryptoPP) void RWFunction::BERDecode(BufferedTransformation &bt) { @@ -201,3 +178,5 @@ void InvertibleRWFunction::AssignFrom(const NameValuePairs &source) } NAMESPACE_END + +#endif @@ -6,13 +6,12 @@ Rabin-Williams signature schemes as defined in IEEE P1363. */ -#include "integer.h" -#include "pssr.h" +#include "pubkey.h" NAMESPACE_BEGIN(CryptoPP) //! _ -class RWFunction : virtual public TrapdoorFunction, public PublicKey +class CRYPTOPP_DLL RWFunction : virtual public TrapdoorFunction, public PublicKey { typedef RWFunction ThisClass; @@ -39,7 +38,7 @@ protected: }; //! _ -class InvertibleRWFunction : public RWFunction, public TrapdoorFunctionInverse, public PrivateKey +class CRYPTOPP_DLL InvertibleRWFunction : public RWFunction, public TrapdoorFunctionInverse, public PrivateKey { typedef InvertibleRWFunction ThisClass; @@ -74,31 +73,6 @@ protected: Integer m_p, m_q, m_u; }; -//! _ -class EMSA2Pad : public EMSA2HashIdLookup<PK_DeterministicSignatureMessageEncodingMethod> -{ -public: - static const char *StaticAlgorithmName() {return "EMSA2";} - - unsigned int MaxUnpaddedLength(unsigned int paddedLength) const {return (paddedLength+1)/8-2;} - - void ComputeMessageRepresentative(RandomNumberGenerator &rng, - const byte *recoverableMessage, unsigned int recoverableMessageLength, - HashTransformation &hash, HashIdentifier hashIdentifier, bool messageEmpty, - byte *representative, unsigned int representativeBitLength) const; -}; - -//! EMSA2, for use with RWSS -/*! Only the following hash functions are supported by this signature standard: - \dontinclude pssr.h - \skip can be instantiated - \until end of list -*/ -struct P1363_EMSA2 : public SignatureStandard -{ - typedef EMSA2Pad SignatureMessageEncodingMethod; -}; - //! RW struct RW { @@ -286,12 +286,28 @@ public: memcpy(m_ptr, t.m_ptr, m_size*sizeof(T)); } - SecBlock& operator=(const SecBlock<T, A> &t) + SecBlock<T, A>& operator=(const SecBlock<T, A> &t) { Assign(t); return *this; } + SecBlock<T, A>& operator+=(const SecBlock<T, A> &t) + { + unsigned int oldSize = m_size; + Grow(m_size+t.m_size); + memcpy(m_ptr+oldSize, t.m_ptr, t.m_size*sizeof(T)); + return *this; + } + + SecBlock<T, A> operator+(const SecBlock<T, A> &t) + { + SecBlock<T, A> result(m_size+t.m_size); + memcpy(result.m_ptr, m_ptr, m_size*sizeof(T)); + memcpy(result.m_ptr+m_size, t.m_ptr, t.m_size*sizeof(T)); + return result; + } + bool operator==(const SecBlock<T, A> &t) const { return m_size == t.m_size && memcmp(m_ptr, t.m_ptr, m_size*sizeof(T)) == 0; @@ -79,7 +79,7 @@ class FixedKeyLength public: enum {KEYLENGTH=N, MIN_KEYLENGTH=N, MAX_KEYLENGTH=N, DEFAULT_KEYLENGTH=N}; enum {IV_REQUIREMENT = IV_REQ}; - static unsigned int StaticGetValidKeyLength(unsigned int) {return KEYLENGTH;} + static unsigned int CRYPTOPP_API StaticGetValidKeyLength(unsigned int) {return KEYLENGTH;} }; /// support query of variable key length, template parameters are default, min, max, multiple (default multiple 1) @@ -96,7 +96,7 @@ class VariableKeyLength public: enum {MIN_KEYLENGTH=N, MAX_KEYLENGTH=M, DEFAULT_KEYLENGTH=D, KEYLENGTH_MULTIPLE=Q}; enum {IV_REQUIREMENT = IV_REQ}; - static unsigned int StaticGetValidKeyLength(unsigned int n) + static unsigned int CRYPTOPP_API StaticGetValidKeyLength(unsigned int n) { if (n < (unsigned int)MIN_KEYLENGTH) return MIN_KEYLENGTH; @@ -117,7 +117,7 @@ class SameKeyLengthAs public: enum {MIN_KEYLENGTH=T::MIN_KEYLENGTH, MAX_KEYLENGTH=T::MAX_KEYLENGTH, DEFAULT_KEYLENGTH=T::DEFAULT_KEYLENGTH}; enum {IV_REQUIREMENT = T::IV_REQUIREMENT}; - static unsigned int StaticGetValidKeyLength(unsigned int keylength) + static unsigned int CRYPTOPP_API StaticGetValidKeyLength(unsigned int keylength) {return T::StaticGetValidKeyLength(keylength);} }; @@ -17,7 +17,7 @@ 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)) -void SHA::InitState(HashWordType *state) +void SHA1::InitState(HashWordType *state) { state[0] = 0x67452301L; state[1] = 0xEFCDAB89L; @@ -38,7 +38,7 @@ void SHA::InitState(HashWordType *state) #define R3(v,w,x,y,z,i) z+=f3(w,x,y)+blk1(i)+0x8F1BBCDC+rotlFixed(v,5);w=rotlFixed(w,30); #define R4(v,w,x,y,z,i) z+=f4(w,x,y)+blk1(i)+0xCA62C1D6+rotlFixed(v,5);w=rotlFixed(w,30); -void SHA::Transform(word32 *state, const word32 *data) +void SHA1::Transform(word32 *state, const word32 *data) { word32 W[16]; /* Copy context->state[] to working vars */ @@ -6,15 +6,15 @@ NAMESPACE_BEGIN(CryptoPP) /// <a href="http://www.weidai.com/scan-mirror/md.html#SHA-1">SHA-1</a> -class CRYPTOPP_DLL SHA : public IteratedHashWithStaticTransform<word32, BigEndian, 64, 20, SHA> +class CRYPTOPP_DLL SHA1 : public IteratedHashWithStaticTransform<word32, BigEndian, 64, 20, SHA1> { public: static void InitState(HashWordType *state); static void Transform(word32 *digest, const word32 *data); - static const char *StaticAlgorithmName() {return "SHA-1";} + static const char * CRYPTOPP_API StaticAlgorithmName() {return "SHA-1";} }; -typedef SHA SHA1; +typedef SHA1 SHA; // for backwards compatibility //! implements the SHA-256 standard class CRYPTOPP_DLL SHA256 : public IteratedHashWithStaticTransform<word32, BigEndian, 64, 32, SHA256> @@ -22,7 +22,7 @@ class CRYPTOPP_DLL SHA256 : public IteratedHashWithStaticTransform<word32, BigEn public: static void InitState(HashWordType *state); static void Transform(word32 *digest, const word32 *data); - static const char *StaticAlgorithmName() {return "SHA-256";} + static const char * CRYPTOPP_API StaticAlgorithmName() {return "SHA-256";} protected: static const word32 K[64]; @@ -34,7 +34,7 @@ class CRYPTOPP_DLL SHA224 : public IteratedHashWithStaticTransform<word32, BigEn public: static void InitState(HashWordType *state); static void Transform(word32 *digest, const word32 *data) {SHA256::Transform(digest, data);} - static const char *StaticAlgorithmName() {return "SHA-224";} + static const char * CRYPTOPP_API StaticAlgorithmName() {return "SHA-224";} }; #ifdef WORD64_AVAILABLE @@ -45,7 +45,7 @@ class CRYPTOPP_DLL SHA512 : public IteratedHashWithStaticTransform<word64, BigEn public: static void InitState(HashWordType *state); static void Transform(word64 *digest, const word64 *data); - static const char *StaticAlgorithmName() {return "SHA-512";} + static const char * CRYPTOPP_API StaticAlgorithmName() {return "SHA-512";} protected: static const word64 K[80]; @@ -57,7 +57,7 @@ class CRYPTOPP_DLL SHA384 : public IteratedHashWithStaticTransform<word64, BigEn public: static void InitState(HashWordType *state); static void Transform(word64 *digest, const word64 *data) {SHA512::Transform(digest, data);} - static const char *StaticAlgorithmName() {return "SHA-384";} + static const char * CRYPTOPP_API StaticAlgorithmName() {return "SHA-384";} }; #endif @@ -24,7 +24,7 @@ template <class BASE, class ALGORITHM_INFO=BASE> class CRYPTOPP_NO_VTABLE AlgorithmImpl : public BASE { public: - static std::string StaticAlgorithmName() {return ALGORITHM_INFO::StaticAlgorithmName();} + static std::string CRYPTOPP_API StaticAlgorithmName() {return ALGORITHM_INFO::StaticAlgorithmName();} std::string AlgorithmName() const {return ALGORITHM_INFO::StaticAlgorithmName();} }; @@ -85,7 +85,7 @@ int (*AdhocTest)(int argc, char *argv[]) = NULL; #ifdef __BCPLUSPLUS__ int cmain(int argc, char *argv[]) #else -int CRYPTOPP_CDECL main(int argc, char *argv[]) +int main(int argc, char *argv[]) #endif { #ifdef _CRTDBG_LEAK_CHECK_DF @@ -170,8 +170,8 @@ int CRYPTOPP_CDECL main(int argc, char *argv[]) else if (command == "mac_dll") { HMODULE hModule = LoadLibrary(argv[2]); - PGetPowerUpSelfTestStatus pGetPowerUpSelfTestStatus = (PGetPowerUpSelfTestStatus)GetProcAddress(hModule, "?GetPowerUpSelfTestStatus@CryptoPP@@YG?AW4PowerUpSelfTestStatus@1@XZ"); - PGetActualMacAndLocation pGetActualMacAndLocation = (PGetActualMacAndLocation)GetProcAddress(hModule, "?GetActualMacAndLocation@CryptoPP@@YGPBEAAI0@Z"); + PGetPowerUpSelfTestStatus pGetPowerUpSelfTestStatus = (PGetPowerUpSelfTestStatus)GetProcAddress(hModule, "?GetPowerUpSelfTestStatus@CryptoPP@@YA?AW4PowerUpSelfTestStatus@1@XZ"); + PGetActualMacAndLocation pGetActualMacAndLocation = (PGetActualMacAndLocation)GetProcAddress(hModule, "?GetActualMacAndLocation@CryptoPP@@YAPBEAAI0@Z"); PowerUpSelfTestStatus status = pGetPowerUpSelfTestStatus(); if (status == POWER_UP_SELF_TEST_PASSED) @@ -383,14 +383,14 @@ string RSADecryptString(const char *privFilename, const char *ciphertext) void RSASignFile(const char *privFilename, const char *messageFilename, const char *signatureFilename) { FileSource privFile(privFilename, true, new HexDecoder); - RSASSA_PKCS1v15_SHA_Signer priv(privFile); + RSASS<PKCS1v15, SHA>::Signer priv(privFile); FileSource f(messageFilename, true, new SignerFilter(GlobalRNG(), priv, new HexEncoder(new FileSink(signatureFilename)))); } bool RSAVerifyFile(const char *pubFilename, const char *messageFilename, const char *signatureFilename) { FileSource pubFile(pubFilename, true, new HexDecoder); - RSASSA_PKCS1v15_SHA_Verifier pub(pubFile); + RSASS<PKCS1v15, SHA>::Verifier pub(pubFile); FileSource signatureFile(signatureFilename, true, new HexDecoder); if (signatureFile.MaxRetrievable() != pub.SignatureLength()) diff --git a/zdeflate.cpp b/zdeflate.cpp index a5a8dafb..b6d61497 100644 --- a/zdeflate.cpp +++ b/zdeflate.cpp @@ -97,6 +97,8 @@ struct FreqLessThan { inline bool operator()(unsigned int lhs, const HuffmanNode &rhs) {return lhs < rhs.freq;} inline bool operator()(const HuffmanNode &lhs, const HuffmanNode &rhs) const {return lhs.freq < rhs.freq;} + // needed for MSVC .NET 2005 + inline bool operator()(const HuffmanNode &lhs, unsigned int rhs) {return lhs.freq < rhs;} }; void HuffmanEncoder::GenerateCodeLengths(unsigned int *codeBits, unsigned int maxCodeBits, const unsigned int *codeCounts, unsigned int nCodes) diff --git a/zinflate.cpp b/zinflate.cpp index f8d5b4b6..864a3e51 100644 --- a/zinflate.cpp +++ b/zinflate.cpp @@ -12,8 +12,11 @@ NAMESPACE_BEGIN(CryptoPP) struct CodeLessThan { - inline bool operator()(const CryptoPP::HuffmanDecoder::code_t lhs, const CryptoPP::HuffmanDecoder::CodeInfo &rhs) + inline bool operator()(CryptoPP::HuffmanDecoder::code_t lhs, const CryptoPP::HuffmanDecoder::CodeInfo &rhs) {return lhs < rhs.code;} + // needed for MSVC .NET 2005 + inline bool operator()(const CryptoPP::HuffmanDecoder::CodeInfo &lhs, const CryptoPP::HuffmanDecoder::CodeInfo &rhs) + {return lhs.code < rhs.code;} }; inline bool LowFirstBitReader::FillBuffer(unsigned int length) |