diff --git a/GNUmakefile b/GNUmakefile index 39f841fa..822846ac 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -44,13 +44,19 @@ endif OBJS = $(SRCS:.cpp=.o) # test.o needs to be after bench.o for cygwin 1.1.4 (possible ld bug?) -TESTOBJS = bench.o test.o validat1.o validat2.o validat3.o adhoc.o datatest.o regtest.o fipsalgt.o +TESTOBJS = bench.o test.o validat1.o validat2.o validat3.o adhoc.o datatest.o regtest.o fipsalgt.o dlltest.o LIBOBJS = $(filter-out $(TESTOBJS),$(OBJS)) +DLLSRCS = algebra.cpp algparam.cpp asn.cpp basecode.cpp cbcmac.cpp channels.cpp cryptlib.cpp des.cpp dessp.cpp dh.cpp dll.cpp dsa.cpp ec2n.cpp eccrypto.cpp ecp.cpp eprecomp.cpp files.cpp filters.cpp fips140.cpp fipstest.cpp gf2n.cpp gfpcrypt.cpp hex.cpp hmac.cpp integer.cpp iterhash.cpp misc.cpp modes.cpp modexppc.cpp mqueue.cpp nbtheory.cpp oaep.cpp osrng.cpp pch.cpp pkcspad.cpp pubkey.cpp queue.cpp randpool.cpp rdtables.cpp rijndael.cpp rng.cpp rsa.cpp sha.cpp simple.cpp skipjack.cpp strciphr.cpp trdlocal.cpp +DLLOBJS = $(DLLSRCS:.cpp=.export.o) +LIBIMPORTOBJS = $(LIBOBJS:.o=import.o) +TESTIMPORTOBJS = $(TESTOBJS:.o=import.o) +DLLTESTOBJS = dlltest.dllonly.o + all: cryptest.exe clean: - $(RM) cryptest.exe libcryptopp.a $(LIBOBJS) $(TESTOBJS) + $(RM) cryptest.exe libcryptopp.a $(LIBOBJS) $(TESTOBJS) cryptopp.dll libcryptopp.dll.a libcryptopp.import.a cryptest.import.exe dlltest.exe $(DLLOBJS) $(LIBIMPORTOBJS) $(TESTIMPORTOBJS) $(DLLTESTOBJS) libcryptopp.a: $(LIBOBJS) $(AR) $(ARFLAGS) $@ $(LIBOBJS) @@ -62,6 +68,21 @@ cryptest.exe: libcryptopp.a $(TESTOBJS) nolib: $(OBJS) # makes it faster to test changes $(CXX) -o ct $(CXXFLAGS) $(OBJS) $(LDFLAGS) $(LDLIBS) +dll: cryptest.import.exe dlltest.exe + +cryptopp.dll: $(DLLOBJS) + $(CXX) -shared -o $@ $(CXXFLAGS) $(DLLOBJS) $(LDFLAGS) $(LDLIBS) -Wl,--out-implib=libcryptopp.dll.a + +libcryptopp.import.a: $(LIBIMPORTOBJS) + $(AR) $(ARFLAGS) $@ $(LIBIMPORTOBJS) + $(RANLIB) $@ + +cryptest.import.exe: cryptopp.dll libcryptopp.import.a $(TESTIMPORTOBJS) + $(CXX) -o $@ $(CXXFLAGS) $(TESTIMPORTOBJS) -L. -lcryptopp.dll -lcryptopp.import $(LDFLAGS) $(LDLIBS) + +dlltest.exe: cryptopp.dll $(DLLTESTOBJS) + $(CXX) -o $@ $(CXXFLAGS) $(DLLTESTOBJS) -L. -lcryptopp.dll $(LDFLAGS) $(LDLIBS) + adhoc.cpp: adhoc.cpp.proto ifeq ($(wildcard adhoc.cpp),) cp adhoc.cpp.proto adhoc.cpp @@ -69,7 +90,14 @@ else touch adhoc.cpp endif -.SUFFIXES: .cpp +%.dllonly.o : %.cpp + $(CXX) $(CXXFLAGS) -DCRYPTOPP_DLL_ONLY -c $< -o $@ -.cpp.o: +%.import.o : %.cpp + $(CXX) $(CXXFLAGS) -DCRYPTOPP_IMPORTS -c $< -o $@ + +%.export.o : %.cpp + $(CXX) $(CXXFLAGS) -DCRYPTOPP_EXPORTS -c $< -o $@ + +%.o : %.cpp $(CXX) $(CXXFLAGS) -c $< diff --git a/Readme.txt b/Readme.txt index 1ffaefc9..2b8a9a25 100644 --- a/Readme.txt +++ b/Readme.txt @@ -248,6 +248,8 @@ History 5.03 - created DLL version of Crypto++ for FIPS 140-2 validation - fixed vulnerabilities in GetNextIV for CTR and OFB modes +5.0.4 - Removed DES, SHA-256, SHA-384, SHA-512 from DLL + 5.1 - added PSS padding and changed PSSR to track IEEE P1363a draft standard - added blinding for RSA and Rabin to defend against timing attacks on decryption operations @@ -260,4 +262,4 @@ History - fixed a number of compiler warnings, minor bugs, and portability problems - removed Sapphire -5.2 - Merged in changes for 5.01 - 5.03 +5.2 - Merged in changes for 5.01 - 5.04 diff --git a/config.h b/config.h index 3b864cac..0d38cd18 100644 --- a/config.h +++ b/config.h @@ -191,35 +191,6 @@ NAMESPACE_END # pragma warning(disable: 4231 4250 4251 4275 4660 4661 4786 4355) #endif -#ifdef _MSC_VER - -#ifdef CRYPTOPP_EXPORTS -#define CRYPTOPP_IS_DLL -#define CRYPTOPP_DLL __declspec(dllexport) -#elif defined(CRYPTOPP_IMPORTS) -#define CRYPTOPP_IS_DLL -#define CRYPTOPP_DLL __declspec(dllimport) -#else -#define CRYPTOPP_DLL -#endif - -#define CRYPTOPP_API __stdcall - -#else // _MSC_VER - -#define CRYPTOPP_DLL -#define CRYPTOPP_API - -#endif // _MSC_VER - -#ifdef CRYPTOPP_MANUALLY_INSTANTIATE_TEMPLATES -#define CRYPTOPP_MANUAL_EXTERN -#else -#define CRYPTOPP_MANUAL_EXTERN extern -#endif - -#define CRYPTOPP_DLL_TEMPLATE_CLASS CRYPTOPP_MANUAL_EXTERN template class CRYPTOPP_DLL - // ***************** determine availability of OS features ******************** #ifndef NO_OS_DEPENDENCE @@ -278,4 +249,40 @@ NAMESPACE_END #endif // NO_OS_DEPENDENCE +// ***************** DLL related ******************** + +#ifdef CRYPTOPP_WIN32_AVAILABLE + +#ifdef CRYPTOPP_EXPORTS +#define CRYPTOPP_IS_DLL +#define CRYPTOPP_DLL __declspec(dllexport) +#elif defined(CRYPTOPP_IMPORTS) +#define CRYPTOPP_IS_DLL +#define CRYPTOPP_DLL __declspec(dllimport) +#else +#define CRYPTOPP_DLL +#endif + +#define CRYPTOPP_API __stdcall + +#else // CRYPTOPP_WIN32_AVAILABLE + +#define CRYPTOPP_NO_DLL +#define CRYPTOPP_DLL +#define CRYPTOPP_API + +#endif // CRYPTOPP_WIN32_AVAILABLE + +#if defined(CRYPTOPP_MANUALLY_INSTANTIATE_TEMPLATES) && !defined(CRYPTOPP_IMPORTS) +#define CRYPTOPP_DLL_TEMPLATE_CLASS template class CRYPTOPP_DLL +#else +#define CRYPTOPP_DLL_TEMPLATE_CLASS extern template class CRYPTOPP_DLL +#endif + +#if defined(CRYPTOPP_MANUALLY_INSTANTIATE_TEMPLATES) && !defined(CRYPTOPP_EXPORTS) +#define CRYPTOPP_STATIC_TEMPLATE_CLASS template class +#else +#define CRYPTOPP_STATIC_TEMPLATE_CLASS extern template class +#endif + #endif diff --git a/cryptdll.dsp b/cryptdll.dsp index d7d68f12..ea13cf13 100644 --- a/cryptdll.dsp +++ b/cryptdll.dsp @@ -81,7 +81,7 @@ SOURCE="$(InputPath)" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "CRYPTDLL_EXPORTS" /YX /FD /GZ /c -# ADD CPP /nologo /G5 /Gz /MDd /W3 /Gm /GX /Zi /Od /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "CRYPTOPP_EXPORTS" /D CRYPTOPP_ENABLE_COMPLIANCE_WITH_FIPS_140_2=1 /D "USE_PRECOMPILED_HEADERS" /Yu"pch.h" /FD /GZ /Zm200 /c +# ADD CPP /nologo /G5 /Gz /MTd /W3 /Gm /GX /Zi /Od /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "CRYPTOPP_EXPORTS" /D CRYPTOPP_ENABLE_COMPLIANCE_WITH_FIPS_140_2=1 /D "USE_PRECOMPILED_HEADERS" /Yu"pch.h" /FD /GZ /Zm200 /c # ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x409 /d "_DEBUG" diff --git a/cryptest.dsw b/cryptest.dsw index 2260dbf9..eff090ba 100644 --- a/cryptest.dsw +++ b/cryptest.dsw @@ -76,6 +76,18 @@ Package=<4> ############################################################################### +Project: "dlltest"=.\dlltest.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + Global: Package=<5> diff --git a/cryptlib.h b/cryptlib.h index a1a2f1c4..c3d15b95 100644 --- a/cryptlib.h +++ b/cryptlib.h @@ -49,15 +49,15 @@ In the FIPS 140-2 validated DLL version of Crypto++, only the following implementation class are available.
Block Ciphers
- AES, DES, DES_EDE2, DES_EDE3, SKIPJACK + AES, DES_EDE2, DES_EDE3, SKIPJACK
Cipher Modes (replace template parameter BC with one of the block ciphers above)
ECB_Mode , CTR_Mode , CBC_Mode , CFB_Mode , OFB_Mode
Hash Functions
- SHA, SHA256, SHA384, SHA512 + SHA
Public Key Signature Schemes
RSASSA , DSA, ECDSA , ECDSA
Message Authentication Codes
- HMAC , HMAC , HMAC , HMAC , CBC_MAC , CBC_MAC , CBC_MAC + HMAC , CBC_MAC , CBC_MAC
Random Number Generators
AutoSeededX917RNG
Key Agreement
diff --git a/cryptopp.rc b/cryptopp.rc index 0a5a0a33..06f52893 100644 --- a/cryptopp.rc +++ b/cryptopp.rc @@ -44,7 +44,7 @@ BEGIN BEGIN BLOCK "040904b0" BEGIN - VALUE "Comments", "free crypto library, more info at www.cryptopp.com\0" + 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" diff --git a/des.cpp b/des.cpp index c9f4a384..3afe0b31 100644 --- a/des.cpp +++ b/des.cpp @@ -20,29 +20,105 @@ NAMESPACE_BEGIN(CryptoPP) +typedef BlockGetAndPut Block; + +// Richard Outerbridge's initial permutation algorithm +/* +inline void IPERM(word32 &left, word32 &right) +{ + word32 work; + + work = ((left >> 4) ^ right) & 0x0f0f0f0f; + right ^= work; + left ^= work << 4; + work = ((left >> 16) ^ right) & 0xffff; + right ^= work; + left ^= work << 16; + work = ((right >> 2) ^ left) & 0x33333333; + left ^= work; + right ^= (work << 2); + work = ((right >> 8) ^ left) & 0xff00ff; + left ^= work; + right ^= (work << 8); + right = rotl(right, 1); + work = (left ^ right) & 0xaaaaaaaa; + left ^= work; + right ^= work; + left = rotl(left, 1); +} +inline void FPERM(word32 &left, word32 &right) +{ + word32 work; + + right = rotr(right, 1); + work = (left ^ right) & 0xaaaaaaaa; + left ^= work; + right ^= work; + left = rotr(left, 1); + work = ((left >> 8) ^ right) & 0xff00ff; + right ^= work; + left ^= work << 8; + work = ((left >> 2) ^ right) & 0x33333333; + right ^= work; + left ^= work << 2; + work = ((right >> 16) ^ left) & 0xffff; + left ^= work; + right ^= work << 16; + work = ((right >> 4) ^ left) & 0x0f0f0f0f; + left ^= work; + right ^= work << 4; +} +*/ + +// Wei Dai's modification to Richard Outerbridge's initial permutation +// algorithm, this one is faster if you have access to rotate instructions +// (like in MSVC) +static inline void IPERM(word32 &left, word32 &right) +{ + word32 work; + + right = rotlFixed(right, 4U); + work = (left ^ right) & 0xf0f0f0f0; + left ^= work; + right = rotrFixed(right^work, 20U); + work = (left ^ right) & 0xffff0000; + left ^= work; + right = rotrFixed(right^work, 18U); + work = (left ^ right) & 0x33333333; + left ^= work; + right = rotrFixed(right^work, 6U); + work = (left ^ right) & 0x00ff00ff; + left ^= work; + right = rotlFixed(right^work, 9U); + work = (left ^ right) & 0xaaaaaaaa; + left = rotlFixed(left^work, 1U); + right ^= work; +} + +static inline void FPERM(word32 &left, word32 &right) +{ + word32 work; + + right = rotrFixed(right, 1U); + work = (left ^ right) & 0xaaaaaaaa; + right ^= work; + left = rotrFixed(left^work, 9U); + work = (left ^ right) & 0x00ff00ff; + right ^= work; + left = rotlFixed(left^work, 6U); + work = (left ^ right) & 0x33333333; + right ^= work; + left = rotlFixed(left^work, 18U); + work = (left ^ right) & 0xffff0000; + right ^= work; + left = rotlFixed(left^work, 20U); + work = (left ^ right) & 0xf0f0f0f0; + right ^= work; + left = rotrFixed(left^work, 4U); +} + #ifndef CRYPTOPP_IMPORTS -static inline bool CheckParity(byte b) -{ - unsigned int a = b ^ (b >> 4); - return ((a ^ (a>>1) ^ (a>>2) ^ (a>>3)) & 1) == 1; -} - -bool DES::CheckKeyParityBits(const byte *key) -{ - for (unsigned int i=0; i<8; i++) - if (!CheckParity(key[i])) - return false; - return true; -} - -void DES::CorrectKeyParityBits(byte *key) -{ - for (unsigned int i=0; i<8; i++) - if (!CheckParity(key[i])) - key[i] ^= 1; -} - /* Tables defined in the Data Encryption Standard documents * Three of these tables, the initial permutation, the final * permutation and the expansion operator, are regular enough that @@ -188,10 +264,8 @@ static const int bytebit[] = { }; /* Set key (initialize key schedule array) */ -void DES::Base::UncheckedSetKey(CipherDir dir, const byte *key, unsigned int length) +void RawDES::UncheckedSetKey(CipherDir dir, const byte *key, unsigned int length) { - AssertValidKeyLength(length); - SecByteBlock buffer(56+56+8); byte *const pc1m=buffer; /* place to modify pc1 into */ byte *const pcr=pc1m+56; /* place to rotate pc1 into */ @@ -238,102 +312,7 @@ void DES::Base::UncheckedSetKey(CipherDir dir, const byte *key, unsigned int len } } -// Richard Outerbridge's initial permutation algorithm -/* -inline void IPERM(word32 &left, word32 &right) -{ - word32 work; - - work = ((left >> 4) ^ right) & 0x0f0f0f0f; - right ^= work; - left ^= work << 4; - work = ((left >> 16) ^ right) & 0xffff; - right ^= work; - left ^= work << 16; - work = ((right >> 2) ^ left) & 0x33333333; - left ^= work; - right ^= (work << 2); - work = ((right >> 8) ^ left) & 0xff00ff; - left ^= work; - right ^= (work << 8); - right = rotl(right, 1); - work = (left ^ right) & 0xaaaaaaaa; - left ^= work; - right ^= work; - left = rotl(left, 1); -} -inline void FPERM(word32 &left, word32 &right) -{ - word32 work; - - right = rotr(right, 1); - work = (left ^ right) & 0xaaaaaaaa; - left ^= work; - right ^= work; - left = rotr(left, 1); - work = ((left >> 8) ^ right) & 0xff00ff; - right ^= work; - left ^= work << 8; - work = ((left >> 2) ^ right) & 0x33333333; - right ^= work; - left ^= work << 2; - work = ((right >> 16) ^ left) & 0xffff; - left ^= work; - right ^= work << 16; - work = ((right >> 4) ^ left) & 0x0f0f0f0f; - left ^= work; - right ^= work << 4; -} -*/ - -// Wei Dai's modification to Richard Outerbridge's initial permutation -// algorithm, this one is faster if you have access to rotate instructions -// (like in MSVC) -static inline void IPERM(word32 &left, word32 &right) -{ - word32 work; - - right = rotlFixed(right, 4U); - work = (left ^ right) & 0xf0f0f0f0; - left ^= work; - right = rotrFixed(right^work, 20U); - work = (left ^ right) & 0xffff0000; - left ^= work; - right = rotrFixed(right^work, 18U); - work = (left ^ right) & 0x33333333; - left ^= work; - right = rotrFixed(right^work, 6U); - work = (left ^ right) & 0x00ff00ff; - left ^= work; - right = rotlFixed(right^work, 9U); - work = (left ^ right) & 0xaaaaaaaa; - left = rotlFixed(left^work, 1U); - right ^= work; -} - -static inline void FPERM(word32 &left, word32 &right) -{ - word32 work; - - right = rotrFixed(right, 1U); - work = (left ^ right) & 0xaaaaaaaa; - right ^= work; - left = rotrFixed(left^work, 9U); - work = (left ^ right) & 0x00ff00ff; - right ^= work; - left = rotlFixed(left^work, 6U); - work = (left ^ right) & 0x33333333; - right ^= work; - left = rotlFixed(left^work, 18U); - work = (left ^ right) & 0xffff0000; - right ^= work; - left = rotlFixed(left^work, 20U); - work = (left ^ right) & 0xf0f0f0f0; - right ^= work; - left = rotrFixed(left^work, 4U); -} - -void DES::Base::RawProcessBlock(word32 &l_, word32 &r_) const +void RawDES::RawProcessBlock(word32 &l_, word32 &r_) const { word32 l = l_, r = r_; const word32 *kptr=k; @@ -366,46 +345,6 @@ void DES::Base::RawProcessBlock(word32 &l_, word32 &r_) const l_ = l; r_ = r; } -typedef BlockGetAndPut Block; - -// Encrypt or decrypt a block of data in ECB mode -void DES::Base::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const -{ - word32 l,r; - Block::Get(inBlock)(l)(r); - IPERM(l,r); - - const word32 *kptr=k; - - for (unsigned i=0; i<8; i++) - { - word32 work = rotrFixed(r, 4U) ^ kptr[4*i+0]; - l ^= Spbox[6][(work) & 0x3f] - ^ Spbox[4][(work >> 8) & 0x3f] - ^ Spbox[2][(work >> 16) & 0x3f] - ^ Spbox[0][(work >> 24) & 0x3f]; - work = r ^ kptr[4*i+1]; - l ^= Spbox[7][(work) & 0x3f] - ^ Spbox[5][(work >> 8) & 0x3f] - ^ Spbox[3][(work >> 16) & 0x3f] - ^ Spbox[1][(work >> 24) & 0x3f]; - - work = rotrFixed(l, 4U) ^ kptr[4*i+2]; - r ^= Spbox[6][(work) & 0x3f] - ^ Spbox[4][(work >> 8) & 0x3f] - ^ Spbox[2][(work >> 16) & 0x3f] - ^ Spbox[0][(work >> 24) & 0x3f]; - work = l ^ kptr[4*i+3]; - r ^= Spbox[7][(work) & 0x3f] - ^ Spbox[5][(work >> 8) & 0x3f] - ^ Spbox[3][(work >> 16) & 0x3f] - ^ Spbox[1][(work >> 24) & 0x3f]; - } - - FPERM(l,r); - Block::Put(xorBlock, outBlock)(r)(l); -} - void DES_EDE2::Base::UncheckedSetKey(CipherDir dir, const byte *key, unsigned int length) { AssertValidKeyLength(length); @@ -449,6 +388,38 @@ void DES_EDE3::Base::ProcessAndXorBlock(const byte *inBlock, const byte *xorBloc #endif // #ifndef CRYPTOPP_IMPORTS +static inline bool CheckParity(byte b) +{ + unsigned int a = b ^ (b >> 4); + return ((a ^ (a>>1) ^ (a>>2) ^ (a>>3)) & 1) == 1; +} + +bool DES::CheckKeyParityBits(const byte *key) +{ + for (unsigned int i=0; i<8; i++) + if (!CheckParity(key[i])) + return false; + return true; +} + +void DES::CorrectKeyParityBits(byte *key) +{ + for (unsigned int i=0; i<8; i++) + if (!CheckParity(key[i])) + key[i] ^= 1; +} + +// Encrypt or decrypt a block of data in ECB mode +void DES::Base::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const +{ + word32 l,r; + Block::Get(inBlock)(l)(r); + IPERM(l,r); + RawProcessBlock(l, r); + FPERM(l,r); + Block::Put(xorBlock, outBlock)(r)(l); +} + void DES_XEX3::Base::UncheckedSetKey(CipherDir dir, const byte *key, unsigned int length) { AssertValidKeyLength(length); diff --git a/des.h b/des.h index a6c56727..e39b1619 100644 --- a/des.h +++ b/des.h @@ -9,9 +9,22 @@ NAMESPACE_BEGIN(CryptoPP) +class CRYPTOPP_DLL RawDES +{ +public: + void UncheckedSetKey(CipherDir direction, const byte *userKey, unsigned int length = 8); + void RawProcessBlock(word32 &l, word32 &r) const; + +protected: + static const word32 Spbox[8][64]; + + FixedSizeSecBlock k; +}; + struct DES_Info : public FixedBlockSize<8>, public FixedKeyLength<8> { - CRYPTOPP_DLL static const char * StaticAlgorithmName() {return "DES";} + // disable DES in DLL version by not exporting this function + static const char * StaticAlgorithmName() {return "DES";} }; /// DES @@ -21,19 +34,10 @@ struct DES_Info : public FixedBlockSize<8>, public FixedKeyLength<8> check or correct the parity bits if you wish. */ class DES : public DES_Info, public BlockCipherDocumentation { - class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE Base : public BlockCipherImpl + class CRYPTOPP_NO_VTABLE Base : public BlockCipherImpl, public RawDES { public: - void UncheckedSetKey(CipherDir direction, const byte *userKey, unsigned int length = 8); void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const; - - // exposed for faster Triple-DES - void RawProcessBlock(word32 &l, word32 &r) const; - - protected: - static const word32 Spbox[8][64]; - - FixedSizeSecBlock k; }; public: @@ -61,7 +65,7 @@ class DES_EDE2 : public DES_EDE2_Info, public BlockCipherDocumentation void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const; protected: - DES::Encryption m_des1, m_des2; + RawDES m_des1, m_des2; }; public: @@ -84,7 +88,7 @@ class DES_EDE3 : public DES_EDE3_Info, public BlockCipherDocumentation void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const; protected: - DES::Encryption m_des1, m_des2, m_des3; + RawDES m_des1, m_des2, m_des3; }; public: diff --git a/dessp.cpp b/dessp.cpp index 4ef9d18b..49ed1d26 100644 --- a/dessp.cpp +++ b/dessp.cpp @@ -15,7 +15,7 @@ void DES_VC60Workaround() { } -const word32 DES::Base::Spbox[8][64] = { +const word32 RawDES::Spbox[8][64] = { { 0x01010400,0x00000000,0x00010000,0x01010404, 0x01010004,0x00010404,0x00000004,0x00010000, 0x00000400,0x01010400,0x01010404,0x00000400, 0x01000404,0x01010004,0x01000000,0x00000004, diff --git a/dll.cpp b/dll.cpp index 29f4aa57..8457abdd 100644 --- a/dll.cpp +++ b/dll.cpp @@ -1,33 +1,32 @@ // dll.cpp - written and placed in the public domain by Wei Dai -#ifndef CRYPTOPP_IMPORTS - #define CRYPTOPP_MANUALLY_INSTANTIATE_TEMPLATES #include "dll.h" #pragma warning(default: 4660) #include -#include +#include "iterhash.cpp" #include "strciphr.cpp" #include "algebra.cpp" #include "eprecomp.cpp" #include "eccrypto.cpp" -#include "iterhash.cpp" #include "oaep.cpp" -static const byte s_moduleMac[CryptoPP::HMAC::DIGESTSIZE] = "reserved for mac"; -static HMODULE s_hModule = NULL; +#ifndef CRYPTOPP_IMPORTS NAMESPACE_BEGIN(CryptoPP) template<> const byte PKCS_DigestDecoration::decoration[] = {0x30,0x21,0x30,0x09,0x06,0x05,0x2B,0x0E,0x03,0x02,0x1A,0x05,0x00,0x04,0x14}; template<> const unsigned int PKCS_DigestDecoration::length = sizeof(PKCS_DigestDecoration::decoration); +static const byte s_moduleMac[CryptoPP::HMAC::DIGESTSIZE] = "reserved for mac"; +static HMODULE s_hModule = NULL; + void DoDllPowerUpSelfTest() { - char moduleFileName[_MAX_PATH]; + char moduleFileName[MAX_PATH]; GetModuleFileNameA(s_hModule, moduleFileName, sizeof(moduleFileName)); CryptoPP::DoPowerUpSelfTest(moduleFileName, s_moduleMac); } @@ -40,43 +39,87 @@ NAMESPACE_END USING_NAMESPACE(CryptoPP) +#if !(defined(_MSC_VER) && (_MSC_VER < 1300)) +using std::set_new_handler; +#endif + static PNew s_pNew = NULL; static PDelete s_pDelete = NULL; +static void * _cdecl New (size_t size) +{ + new_handler newHandler = set_new_handler(NULL); + if (newHandler) + set_new_handler(newHandler); + + void *p; + while (!(p = malloc(size))) + { + if (newHandler) + newHandler(); + else + throw std::bad_alloc(); + } + + return p; +} + +static void SetNewAndDeleteFunctionPointers() +{ + void *p = NULL; + HMODULE hModule = NULL; + MEMORY_BASIC_INFORMATION mbi; + + while (true) + { + VirtualQuery(p, &mbi, sizeof(mbi)); + + if (p >= (char *)mbi.BaseAddress + mbi.RegionSize) + break; + + p = (char *)mbi.BaseAddress + mbi.RegionSize; + + if (!mbi.AllocationBase || mbi.AllocationBase == hModule) + continue; + + hModule = HMODULE(mbi.AllocationBase); + + PGetNewAndDelete pGetNewAndDelete = (PGetNewAndDelete)GetProcAddress(hModule, "GetNewAndDeleteForCryptoPP"); + if (pGetNewAndDelete) + { + pGetNewAndDelete(s_pNew, s_pDelete); + return; + } + + PSetNewAndDelete pSetNewAndDelete = (PSetNewAndDelete)GetProcAddress(hModule, "SetNewAndDeleteFromCryptoPP"); + if (pSetNewAndDelete) + { + s_pNew = &New; + s_pDelete = &free; + pSetNewAndDelete(s_pNew, s_pDelete, &set_new_handler); + return; + } + } + + hModule = GetModuleHandle("msvcrtd"); + if (!hModule) + hModule = GetModuleHandle("msvcrt"); + if (hModule) + { + s_pNew = (PNew)GetProcAddress(hModule, "??2@YAPAXI@Z"); // operator new + s_pDelete = (PDelete)GetProcAddress(hModule, "??3@YAXPAX@Z"); // operator delete + return; + } + + OutputDebugString("Crypto++ was not able to obtain new and delete function pointers.\n"); + throw 0; +} + void * _cdecl operator new (size_t size) { if (!s_pNew) - { - HMODULE hExe = GetModuleHandle(NULL); - PGetNewAndDelete pGetNewAndDelete = (PGetNewAndDelete)GetProcAddress(hExe, "GetNewAndDeleteForCryptoPP"); - if (pGetNewAndDelete) - pGetNewAndDelete(s_pNew, s_pDelete); - else - { - PSetNewAndDelete pSetNewAndDelete = (PSetNewAndDelete)GetProcAddress(hExe, "SetNewAndDeleteFromCryptoPP"); - if (pSetNewAndDelete) - { - _set_new_mode(1); - s_pNew = &malloc; - s_pDelete = &free; - pSetNewAndDelete(s_pNew, s_pDelete, &_set_new_handler); - } - else - { - HMODULE hCrt = GetModuleHandle("msvcrtd"); - if (!hCrt) - hCrt = GetModuleHandle("msvcrt"); - if (hCrt) - { - s_pNew = (PNew)GetProcAddress(hCrt, "??2@YAPAXI@Z"); // operator new - s_pDelete = (PDelete)GetProcAddress(hCrt, "??3@YAXPAX@Z"); // operator delete - } - } - } + SetNewAndDeleteFunctionPointers(); - if (!s_pNew || !s_pDelete) - OutputDebugString("Crypto++ was not able to obtain new and delete function pointers."); - } return s_pNew(size); } @@ -97,4 +140,4 @@ BOOL APIENTRY DllMain(HANDLE hModule, return TRUE; } -#endif +#endif // #ifdef CRYPTOPP_EXPORTS diff --git a/dll.h b/dll.h index a8b07d69..e2554be7 100644 --- a/dll.h +++ b/dll.h @@ -1,7 +1,7 @@ #ifndef CRYPTOPP_DLL_H #define CRYPTOPP_DLL_H -#if !defined(CRYPTOPP_EXPORTS) && !defined(CRYPTOPP_IMPORTS) && !defined(CRYPTOPP_NO_DLL) +#if !defined(CRYPTOPP_IMPORTS) && !defined(CRYPTOPP_EXPORTS) && !defined(CRYPTOPP_NO_DLL) #ifdef CRYPTOPP_CONFIG_H #error To use the DLL version of Crypto++, this file must be included before any other Crypto++ header files. #endif @@ -47,14 +47,18 @@ #endif // #ifdef CRYPTOPP_IMPORTS -#include // for _PNH +#include // for new_handler NAMESPACE_BEGIN(CryptoPP) +#if !(defined(_MSC_VER) && (_MSC_VER < 1300)) +using std::new_handler; +#endif + typedef void * (_cdecl * PNew)(size_t); typedef void (_cdecl * PDelete)(void *); typedef void (_cdecl * PGetNewAndDelete)(PNew &, PDelete &); -typedef _PNH (_cdecl * PSetNewHandler)(_PNH); +typedef new_handler (_cdecl * PSetNewHandler)(new_handler); typedef void (_cdecl * PSetNewAndDelete)(PNew, PDelete, PSetNewHandler); CRYPTOPP_DLL void DoDllPowerUpSelfTest(); diff --git a/dlltest.cpp b/dlltest.cpp index eb11feb4..5d36df9e 100644 --- a/dlltest.cpp +++ b/dlltest.cpp @@ -25,10 +25,10 @@ void FIPS140_SampleApplication() try { // trying to use a crypto algorithm after power-up self test error will result in an exception - DES::Encryption des; + AES::Encryption aes; // should not be here - cerr << "Use of DES failed to cause an exception after power-up self test error.\n"; + cerr << "Use of AES failed to cause an exception after power-up self test error.\n"; abort(); } catch (SelfTestFailure &e) @@ -47,7 +47,7 @@ void FIPS140_SampleApplication() cout << "2. Re-do power-up self test passed.\n"; // encrypt and decrypt - const byte key[] = {0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef}; + const byte key[] = {0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef, 0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef, 0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef}; const byte iv[] = {0x12,0x34,0x56,0x78,0x90,0xab,0xcd,0xef}; const byte plaintext[] = { // "Now is the time for all " without tailing 0 0x4e,0x6f,0x77,0x20,0x69,0x73,0x20,0x74, @@ -56,20 +56,20 @@ void FIPS140_SampleApplication() byte ciphertext[24]; byte decrypted[24]; - CFB_Mode::Encryption encryption_DES_CBC; - encryption_DES_CBC.SetKeyWithIV(key, 8, iv); - encryption_DES_CBC.ProcessString(ciphertext, plaintext, 24); + CFB_Mode::Encryption encryption_DES_EDE3_CBC; + encryption_DES_EDE3_CBC.SetKeyWithIV(key, sizeof(key), iv); + encryption_DES_EDE3_CBC.ProcessString(ciphertext, plaintext, 24); - CFB_Mode::Decryption decryption_DES_CBC; - decryption_DES_CBC.SetKeyWithIV(key, 8, iv); - decryption_DES_CBC.ProcessString(decrypted, ciphertext, 24); + CFB_Mode::Decryption decryption_DES_EDE3_CBC; + decryption_DES_EDE3_CBC.SetKeyWithIV(key, sizeof(key), iv); + decryption_DES_EDE3_CBC.ProcessString(decrypted, ciphertext, 24); if (memcmp(plaintext, decrypted, 24) != 0) { - cerr << "DES-CBC Encryption/decryption failed.\n"; + cerr << "DES-EDE3-CBC Encryption/decryption failed.\n"; abort(); } - cout << "3. DES-CBC Encryption/decryption succeeded.\n"; + cout << "3. DES-EDE3-CBC Encryption/decryption succeeded.\n"; // hash const byte message[] = {'a', 'b', 'c'}; @@ -152,10 +152,10 @@ void FIPS140_SampleApplication() // try to use an invalid key length try { - encryption_DES_CBC.SetKey(key, 5); + encryption_DES_EDE3_CBC.SetKey(key, 5); // should not be here - cerr << "DES implementation did not detect use of invalid key length.\n"; + cerr << "DES-EDE3 implementation did not detect use of invalid key length.\n"; abort(); } catch (InvalidArgument &e) diff --git a/fips140.h b/fips140.h index f46eff69..8d255cf7 100644 --- a/fips140.h +++ b/fips140.h @@ -6,6 +6,7 @@ */ #include "cryptlib.h" +#include "secblock.h" NAMESPACE_BEGIN(CryptoPP) diff --git a/fipstest.cpp b/fipstest.cpp index 70fbb87e..1e094af2 100644 --- a/fipstest.cpp +++ b/fipstest.cpp @@ -5,7 +5,10 @@ #ifndef CRYPTOPP_IMPORTS #include "dll.h" + +#ifdef CRYPTOPP_WIN32_AVAILABLE #include +#endif NAMESPACE_BEGIN(CryptoPP) @@ -334,7 +337,7 @@ void DoPowerUpSelfTest(const char *moduleFilename, const byte *expectedModuleMac "22B590B08B53363AEB89AD65F81A5B6FB83F326CE06BF35751E6C41B43B729C4", // output 1489728269); // time vector - SymmetricEncryptionKnownAnswerTest( +/* SymmetricEncryptionKnownAnswerTest( "0123456789abcdef", // key "1234567890abcdef", // IV "4e6f77206973207468652074696d6520666f7220616c6c20", // plaintext @@ -343,7 +346,7 @@ void DoPowerUpSelfTest(const char *moduleFilename, const byte *expectedModuleMac "F3096249C7F46E51A69E839B1A92F78403467133898EA622", // cfb "f3096249c7f46e5135f24a242eeb3d3f3d6d5be3255af8c3", // ofb "F3096249C7F46E51163A8CA0FFC94C27FA2F80F480B86F75");// ctr - +*/ SymmetricEncryptionKnownAnswerTest( "385D7189A5C3D485E1370AA5D408082B5CCCCB5E19F2D90E", "C141B5FCCD28DC8A", @@ -388,7 +391,7 @@ void DoPowerUpSelfTest(const char *moduleFilename, const byte *expectedModuleMac SecureHashKnownAnswerTest( "abc", "A9993E364706816ABA3E25717850C26C9CD0D89D"); - +/* SecureHashKnownAnswerTest( "abc", "ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad"); @@ -400,12 +403,12 @@ void DoPowerUpSelfTest(const char *moduleFilename, const byte *expectedModuleMac SecureHashKnownAnswerTest( "abc", "ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f"); - +*/ MAC_KnownAnswerTest >( "303132333435363738393a3b3c3d3e3f40414243", "Sample #2", "0922d3405faa3d194f82a45830737d5cc6c75d24"); - +/* MAC_KnownAnswerTest >( "303132333435363738393a3b3c3d3e3f40414243", "abc", @@ -420,7 +423,7 @@ void DoPowerUpSelfTest(const char *moduleFilename, const byte *expectedModuleMac "303132333435363738393a3b3c3d3e3f40414243", "abc", "BF07864E733B995862F3C2D432C7FF2F5EB073FFFC4F880CD94D5D21086476B7428F27BE694A9D9CB3BB500FE1255852BAFCBAF4042390B3706CDF02421B51AC"); - +*/ SignatureKnownAnswerTest >( "30820150020100300d06092a864886f70d01010105000482013a3082013602010002400a66791dc6988168de7ab77419bb7fb0" "c001c62710270075142942e19a8d8c51d053b3e3782a1de5dc5af4ebe99468170114a1dfe67cdc9a9af55d655620bbab0203010001" diff --git a/iterhash.cpp b/iterhash.cpp index 7e1187f4..33dc9249 100644 --- a/iterhash.cpp +++ b/iterhash.cpp @@ -1,9 +1,6 @@ // iterhash.cpp - written and placed in the public domain by Wei Dai #include "pch.h" - -#ifndef CRYPTOPP_IMPORTS - #include "iterhash.h" #include "misc.h" @@ -108,5 +105,3 @@ template void IteratedHashBase::Restart() } NAMESPACE_END - -#endif diff --git a/iterhash.h b/iterhash.h index 0911feeb..5adecd3c 100644 --- a/iterhash.h +++ b/iterhash.h @@ -41,12 +41,12 @@ private: }; #ifdef WORD64_AVAILABLE -CRYPTOPP_DLL_TEMPLATE_CLASS IteratedHashBase; -CRYPTOPP_DLL_TEMPLATE_CLASS IteratedHashBase; +CRYPTOPP_STATIC_TEMPLATE_CLASS IteratedHashBase; +CRYPTOPP_STATIC_TEMPLATE_CLASS IteratedHashBase; #endif CRYPTOPP_DLL_TEMPLATE_CLASS IteratedHashBase; -CRYPTOPP_DLL_TEMPLATE_CLASS IteratedHashBase; +CRYPTOPP_STATIC_TEMPLATE_CLASS IteratedHashBase; //! . template diff --git a/sha.cpp b/sha.cpp index 4eaae566..a570fb79 100644 --- a/sha.cpp +++ b/sha.cpp @@ -4,9 +4,6 @@ // Both are in the public domain. #include "pch.h" - -#ifndef CRYPTOPP_IMPORTS - #include "sha.h" #include "misc.h" @@ -17,6 +14,8 @@ NAMESPACE_BEGIN(CryptoPP) #define blk0(i) (W[i] = data[i]) #define blk1(i) (W[i&15] = rotlFixed(W[(i+13)&15]^W[(i+8)&15]^W[(i+2)&15]^W[i&15],1)) +#ifndef CRYPTOPP_IMPORTS + void SHA::InitState(HashWordType *state) { state[0] = 0x67452301L; @@ -79,6 +78,8 @@ void SHA::Transform(word32 *state, const word32 *data) memset(W, 0, sizeof(W)); } +#endif // #ifndef CRYPTOPP_IMPORTS + // end of Steve Reid's code // ************************************************************* @@ -278,5 +279,3 @@ void SHA384::InitState(HashWordType *state) #endif NAMESPACE_END - -#endif diff --git a/sha.h b/sha.h index f7936761..efe5350e 100644 --- a/sha.h +++ b/sha.h @@ -17,7 +17,7 @@ public: typedef SHA SHA1; //! implements the SHA-256 standard -class CRYPTOPP_DLL SHA256 : public IteratedHashWithStaticTransform +class SHA256 : public IteratedHashWithStaticTransform { public: static void InitState(HashWordType *state); @@ -31,7 +31,7 @@ protected: #ifdef WORD64_AVAILABLE //! implements the SHA-512 standard -class CRYPTOPP_DLL SHA512 : public IteratedHashWithStaticTransform +class SHA512 : public IteratedHashWithStaticTransform { public: static void InitState(HashWordType *state); @@ -43,7 +43,7 @@ protected: }; //! implements the SHA-384 standard -class CRYPTOPP_DLL SHA384 : public IteratedHashWithStaticTransform +class SHA384 : public IteratedHashWithStaticTransform { public: static void InitState(HashWordType *state); diff --git a/test.cpp b/test.cpp index 2aea6077..48e78cd8 100644 --- a/test.cpp +++ b/test.cpp @@ -2,23 +2,15 @@ #include "dll.h" #include "md5.h" -#include "sha.h" #include "ripemd.h" -#include "files.h" #include "rng.h" -#include "hex.h" #include "gzip.h" #include "default.h" -#include "rsa.h" #include "randpool.h" #include "ida.h" #include "base64.h" #include "socketft.h" -#include "dsa.h" -#include "rsa.h" -#include "osrng.h" #include "wait.h" -#include "fips140.h" #include "factory.h" #include "validate.h" @@ -118,10 +110,8 @@ int main(int argc, char *argv[]) else command = argv[1]; - switch (command[0]) + if (command == "g") { - case 'g': - { char seed[1024], privFilename[128], pubFilename[128]; unsigned int keyLength; @@ -139,103 +129,89 @@ int main(int argc, char *argv[]) cin.getline(seed, 1024); GenerateRSAKey(keyLength, privFilename, pubFilename, seed); - return 0; - } - case 'r': - { - switch (argv[1][1]) + } + else if (command == "rs") + RSASignFile(argv[2], argv[3], argv[4]); + else if (command == "rv") + { + bool verified = RSAVerifyFile(argv[2], argv[3], argv[4]); + cout << (verified ? "valid signature" : "invalid signature") << endl; + } + else if (command == "r") + { + char privFilename[128], pubFilename[128]; + char seed[1024], message[1024]; + + cout << "Private key file: "; + cin >> privFilename; + + cout << "\nPublic key file: "; + cin >> pubFilename; + + cout << "\nRandom Seed: "; + ws(cin); + cin.getline(seed, 1024); + + cout << "\nMessage: "; + cin.getline(message, 1024); + + string ciphertext = RSAEncryptString(pubFilename, seed, message); + cout << "\nCiphertext: " << ciphertext << endl; + + string decrypted = RSADecryptString(privFilename, ciphertext.c_str()); + cout << "\nDecrypted: " << decrypted << endl; + } + else if (command == "mt") + { + MaurerRandomnessTest mt; + FileStore fs(argv[2]); + fs.TransferAllTo(mt); + cout << "Maurer Test Value: " << mt.GetTestValue() << endl; + } +#ifdef CRYPTOPP_WIN32_AVAILABLE + 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"); + + PowerUpSelfTestStatus status = pGetPowerUpSelfTestStatus(); + if (status == POWER_UP_SELF_TEST_PASSED) { - case 's': - RSASignFile(argv[2], argv[3], argv[4]); + cout << "Crypto++ DLL MAC is valid. Nothing to do.\n"; return 0; - case 'v': - { - bool verified = RSAVerifyFile(argv[2], argv[3], argv[4]); - cout << (verified ? "valid signature" : "invalid signature") << endl; - return 0; - } - default: - { - char privFilename[128], pubFilename[128]; - char seed[1024], message[1024]; - - cout << "Private key file: "; - cin >> privFilename; - - cout << "\nPublic key file: "; - cin >> pubFilename; - - cout << "\nRandom Seed: "; - ws(cin); - cin.getline(seed, 1024); - - cout << "\nMessage: "; - cin.getline(message, 1024); - - string ciphertext = RSAEncryptString(pubFilename, seed, message); - cout << "\nCiphertext: " << ciphertext << endl; - - string decrypted = RSADecryptString(privFilename, ciphertext.c_str()); - cout << "\nDecrypted: " << decrypted << endl; - - return 0; - } } - } - case 'm': - 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"); - PowerUpSelfTestStatus status = pGetPowerUpSelfTestStatus(); - if (status == POWER_UP_SELF_TEST_PASSED) - { - cout << "Crypto++ DLL MAC is valid. Nothing to do.\n"; - return 0; - } - - unsigned int macSize, macFileLocation; - const byte *pMac = pGetActualMacAndLocation(macSize, macFileLocation); - - if (macFileLocation == 0) - { - cerr << "Could not find MAC location in Crypto++ DLL.\n"; - return 1; - } - else - { - SecByteBlock mac(pMac, macSize); // copy MAC before freeing the DLL - BOOL r = FreeLibrary(hModule); - cout << "Placing MAC in file " << argv[2] << ", location " << macFileLocation << ".\n"; - std::ofstream dllFile(argv[2], ios::in | ios::out | ios::binary); - dllFile.seekp(macFileLocation); - dllFile.write((const char *)mac.data(), macSize); - if (!dllFile.good()) - { - cerr << "Error writing file.\n"; - return 1; - } - return 0; - } - } - else if (command == "mt") + unsigned int macSize, macFileLocation; + const byte *pMac = pGetActualMacAndLocation(macSize, macFileLocation); + + if (macFileLocation == 0) { - MaurerRandomnessTest mt; - FileStore fs(argv[2]); - fs.TransferAllTo(mt); - cout << "Maurer Test Value: " << mt.GetTestValue() << endl; + cerr << "Could not find MAC location in Crypto++ DLL.\n"; + return 1; } else - DigestFile(argv[2]); - return 0; - case 't': - { - if (command == "tv") { - return !RunTestDataFile(argv[2]); + SecByteBlock mac(pMac, macSize); // copy MAC before freeing the DLL + BOOL r = FreeLibrary(hModule); + cout << "Placing MAC in file " << argv[2] << ", location " << macFileLocation << ".\n"; + std::ofstream dllFile(argv[2], ios::in | ios::out | ios::binary); + dllFile.seekp(macFileLocation); + dllFile.write((const char *)mac.data(), macSize); + if (!dllFile.good()) + { + cerr << "Error writing file.\n"; + return 1; + } } + } +#endif + else if (command == "m") + DigestFile(argv[2]); + else if (command == "tv") + return !RunTestDataFile(argv[2]); + else if (command == "t") + { // VC60 workaround: use char array instead of std::string to workaround MSVC's getline bug char passPhrase[MAX_PHRASE_LENGTH], plaintext[1024]; @@ -252,84 +228,81 @@ int main(int argc, char *argv[]) cout << "\nDecrypted: " << decrypted << endl; return 0; - } - case 'e': - case 'd': - if (command == "e64") - Base64Encode(argv[2], argv[3]); - else if (command == "d64") - Base64Decode(argv[2], argv[3]); - else if (command == "e16") - HexEncode(argv[2], argv[3]); - else if (command == "d16") - HexDecode(argv[2], argv[3]); + } + else if (command == "e64") + Base64Encode(argv[2], argv[3]); + else if (command == "d64") + Base64Decode(argv[2], argv[3]); + else if (command == "e16") + HexEncode(argv[2], argv[3]); + else if (command == "d16") + HexDecode(argv[2], argv[3]); + else if (command == "e" || command == "d") + { + char passPhrase[MAX_PHRASE_LENGTH]; + cout << "Passphrase: "; + cin.getline(passPhrase, MAX_PHRASE_LENGTH); + if (command == "e") + EncryptFile(argv[2], argv[3], passPhrase); else - { - char passPhrase[MAX_PHRASE_LENGTH]; - cout << "Passphrase: "; - cin.getline(passPhrase, MAX_PHRASE_LENGTH); - if (command == "e") - EncryptFile(argv[2], argv[3], passPhrase); - else - DecryptFile(argv[2], argv[3], passPhrase); - } - return 0; - case 's': - if (argv[1][1] == 's') - { - char seed[1024]; - cout << "\nRandom Seed: "; - ws(cin); - cin.getline(seed, 1024); - SecretShareFile(atoi(argv[2]), atoi(argv[3]), argv[4], seed); - } - else - SecretRecoverFile(argc-3, argv[2], argv+3); - return 0; - case 'i': - if (argv[1][1] == 'd') - InformationDisperseFile(atoi(argv[2]), atoi(argv[3]), argv[4]); - else - InformationRecoverFile(argc-3, argv[2], argv+3); - return 0; - case 'v': + DecryptFile(argv[2], argv[3], passPhrase); + } + else if (command == "ss") + { + char seed[1024]; + cout << "\nRandom Seed: "; + ws(cin); + cin.getline(seed, 1024); + SecretShareFile(atoi(argv[2]), atoi(argv[3]), argv[4], seed); + } + else if (command == "sr") + SecretRecoverFile(argc-3, argv[2], argv+3); + else if (command == "id") + InformationDisperseFile(atoi(argv[2]), atoi(argv[3]), argv[4]); + else if (command == "ir") + InformationRecoverFile(argc-3, argv[2], argv+3); + else if (command == "v") return !Validate(argc>2 ? atoi(argv[2]) : 0, argv[1][1] == 'v', argc>3 ? argv[3] : NULL); - case 'b': + else if (command == "b") + { if (argc<3) BenchMarkAll(); else BenchMarkAll((float)atof(argv[2])); - return 0; - case 'z': + } + else if (command == "z") GzipFile(argv[3], argv[4], argv[2][0]-'0'); - return 0; - case 'u': + else if (command == "u") GunzipFile(argv[2], argv[3]); - return 0; - case 'f': - if (command == "fips") - FIPS140_SampleApplication(); - else if (command == "fips-rand") - FIPS140_GenerateRandomFiles(); - else if (command == "ft") - ForwardTcpPort(argv[2], argv[3], argv[4]); - return 0; - case 'a': + else if (command == "fips") + FIPS140_SampleApplication(); + else if (command == "fips-rand") + FIPS140_GenerateRandomFiles(); + else if (command == "ft") + ForwardTcpPort(argv[2], argv[3], argv[4]); + else if (command == "a") + { if (AdhocTest) return (*AdhocTest)(argc, argv); else - return 0; - case 'h': - if (command == "hmac") { - HmacFile(argv[2], argv[3]); - return 0; + cerr << "AdhocTest not defined.\n"; + return 1; } - // fall through - default: + } + else if (command == "hmac") + HmacFile(argv[2], argv[3]); + else if (command == "h") + { FileSource usage("usage.dat", true, new FileSink(cout)); return 1; } + else + { + cerr << "Unrecognized command.\n"; + return 1; + } + return 0; } catch(CryptoPP::Exception &e) {