3 #define CRYPTOPP_DEFAULT_NO_DLL
4 #define CRYPTOPP_ENABLE_NAMESPACE_WEAK 1
22 #if (CRYPTOPP_MSC_VERSION >= 1410)
23 # pragma strict_gs_check (on)
26 #if defined(__COVERITY__)
27 extern "C" void __coverity_tainted_data_sanitize__(
void *);
33 typedef std::map<std::string, std::string> TestData;
34 static bool s_thorough =
false;
42 static const TestData *s_currentTestData = NULL;
44 static void OutputTestData(
const TestData &v)
46 for (TestData::const_iterator i = v.begin(); i != v.end(); ++i)
48 cerr << i->first <<
": " << i->second << endl;
52 static void SignalTestFailure()
54 OutputTestData(*s_currentTestData);
58 static void SignalUnknownAlgorithmError(
const std::string& algType)
60 OutputTestData(*s_currentTestData);
64 static void SignalTestError()
66 OutputTestData(*s_currentTestData);
70 bool DataExists(
const TestData &data,
const char *name)
72 TestData::const_iterator i = data.find(name);
73 return (i != data.end());
76 const std::string & GetRequiredDatum(
const TestData &data,
const char *name)
78 TestData::const_iterator i = data.find(name);
91 len = source.
Get(buf+start, len);
98 std::string s1 = GetRequiredDatum(data, name), s2;
113 repeat = atoi(s1.c_str()+1);
114 s1 = s1.substr(s1.find(
' ')+1);
121 s2 = s1.substr(1, s1.find(
'\"', 1)-1);
122 s1 = s1.substr(s2.length() + 2);
124 else if (s1.substr(0, 2) ==
"0x")
127 s1 = s1.substr(
STDMIN(s1.find(
' '), s1.length()));
132 s1 = s1.substr(
STDMIN(s1.find(
' '), s1.length()));
137 q.
Put((
const byte *)s2.data(), s2.size());
138 RandomizedTransfer(q, target,
false);
143 RandomizedTransfer(q, target,
true);
146 std::string GetDecodedDatum(
const TestData &data,
const char *name)
149 PutDecodedDatumInto(data, name,
StringSink(s).Ref());
153 std::string GetOptionalDecodedDatum(
const TestData &data,
const char *name)
156 if (DataExists(data, name))
157 PutDecodedDatumInto(data, name,
StringSink(s).Ref());
166 virtual bool GetVoidValue(
const char *name,
const std::type_info &valueType,
void *pValue)
const
168 TestData::const_iterator i = m_data.find(name);
169 if (i == m_data.end())
171 if (std::string(name) == Name::DigestSize() && valueType ==
typeid(
int))
173 i = m_data.find(
"MAC");
174 if (i == m_data.end())
175 i = m_data.find(
"Digest");
176 if (i == m_data.end())
180 PutDecodedDatumInto(m_data, i->first.c_str(),
StringSink(m_temp).Ref());
181 *
reinterpret_cast<int *
>(pValue) = (
int)m_temp.size();
188 const std::string &value = i->second;
190 if (valueType ==
typeid(
int))
191 *
reinterpret_cast<int *
>(pValue) = atoi(value.c_str());
192 else if (valueType ==
typeid(
Integer))
193 *
reinterpret_cast<Integer *
>(pValue) =
Integer((std::string(value) +
"h").c_str());
197 PutDecodedDatumInto(m_data, name,
StringSink(m_temp).Ref());
198 reinterpret_cast<ConstByteArrayParameter *
>(pValue)->Assign((
const byte *)m_temp.data(), m_temp.size(),
false);
207 const TestData &m_data;
208 mutable std::string m_temp;
214 if (!pub.
Validate(GlobalRNG(), 2U+!!s_thorough))
216 if (!priv.
Validate(GlobalRNG(), 2U+!!s_thorough))
227 void TestSignatureScheme(TestData &v)
229 std::string name = GetRequiredDatum(v,
"Name");
230 std::string test = GetRequiredDatum(v,
"Test");
237 if (test ==
"GenerateKey")
239 signer->AccessPrivateKey().GenerateRandom(GlobalRNG(), pairs);
240 verifier->AccessPublicKey().AssignFrom(signer->AccessPrivateKey());
244 std::string keyFormat = GetRequiredDatum(v,
"KeyFormat");
246 if (keyFormat ==
"DER")
247 verifier->AccessMaterial().Load(
StringStore(GetDecodedDatum(v,
"PublicKey")).Ref());
248 else if (keyFormat ==
"Component")
249 verifier->AccessMaterial().AssignFrom(pairs);
251 if (test ==
"Verify" || test ==
"NotVerify")
254 PutDecodedDatumInto(v,
"Signature", verifierFilter);
255 PutDecodedDatumInto(v,
"Message", verifierFilter);
256 verifierFilter.MessageEnd();
257 if (verifierFilter.GetLastResult() == (test ==
"NotVerify"))
261 else if (test ==
"PublicKeyValid")
263 if (!verifier->GetMaterial().Validate(GlobalRNG(), 3))
268 if (keyFormat ==
"DER")
269 signer->AccessMaterial().Load(
StringStore(GetDecodedDatum(v,
"PrivateKey")).Ref());
270 else if (keyFormat ==
"Component")
271 signer->AccessMaterial().AssignFrom(pairs);
274 if (test ==
"GenerateKey" || test ==
"KeyPairValidAndConsistent")
276 TestKeyPairValidAndConsistent(verifier->AccessMaterial(), signer->GetMaterial());
278 verifierFilter.Put((
const byte *)
"abc", 3);
281 else if (test ==
"Sign")
287 else if (test ==
"DeterministicSign")
296 if (GetDecodedDatum(v,
"Signature") != signature)
300 else if (test ==
"RandomSign")
312 void TestAsymmetricCipher(TestData &v)
314 std::string name = GetRequiredDatum(v,
"Name");
315 std::string test = GetRequiredDatum(v,
"Test");
320 std::string keyFormat = GetRequiredDatum(v,
"KeyFormat");
322 if (keyFormat ==
"DER")
324 decryptor->AccessMaterial().Load(
StringStore(GetDecodedDatum(v,
"PrivateKey")).Ref());
325 encryptor->AccessMaterial().Load(
StringStore(GetDecodedDatum(v,
"PublicKey")).Ref());
327 else if (keyFormat ==
"Component")
330 decryptor->AccessMaterial().AssignFrom(pairs);
331 encryptor->AccessMaterial().AssignFrom(pairs);
334 if (test ==
"DecryptMatch")
336 std::string decrypted, expected = GetDecodedDatum(v,
"Plaintext");
338 if (decrypted != expected)
341 else if (test ==
"KeyPairValidAndConsistent")
343 TestKeyPairValidAndConsistent(encryptor->AccessMaterial(), decryptor->GetMaterial());
352 void TestSymmetricCipher(TestData &v,
const NameValuePairs &overrideParameters)
354 std::string name = GetRequiredDatum(v,
"Name");
355 std::string test = GetRequiredDatum(v,
"Test");
357 std::string key = GetDecodedDatum(v,
"Key");
358 std::string plaintext = GetDecodedDatum(v,
"Plaintext");
363 if (test ==
"Encrypt" || test ==
"EncryptXorDigest" || test ==
"Resync" || test ==
"EncryptionMCT" || test ==
"DecryptionMCT")
366 static std::string lastName;
368 if (name != lastName)
376 if (pairs.GetValue(Name::IV(), iv) && iv.
size() != encryptor->
IVSize())
379 if (test ==
"Resync")
386 encryptor->
SetKey((
const byte *)key.data(), key.size(), pairs);
387 decryptor->
SetKey((
const byte *)key.data(), key.size(), pairs);
390 int seek = pairs.GetIntValueWithDefault(
"Seek", 0);
393 encryptor->
Seek(seek);
394 decryptor->
Seek(seek);
397 std::string encrypted, xorDigest, ciphertext, ciphertextXorDigest;
398 if (test ==
"EncryptionMCT" || test ==
"DecryptionMCT")
401 SecByteBlock buf((
byte *)plaintext.data(), plaintext.size()), keybuf((
byte *)key.data(), key.size());
403 if (test ==
"DecryptionMCT")
405 cipher = decryptor.get();
406 ciphertext = GetDecodedDatum(v,
"Ciphertext");
407 buf.Assign((
byte *)ciphertext.data(), ciphertext.size());
410 for (
int i=0; i<400; i++)
412 encrypted.reserve(10000 * plaintext.size());
413 for (
int j=0; j<10000; j++)
416 encrypted.append((
char *)buf.begin(), buf.size());
419 encrypted.erase(0, encrypted.size() - keybuf.size());
420 xorbuf(keybuf.begin(), (
const byte *)encrypted.data(), keybuf.size());
421 cipher->
SetKey(keybuf, keybuf.size());
423 encrypted.assign((
char *)buf.begin(), buf.size());
424 ciphertext = GetDecodedDatum(v, test ==
"EncryptionMCT" ?
"Ciphertext" :
"Plaintext");
425 if (encrypted != ciphertext)
427 std::cout <<
"incorrectly encrypted: ";
429 xx.Pump(256); xx.Flush(
false);
437 RandomizedTransfer(
StringStore(plaintext).Ref(), encFilter,
true);
438 encFilter.MessageEnd();
448 if (test !=
"EncryptXorDigest")
449 ciphertext = GetDecodedDatum(v,
"Ciphertext");
452 ciphertextXorDigest = GetDecodedDatum(v,
"CiphertextXorDigest");
453 xorDigest.append(encrypted, 0, 64);
454 for (
size_t i=64; i<encrypted.size(); i++)
455 xorDigest[i%64] ^= encrypted[i];
457 if (test !=
"EncryptXorDigest" ? encrypted != ciphertext : xorDigest != ciphertextXorDigest)
459 std::cout <<
"incorrectly encrypted: ";
461 xx.Pump(2048); xx.Flush(
false);
465 std::string decrypted;
467 RandomizedTransfer(
StringStore(encrypted).Ref(), decFilter,
true);
468 decFilter.MessageEnd();
469 if (decrypted != plaintext)
471 std::cout <<
"incorrectly decrypted: ";
473 xx.Pump(256); xx.Flush(
false);
480 std::cout <<
"unexpected test name\n";
485 void TestAuthenticatedSymmetricCipher(TestData &v,
const NameValuePairs &overrideParameters)
487 std::string type = GetRequiredDatum(v,
"AlgorithmType");
488 std::string name = GetRequiredDatum(v,
"Name");
489 std::string test = GetRequiredDatum(v,
"Test");
490 std::string key = GetDecodedDatum(v,
"Key");
492 std::string plaintext = GetOptionalDecodedDatum(v,
"Plaintext");
493 std::string ciphertext = GetOptionalDecodedDatum(v,
"Ciphertext");
494 std::string header = GetOptionalDecodedDatum(v,
"Header");
495 std::string footer = GetOptionalDecodedDatum(v,
"Footer");
496 std::string mac = GetOptionalDecodedDatum(v,
"MAC");
501 if (test ==
"Encrypt" || test ==
"EncryptXorDigest" || test ==
"NotVerify")
506 asc1->
SetKey((
const byte *)key.data(), key.size(), pairs);
507 asc2->
SetKey((
const byte *)key.data(), key.size(), pairs);
509 std::string encrypted, decrypted;
511 bool macAtBegin = !mac.empty() && !GlobalRNG().
GenerateBit();
520 StringStore sh(header), sp(plaintext), sc(ciphertext), sf(footer), sm(mac);
523 RandomizedTransfer(sm, df,
true);
525 RandomizedTransfer(sc, df,
true);
528 RandomizedTransfer(sm, df,
true);
532 RandomizedTransfer(sp, ef,
true);
536 if (test ==
"Encrypt" && encrypted != ciphertext+mac)
538 std::cout <<
"incorrectly encrypted: ";
540 xx.Pump(2048); xx.Flush(
false);
544 if (test ==
"Encrypt" && decrypted != plaintext)
546 std::cout <<
"incorrectly decrypted: ";
548 xx.Pump(256); xx.Flush(
false);
553 if (ciphertext.size()+mac.size()-plaintext.size() != asc1->
DigestSize())
555 std::cout <<
"bad MAC size\n";
558 if (df.GetLastResult() != (test ==
"Encrypt"))
560 std::cout <<
"MAC incorrectly verified\n";
566 std::cout <<
"unexpected test name\n";
571 void TestDigestOrMAC(TestData &v,
bool testDigest)
573 std::string name = GetRequiredDatum(v,
"Name");
574 std::string test = GetRequiredDatum(v,
"Test");
575 const char *digestName = testDigest ?
"Digest" :
"MAC";
592 std::string key = GetDecodedDatum(v,
"Key");
593 mac->
SetKey((
const byte *)key.c_str(), key.size(), pairs);
596 if (test ==
"Verify" || test ==
"VerifyTruncated" || test ==
"NotVerify")
599 if (test ==
"VerifyTruncated")
600 digestSize = pairs.GetIntValueWithDefault(Name::DigestSize(), digestSize);
602 PutDecodedDatumInto(v, digestName, verifierFilter);
603 PutDecodedDatumInto(v,
"Message", verifierFilter);
604 verifierFilter.MessageEnd();
605 if (verifierFilter.GetLastResult() == (test ==
"NotVerify"))
615 void TestKeyDerivationFunction(TestData &v)
617 std::string name = GetRequiredDatum(v,
"Name");
618 std::string test = GetRequiredDatum(v,
"Test");
620 if(test ==
"Skip")
return;
621 assert(test ==
"Verify");
623 std::string key = GetDecodedDatum(v,
"Key");
624 std::string salt = GetDecodedDatum(v,
"Salt");
625 std::string info = GetDecodedDatum(v,
"Info");
626 std::string derived = GetDecodedDatum(v,
"DerivedKey");
627 std::string t = GetDecodedDatum(v,
"DerivedKeyLength");
630 unsigned int length = pairs.GetIntValueWithDefault(Name::DerivedKeyLength(), (
int)derived.size());
635 std::string calc; calc.resize(length);
636 unsigned int ret = kdf->
DeriveKey(
reinterpret_cast<byte*
>(&calc[0]), calc.size(),
637 reinterpret_cast<const byte*
>(key.data()), key.size(),
638 reinterpret_cast<const byte*
>(salt.data()), salt.size(),
639 reinterpret_cast<const byte*
>(info.data()), info.size());
641 if(calc != derived || ret != length)
645 bool GetField(std::istream &is, std::string &name, std::string &value)
653 if (name[name.size()-1] !=
':')
661 name.erase(name.size()-1);
663 while (is.peek() ==
' ')
669 bool continueLine, space =
false;
675 is.get(buffer,
sizeof(buffer));
677 if (buffer[0] ==
' ')
680 while (buffer[0] != 0);
684 if (!value.empty() && value[value.size()-1] ==
'\r')
685 value.resize(value.size()-1);
687 if (!value.empty() && value[value.size()-1] ==
'\\')
689 value.resize(value.size()-1);
693 continueLine =
false;
695 std::string::size_type i = value.find(
'#');
696 if (i != std::string::npos)
699 while (continueLine);
702 if (space && (name ==
"Modulus" || name ==
"SubgroupOrder" || name ==
"SubgroupGenerator" ||
703 name ==
"PublicElement" || name ==
"PrivateExponent" || name ==
"Signature"))
706 temp.reserve(value.size());
708 std::string::const_iterator it;
709 for(it = value.begin(); it != value.end(); it++)
715 std::swap(temp, value);
725 CRYPTOPP_UNUSED(b); assert(b);
726 cout << name <<
": \\\n ";
727 x.Encode(
HexEncoder(
new FileSink(cout),
false, 64,
"\\\n ").Ref(), x.MinEncodedSize());
734 string::size_type i = 0;
735 while (i < names.size())
737 string::size_type j = names.find_first_of (
';', i);
739 if (j == string::npos)
743 std::string name = names.substr(i, j-i);
744 if (name.find(
':') == string::npos)
745 OutputPair(v, name.c_str());
752 void TestDataFile(std::string filename,
const NameValuePairs &overrideParameters,
unsigned int &totalTests,
unsigned int &failedTests)
754 static const std::string dataDirectory(CRYPTOPP_DATA_DIR);
755 if (!dataDirectory.empty())
757 if(dataDirectory != filename.substr(0, dataDirectory.length()))
758 filename.insert(0, dataDirectory);
761 std::ifstream file(filename.c_str());
765 s_currentTestData = &v;
766 std::string name, value, lastAlgName;
770 while (file.peek() ==
'#')
771 file.ignore(std::numeric_limits<std::streamsize>::max(),
'\n');
773 if (file.peek() ==
'\n' || file.peek() ==
'\r')
776 if (!GetField(file, name, value))
780 if (name ==
"Test" && (s_thorough || v[
"SlowTest"] !=
"1"))
783 std::string algType = GetRequiredDatum(v,
"AlgorithmType");
785 if (lastAlgName != GetRequiredDatum(v,
"Name"))
787 lastAlgName = GetRequiredDatum(v,
"Name");
788 cout <<
"\nTesting " << algType.c_str() <<
" algorithm " << lastAlgName.c_str() <<
".\n";
793 if (algType ==
"Signature")
794 TestSignatureScheme(v);
795 else if (algType ==
"SymmetricCipher")
796 TestSymmetricCipher(v, overrideParameters);
797 else if (algType ==
"AuthenticatedSymmetricCipher")
798 TestAuthenticatedSymmetricCipher(v, overrideParameters);
799 else if (algType ==
"AsymmetricCipher")
800 TestAsymmetricCipher(v);
801 else if (algType ==
"MessageDigest")
802 TestDigestOrMAC(v,
true);
803 else if (algType ==
"MAC")
804 TestDigestOrMAC(v,
false);
805 else if (algType ==
"KDF")
806 TestKeyDerivationFunction(v);
807 else if (algType ==
"FileList")
810 SignalUnknownAlgorithmError(algType);
815 cout <<
"\nTest failed.\n";
817 catch (
const CryptoPP::Exception &e)
819 cout <<
"\nCryptoPP::Exception caught: " << e.what() << endl;
821 catch (
const std::exception &e)
823 cout <<
"\nstd::exception caught: " << e.what() << endl;
828 cout <<
"Skipping to next test.\n";
832 cout <<
"." << flush;
839 bool RunTestDataFile(
const char *filename,
const NameValuePairs &overrideParameters,
bool thorough)
841 s_thorough = thorough;
842 unsigned int totalTests = 0, failedTests = 0;
843 TestDataFile((filename ? filename :
""), overrideParameters, totalTests, failedTests);
844 cout << dec <<
"\nTests complete. Total tests = " << totalTests <<
". Failed tests = " << failedTests <<
"." << endl;
845 if (failedTests != 0)
846 cout <<
"SOME TESTS FAILED!\n";
847 return failedTests == 0;