summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorweidai <weidai@57ff6487-cd31-0410-9ec3-f628ee90f5f0>2002-12-06 22:02:46 +0000
committerweidai <weidai@57ff6487-cd31-0410-9ec3-f628ee90f5f0>2002-12-06 22:02:46 +0000
commita3f0af934e387ba259919f0b72b42120eef3bc5c (patch)
treedf9cff822523331cad30742ddb34056544c7a80d
parentf8840dc745d13414205c944b2ffc0796837340f5 (diff)
downloadcryptopp-a3f0af934e387ba259919f0b72b42120eef3bc5c.tar.gz
add script-driven testing
git-svn-id: svn://svn.code.sf.net/p/cryptopp/code/trunk/c5@24 57ff6487-cd31-0410-9ec3-f628ee90f5f0
-rw-r--r--GNUmakefile15
-rw-r--r--adhoc.cpp.proto8
-rw-r--r--cryptest.dsp69
-rw-r--r--datatest.cpp434
-rw-r--r--factory.h90
-rw-r--r--regtest.cpp34
-rw-r--r--secblock.h9
-rw-r--r--strciphr.cpp2
-rw-r--r--test.cpp15
9 files changed, 671 insertions, 5 deletions
diff --git a/GNUmakefile b/GNUmakefile
index 4308679..375e531 100644
--- a/GNUmakefile
+++ b/GNUmakefile
@@ -1,6 +1,9 @@
# can't use -fno-rtti yet because it causes problems with exception handling in GCC 2.95.2
CXXFLAGS = -g
-# uncomment the next two lines to do a release build
+# Uncomment the next two lines to do a release build.
+# Note that you must define NDEBUG for your own application if you define it for Crypto++.
+# Also, make sure you run the validation tests and test your own program thoroughly
+# after turning on -O2. The GCC optimizer may have bugs that cause it to generate incorrect code.
# CXXFLAGS = -O2 -DNDEBUG -ffunction-sections -fdata-sections
# LDFLAGS = -Wl,--gc-sections
ARFLAGS = -cr # ar needs the dash on OpenBSD
@@ -29,14 +32,13 @@ CXX = g++
endif
SRCS = $(wildcard *.cpp)
-
ifeq ($(SRCS),) # workaround wildcard function bug in GNU Make 3.77
SRCS = $(shell ls *.cpp)
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
+TESTOBJS = bench.o test.o validat1.o validat2.o validat3.o adhoc.o datatest.o regtest.o
LIBOBJS = $(filter-out $(TESTOBJS),$(OBJS))
all: cryptest.exe
@@ -54,6 +56,13 @@ cryptest.exe: libcryptopp.a $(TESTOBJS)
nolib: $(OBJS) # makes it faster to test changes
$(CXX) -o ct $(CXXFLAGS) $(OBJS) $(LDFLAGS) $(LDLIBS)
+adhoc.cpp: adhoc.cpp.proto
+ifeq ($(wildcard adhoc.cpp),)
+ cp adhoc.cpp.proto adhoc.cpp
+else
+ touch adhoc.cpp
+endif
+
.SUFFIXES: .cpp
.cpp.o:
diff --git a/adhoc.cpp.proto b/adhoc.cpp.proto
new file mode 100644
index 0000000..8e7f9c2
--- /dev/null
+++ b/adhoc.cpp.proto
@@ -0,0 +1,8 @@
+extern int (*AdhocTest)(int argc, char *argv[]);
+
+int MyAdhocTest(int argc, char *argv[])
+{
+ return 0;
+}
+
+static int s_i = (AdhocTest = &MyAdhocTest, 0);
diff --git a/cryptest.dsp b/cryptest.dsp
index 515e1a5..3f53678 100644
--- a/cryptest.dsp
+++ b/cryptest.dsp
@@ -1,5 +1,5 @@
# Microsoft Developer Studio Project File - Name="cryptest" - Package Owner=<4>
-# Microsoft Developer Studio Generated Build File, Format Version 60000
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
# ** DO NOT EDIT **
# TARGTYPE "Win32 (x86) Console Application" 0x0103
@@ -369,6 +369,61 @@ SOURCE=.\xtrdh342.dat
# PROP Default_Filter ".cpp;.h"
# Begin Source File
+SOURCE=.\adhoc.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\adhoc.cpp.proto
+
+!IF "$(CFG)" == "cryptest - Win32 FIPS 140 Release"
+
+# Begin Custom Build
+InputPath=.\adhoc.cpp.proto
+
+"adhoc.cpp" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ if exist adhoc.cpp touch adhoc.cpp
+ if not exist adhoc.cpp copy $(InputPath) adhoc.cpp
+
+# End Custom Build
+
+!ELSEIF "$(CFG)" == "cryptest - Win32 FIPS 140 Debug"
+
+# Begin Custom Build
+InputPath=.\adhoc.cpp.proto
+
+"adhoc.cpp" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ if exist adhoc.cpp touch adhoc.cpp
+ if not exist adhoc.cpp copy $(InputPath) adhoc.cpp
+
+# End Custom Build
+
+!ELSEIF "$(CFG)" == "cryptest - Win32 Release"
+
+# Begin Custom Build
+InputPath=.\adhoc.cpp.proto
+
+"adhoc.cpp" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ if exist adhoc.cpp touch adhoc.cpp
+ if not exist adhoc.cpp copy $(InputPath) adhoc.cpp
+
+# End Custom Build
+
+!ELSEIF "$(CFG)" == "cryptest - Win32 Debug"
+
+# Begin Custom Build
+InputPath=.\adhoc.cpp.proto
+
+"adhoc.cpp" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ if exist adhoc.cpp touch adhoc.cpp
+ if not exist adhoc.cpp copy $(InputPath) adhoc.cpp
+
+# End Custom Build
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
SOURCE=.\bench.cpp
# End Source File
# Begin Source File
@@ -377,6 +432,18 @@ SOURCE=.\bench.h
# End Source File
# Begin Source File
+SOURCE=.\datatest.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\factory.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\regtest.cpp
+# End Source File
+# Begin Source File
+
SOURCE=.\test.cpp
# End Source File
# Begin Source File
diff --git a/datatest.cpp b/datatest.cpp
new file mode 100644
index 0000000..1be7d89
--- /dev/null
+++ b/datatest.cpp
@@ -0,0 +1,434 @@
+#include "factory.h"
+#include "integer.h"
+#include "filters.h"
+#include "hex.h"
+#include "randpool.h"
+#include "files.h"
+#include "trunhash.h"
+#include <iostream>
+#include <memory>
+
+USING_NAMESPACE(CryptoPP)
+USING_NAMESPACE(std)
+
+RandomPool & GlobalRNG();
+void RegisterFactories();
+
+typedef std::map<std::string, std::string> TestData;
+
+class TestFailure : public Exception
+{
+public:
+ TestFailure() : Exception(OTHER_ERROR, "Validation test failed") {}
+};
+
+static const TestData *s_currentTestData = NULL;
+
+void OutputTestData(const TestData &v)
+{
+ for (TestData::const_iterator i = v.begin(); i != v.end(); ++i)
+ {
+ cerr << i->first << ": " << i->second << endl;
+ }
+}
+
+void SignalTestFailure()
+{
+ OutputTestData(*s_currentTestData);
+ throw TestFailure();
+}
+
+void SignalTestError()
+{
+ OutputTestData(*s_currentTestData);
+ throw Exception(Exception::OTHER_ERROR, "Unexpected error during validation test");
+}
+
+class TestDataNameValuePairs : public NameValuePairs
+{
+public:
+ TestDataNameValuePairs(const TestData &data) : m_data(data) {}
+
+ virtual bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const
+ {
+ TestData::const_iterator i = m_data.find(name);
+ if (i == m_data.end())
+ return false;
+
+ const std::string &value = i->second;
+
+ if (valueType == typeid(int))
+ *reinterpret_cast<int *>(pValue) = atoi(value.c_str());
+ else if (valueType == typeid(Integer))
+ *reinterpret_cast<Integer *>(pValue) = Integer((std::string(value) + "h").c_str());
+ else
+ throw ValueTypeMismatch(name, typeid(std::string), valueType);
+
+ return true;
+ }
+
+private:
+ const TestData &m_data;
+};
+
+const std::string & GetRequiredDatum(const TestData &data, const char *name)
+{
+ TestData::const_iterator i = data.find(name);
+ if (i == data.end())
+ SignalTestError();
+ return i->second;
+}
+
+void PutDecodedDatumInto(const TestData &data, const char *name, BufferedTransformation &target)
+{
+ std::string s1 = GetRequiredDatum(data, name), s2;
+
+ int repeat = 1;
+ if (s1[0] == 'r')
+ {
+ repeat = atoi(s1.c_str()+1);
+ s1 = s1.substr(s1.find(' ')+1);
+ }
+
+ if (s1[0] == '\"')
+ s2 = s1.substr(1, s1.find('\"', 1)-1);
+ else if (s1.substr(0, 2) == "0x")
+ StringSource(s1.substr(2), true, new HexDecoder(new StringSink(s2)));
+ else
+ StringSource(s1, true, new HexDecoder(new StringSink(s2)));
+
+ while (repeat--)
+ target.Put((const byte *)s2.data(), s2.size());
+}
+
+std::string GetDecodedDatum(const TestData &data, const char *name)
+{
+ std::string s;
+ PutDecodedDatumInto(data, name, StringSink(s).Ref());
+ return s;
+}
+
+void TestKeyPairValidAndConsistent(CryptoMaterial &pub, const CryptoMaterial &priv)
+{
+ if (!pub.Validate(GlobalRNG(), 3))
+ SignalTestFailure();
+ if (!priv.Validate(GlobalRNG(), 3))
+ SignalTestFailure();
+
+/* EqualityComparisonFilter comparison;
+ pub.Save(ChannelSwitch(comparison, "0"));
+ pub.AssignFrom(priv);
+ pub.Save(ChannelSwitch(comparison, "1"));
+ comparison.ChannelMessageSeriesEnd("0");
+ comparison.ChannelMessageSeriesEnd("1");
+*/
+}
+
+void TestSignatureScheme(TestData &v)
+{
+ std::string name = GetRequiredDatum(v, "Name");
+ std::string test = GetRequiredDatum(v, "Test");
+
+ std::auto_ptr<PK_Signer> signer(ObjectFactoryRegistry<PK_Signer>::Registry().CreateObject(name.c_str()));
+ std::auto_ptr<PK_Verifier> verifier(ObjectFactoryRegistry<PK_Verifier>::Registry().CreateObject(name.c_str()));
+
+ TestDataNameValuePairs pairs(v);
+ std::string keyFormat = GetRequiredDatum(v, "KeyFormat");
+
+ if (keyFormat == "DER")
+ verifier->AccessMaterial().Load(StringStore(GetDecodedDatum(v, "PublicKey")).Ref());
+ else if (keyFormat == "Component")
+ verifier->AccessMaterial().AssignFrom(pairs);
+
+ if (test == "Verify" || test == "NotVerify")
+ {
+ VerifierFilter verifierFilter(*verifier, NULL, VerifierFilter::SIGNATURE_AT_BEGIN);
+ PutDecodedDatumInto(v, "Signature", verifierFilter);
+ PutDecodedDatumInto(v, "Message", verifierFilter);
+ verifierFilter.MessageEnd();
+ if (verifierFilter.GetLastResult() == (test == "NotVerify"))
+ SignalTestFailure();
+ }
+ else if (test == "PublicKeyValid")
+ {
+ if (!verifier->GetMaterial().Validate(GlobalRNG(), 3))
+ SignalTestFailure();
+ }
+ else
+ goto privateKeyTests;
+
+ return;
+
+privateKeyTests:
+ if (keyFormat == "DER")
+ signer->AccessMaterial().Load(StringStore(GetDecodedDatum(v, "PrivateKey")).Ref());
+ else if (keyFormat == "Component")
+ signer->AccessMaterial().AssignFrom(pairs);
+
+ if (test == "KeyPairValidAndConsistent")
+ {
+ TestKeyPairValidAndConsistent(verifier->AccessMaterial(), signer->GetMaterial());
+ }
+ else if (test == "Sign")
+ {
+ SignerFilter f(GlobalRNG(), *signer, new HexEncoder(new FileSink(cout)));
+ StringSource ss(GetDecodedDatum(v, "Message"), true, new Redirector(f));
+ SignalTestFailure();
+ }
+ else if (test == "DeterministicSign")
+ {
+ SignalTestError();
+ assert(false); // TODO: implement
+ }
+ else if (test == "RandomSign")
+ {
+ SignalTestError();
+ assert(false); // TODO: implement
+ }
+ else if (test == "GenerateKey")
+ {
+ SignalTestError();
+ assert(false);
+ }
+ else
+ {
+ SignalTestError();
+ assert(false);
+ }
+}
+
+void TestEncryptionScheme(TestData &v)
+{
+ std::string name = GetRequiredDatum(v, "Name");
+ std::string test = GetRequiredDatum(v, "Test");
+
+ std::auto_ptr<PK_Encryptor> encryptor(ObjectFactoryRegistry<PK_Encryptor>::Registry().CreateObject(name.c_str()));
+ std::auto_ptr<PK_Decryptor> decryptor(ObjectFactoryRegistry<PK_Decryptor>::Registry().CreateObject(name.c_str()));
+
+ std::string keyFormat = GetRequiredDatum(v, "KeyFormat");
+
+ if (keyFormat == "DER")
+ {
+ decryptor->AccessMaterial().Load(StringStore(GetDecodedDatum(v, "PrivateKey")).Ref());
+ encryptor->AccessMaterial().Load(StringStore(GetDecodedDatum(v, "PublicKey")).Ref());
+ }
+ else if (keyFormat == "Component")
+ {
+ TestDataNameValuePairs pairs(v);
+ decryptor->AccessMaterial().AssignFrom(pairs);
+ encryptor->AccessMaterial().AssignFrom(pairs);
+ }
+
+ if (test == "DecryptMatch")
+ {
+ std::string decrypted, expected = GetDecodedDatum(v, "Plaintext");
+ StringSource ss(GetDecodedDatum(v, "Ciphertext"), true, new PK_DecryptorFilter(*decryptor, new StringSink(decrypted)));
+ if (decrypted != expected)
+ SignalTestFailure();
+ }
+ else if (test == "KeyPairValidAndConsistent")
+ {
+ TestKeyPairValidAndConsistent(encryptor->AccessMaterial(), decryptor->GetMaterial());
+ }
+ else
+ {
+ SignalTestError();
+ assert(false);
+ }
+}
+
+void TestDigestOrMAC(TestData &v, bool testDigest)
+{
+ std::string name = GetRequiredDatum(v, "Name");
+ std::string test = GetRequiredDatum(v, "Test");
+
+ member_ptr<MessageAuthenticationCode> mac;
+ member_ptr<HashTransformation> hash;
+ HashTransformation *pHash = NULL;
+
+ if (testDigest)
+ {
+ hash.reset(ObjectFactoryRegistry<HashTransformation>::Registry().CreateObject(name.c_str()));
+ pHash = hash.get();
+ }
+ else
+ {
+ mac.reset(ObjectFactoryRegistry<MessageAuthenticationCode>::Registry().CreateObject(name.c_str()));
+ pHash = mac.get();
+ std::string key = GetDecodedDatum(v, "Key");
+ mac->SetKey((const byte *)key.c_str(), key.size());
+ }
+
+ if (test == "Verify" || test == "VerifyTruncated" || test == "NotVerify")
+ {
+ int digestSize = pHash->DigestSize();
+ if (test == "VerifyTruncated")
+ digestSize = atoi(GetRequiredDatum(v, "TruncatedSize").c_str());
+ TruncatedHashModule thash(*pHash, digestSize);
+ HashVerificationFilter verifierFilter(thash, NULL, HashVerificationFilter::HASH_AT_BEGIN);
+ PutDecodedDatumInto(v, "Digest", verifierFilter);
+ PutDecodedDatumInto(v, "Message", verifierFilter);
+ verifierFilter.MessageEnd();
+ if (verifierFilter.GetLastResult() == (test == "NotVerify"))
+ SignalTestFailure();
+ }
+ else
+ {
+ SignalTestError();
+ assert(false);
+ }
+}
+
+bool GetField(std::istream &is, std::string &name, std::string &value)
+{
+ is >> name;
+ if (name.empty())
+ return false;
+
+ if (name[name.size()-1] != ':')
+ SignalTestError();
+ name.erase(name.size()-1);
+
+ while (is.peek() == ' ')
+ is.ignore(1);
+
+ // VC60 workaround: getline bug
+ char buffer[4];
+ value.resize(0);
+ bool continueLine;
+
+ do
+ {
+ do
+ {
+ is.get(buffer, sizeof(buffer));
+ value += buffer;
+ }
+ while (buffer[0] != 0);
+ is.clear();
+ is.ignore();
+
+ if (value[value.size()-1] == '\\')
+ {
+ value.resize(value.size()-1);
+ continueLine = true;
+ }
+ else
+ continueLine = false;
+
+ std::string::size_type i = value.find('#');
+ if (i != std::string::npos)
+ value.erase(i);
+ }
+ while (continueLine);
+
+ return true;
+}
+
+void OutputPair(const NameValuePairs &v, const char *name)
+{
+ Integer x;
+ bool b = v.GetValue(name, x);
+ assert(b);
+ cout << name << ": \\\n ";
+ x.Encode(HexEncoder(new FileSink(cout), false, 64, "\\\n ").Ref(), x.MinEncodedSize());
+ cout << endl;
+}
+
+void OutputNameValuePairs(const NameValuePairs &v)
+{
+ std::string names = v.GetValueNames();
+ string::size_type i = 0;
+ while (i < names.size())
+ {
+ string::size_type j = names.find_first_of (';', i);
+
+ if (j == string::npos)
+ return;
+ else
+ {
+ std::string name = names.substr(i, j-i);
+ if (name.find(':') == string::npos)
+ OutputPair(v, name.c_str());
+ }
+
+ i = j + 1;
+ }
+}
+
+bool RunTestDataFile(const char *filename)
+{
+ RegisterFactories();
+
+ std::ifstream file(filename);
+ TestData v;
+ s_currentTestData = &v;
+ std::string name, value, lastAlgName;
+ unsigned int totalTests = 0, failedTests = 0;
+
+ while (file)
+ {
+ while (file.peek() == '#')
+ file.ignore(INT_MAX, '\n');
+
+ if (file.peek() == '\n')
+ v.clear();
+
+ if (!GetField(file, name, value))
+ break;
+ v[name] = value;
+
+ if (name == "Test")
+ {
+ bool failed = true;
+ std::string algType = GetRequiredDatum(v, "AlgorithmType");
+
+ if (lastAlgName != GetRequiredDatum(v, "Name"))
+ {
+ lastAlgName = GetRequiredDatum(v, "Name");
+ cout << "Testing " << algType.c_str() << " algorithm " << lastAlgName.c_str() << ".\n";
+ }
+
+ try
+ {
+ if (algType == "Signature")
+ TestSignatureScheme(v);
+ else if (algType == "AsymmetricCipher")
+ TestEncryptionScheme(v);
+ else if (algType == "MessageDigest")
+ TestDigestOrMAC(v, true);
+ else if (algType == "MAC")
+ TestDigestOrMAC(v, false);
+ else
+ SignalTestError();
+ failed = false;
+ }
+ catch (TestFailure &)
+ {
+ cout << "\nTest failed.\n";
+ }
+ catch (CryptoPP::Exception &e)
+ {
+ cout << "\nCryptoPP::Exception caught: " << e.what() << endl;
+ }
+ catch (std::exception &e)
+ {
+ cout << "\nstd::exception caught: " << e.what() << endl;
+ }
+
+ if (failed)
+ {
+ cout << "Skipping to next test.\n";
+ failedTests++;
+ }
+ else
+ cout << ".";
+
+ totalTests++;
+ }
+ }
+ cout << "\nTests complete. Total tests = " << totalTests << ". Failed tests = " << failedTests << ".\n";
+ if (failedTests != 0)
+ cout << "SOME TESTS FAILED!\n";
+ return failedTests == 0;
+}
diff --git a/factory.h b/factory.h
new file mode 100644
index 0000000..85d6631
--- /dev/null
+++ b/factory.h
@@ -0,0 +1,90 @@
+#ifndef CRYPTOPP_OBJFACT_H
+#define CRYPTOPP_OBJFACT_H
+
+#include "cryptlib.h"
+#include <map>
+
+NAMESPACE_BEGIN(CryptoPP)
+
+template <class AbstractClass>
+class ObjectFactory
+{
+public:
+ virtual AbstractClass * CreateObject() const =0;
+};
+
+template <class AbstractClass, class ConcreteClass>
+class DefaultObjectFactory : public ObjectFactory<AbstractClass>
+{
+public:
+ AbstractClass * CreateObject() const
+ {
+ return new ConcreteClass;
+ }
+
+};
+
+template <class AbstractClass>
+class ObjectFactoryRegistry
+{
+public:
+ ~ObjectFactoryRegistry()
+ {
+ for (Map::iterator i = m_map.begin(); i != m_map.end(); ++i)
+ {
+ delete i->second;
+ i->second = NULL;
+ }
+ }
+
+ void RegisterFactory(const char *name, ObjectFactory<AbstractClass> *factory)
+ {
+ m_map[name] = factory;
+ }
+
+ const ObjectFactory<AbstractClass> * GetFactory(const char *name) const
+ {
+ Map::const_iterator i = m_map.find(name);
+ return i == m_map.end() ? NULL : i->second;
+ }
+
+ AbstractClass *CreateObject(const char *name) const
+ {
+ const ObjectFactory<AbstractClass> *factory = GetFactory(name);
+ return factory ? factory->CreateObject() : NULL;
+ }
+
+ static ObjectFactoryRegistry<AbstractClass> & Registry()
+ {
+ static ObjectFactoryRegistry<AbstractClass> s_registry;
+ return s_registry;
+ }
+
+private:
+ typedef std::map<std::string, ObjectFactory<AbstractClass> *> Map;
+ Map m_map;
+};
+
+template <class AbstractClass, class ConcreteClass>
+void RegisterDefaultFactoryFor(const char *name, AbstractClass *Dummy1=NULL, ConcreteClass *Dummy2=NULL)
+{
+ ObjectFactoryRegistry<AbstractClass>::Registry().RegisterFactory(name, new DefaultObjectFactory<AbstractClass, ConcreteClass>);
+}
+
+template <class SchemeClass>
+void RegisterPublicKeyCryptoSystemDefaultFactories(const char *name, SchemeClass *dummy=NULL)
+{
+ RegisterDefaultFactoryFor<PK_Encryptor, CPP_TYPENAME SchemeClass::Encryptor>(name);
+ RegisterDefaultFactoryFor<PK_Decryptor, CPP_TYPENAME SchemeClass::Decryptor>(name);
+}
+
+template <class SchemeClass>
+void RegisterSignatureSchemeDefaultFactories(const char *name, SchemeClass *dummy=NULL)
+{
+ RegisterDefaultFactoryFor<PK_Signer, CPP_TYPENAME SchemeClass::Signer>(name);
+ RegisterDefaultFactoryFor<PK_Verifier, CPP_TYPENAME SchemeClass::Verifier>(name);
+}
+
+NAMESPACE_END
+
+#endif
diff --git a/regtest.cpp b/regtest.cpp
new file mode 100644
index 0000000..38d80c2
--- /dev/null
+++ b/regtest.cpp
@@ -0,0 +1,34 @@
+#include "factory.h"
+
+#include "dh.h"
+#include "esign.h"
+#include "md2.h"
+#include "trunhash.h"
+#include "rw.h"
+#include "md5.h"
+#include "rsa.h"
+#include "ripemd.h"
+#include "dsa.h"
+
+USING_NAMESPACE(CryptoPP)
+
+void RegisterFactories()
+{
+ RegisterDefaultFactoryFor<SimpleKeyAgreementDomain, DH>("DH");
+ RegisterDefaultFactoryFor<HashTransformation, SHA1>("SHA-1");
+ RegisterDefaultFactoryFor<HashTransformation, SHA256>("SHA-256");
+ RegisterDefaultFactoryFor<HashTransformation, SHA384>("SHA-384");
+ RegisterDefaultFactoryFor<HashTransformation, SHA512>("SHA-512");
+ RegisterDefaultFactoryFor<MessageAuthenticationCode, HMAC<MD5> >("HMAC(MD5)");
+ RegisterDefaultFactoryFor<MessageAuthenticationCode, HMAC<SHA1> >("HMAC(SHA-1)");
+ RegisterDefaultFactoryFor<MessageAuthenticationCode, HMAC<RIPEMD160> >("HMAC(RIPEMD-160)");
+ RegisterPublicKeyCryptoSystemDefaultFactories<RSAES<OAEP<SHA1> > >("RSA/OAEP-MGF1(SHA-1)");
+ RegisterPublicKeyCryptoSystemDefaultFactories<DLIES<> >("DLIES(NoCofactorMultiplication, KDF2(SHA-1), XOR, HMAC(SHA-1), DHAES)");
+ RegisterSignatureSchemeDefaultFactories<DSA>("DSA(1363)");
+ RegisterSignatureSchemeDefaultFactories<NR<SHA1> >("NR(1363)/EMSA1(SHA-1)");
+ RegisterSignatureSchemeDefaultFactories<GDSA<SHA1> >("DSA-1363/EMSA1(SHA-1)");
+ RegisterSignatureSchemeDefaultFactories<RSASSA<PKCS1v15, MD2> >("RSA/PKCS1-1.5(MD2)");
+ RegisterSignatureSchemeDefaultFactories<RSASSA<PKCS1v15, SHA1> >("RSA/PKCS1-1.5(SHA-1)");
+ RegisterSignatureSchemeDefaultFactories<ESIGN<SHA1> >("ESIGN/EMSA5-MGF1(SHA-1)");
+ RegisterSignatureSchemeDefaultFactories<RWSSA<SHA1> >("RW/EMSA2(SHA-1)");
+}
diff --git a/secblock.h b/secblock.h
index 31997b6..e07c6a2 100644
--- a/secblock.h
+++ b/secblock.h
@@ -371,6 +371,15 @@ inline void swap(CryptoPP::SecBlock<T, A> &a, CryptoPP::SecBlock<T, A> &b)
a.swap(b);
}
+#if defined(_STLPORT_VERSION) && !defined(_STLP_MEMBER_TEMPLATE_CLASSES)
+template <class _Tp1, class _Tp2>
+inline CryptoPP::AllocatorWithCleanup<_Tp2>&
+__stl_alloc_rebind(CryptoPP::AllocatorWithCleanup<_Tp1>& __a, const _Tp2*)
+{
+ return (CryptoPP::AllocatorWithCleanup<_Tp2>&)(__a);
+}
+#endif
+
NAMESPACE_END
#endif
diff --git a/strciphr.cpp b/strciphr.cpp
index 694d158..78e1a3f 100644
--- a/strciphr.cpp
+++ b/strciphr.cpp
@@ -16,7 +16,7 @@ byte AdditiveCipherTemplate<S>::GenerateByte()
m_leftOver = policy.GetBytesPerIteration();
}
- return KeystreamBufferEnd()[-m_leftOver--];
+ return *(KeystreamBufferEnd()-m_leftOver--);
}
template <class S>
diff --git a/test.cpp b/test.cpp
index 77719fe..926d98d 100644
--- a/test.cpp
+++ b/test.cpp
@@ -19,6 +19,7 @@
#include "osrng.h"
#include "wait.h"
#include "fips140.h"
+#include "factory.h"
#include "validate.h"
#include "bench.h"
@@ -78,6 +79,11 @@ void FIPS140_GenerateRandomFiles();
bool Validate(int, bool, const char *);
+void RegisterFactories();
+bool RunTestDataFile(const char *filename);
+
+int (*AdhocTest)(int argc, char *argv[]) = NULL;
+
#ifdef __BCPLUSPLUS__
int cmain(int argc, char *argv[])
#elif defined(_MSC_VER)
@@ -199,6 +205,10 @@ int main(int argc, char *argv[])
return 0;
case 't':
{
+ if (command == "tv")
+ {
+ return !RunTestDataFile(argv[2]);
+ }
// VC60 workaround: use char array instead of std::string to workaround MSVC's getline bug
char passPhrase[MAX_PHRASE_LENGTH], plaintext[1024];
@@ -277,6 +287,11 @@ int main(int argc, char *argv[])
else if (command == "ft")
ForwardTcpPort(argv[2], argv[3], argv[4]);
return 0;
+ case 'a':
+ if (AdhocTest)
+ return (*AdhocTest)(argc, argv);
+ else
+ return 0;
default:
FileSource usage("usage.dat", true, new FileSink(cout));
return 1;