13 USING_NAMESPACE(CryptoPP)
16 typedef std::map<std::
string, std::
string> TestData;
21 TestFailure() : Exception(OTHER_ERROR,
"Validation test failed") {}
24 static const TestData *s_currentTestData = NULL;
26 static void OutputTestData(
const TestData &v)
28 for (TestData::const_iterator i = v.begin(); i != v.end(); ++i)
30 cerr << i->first <<
": " << i->second << endl;
34 static void SignalTestFailure()
36 OutputTestData(*s_currentTestData);
40 static void SignalTestError()
42 OutputTestData(*s_currentTestData);
46 bool DataExists(
const TestData &data,
const char *name)
48 TestData::const_iterator i = data.find(name);
49 return (i != data.end());
52 const std::string & GetRequiredDatum(
const TestData &data,
const char *name)
54 TestData::const_iterator i = data.find(name);
67 len = source.
Get(buf+start, len);
68 target.ChannelPut(channel, buf+start, len);
74 std::string s1 = GetRequiredDatum(data, name), s2;
89 repeat = atoi(s1.c_str()+1);
90 s1 = s1.substr(s1.find(
' ')+1);
97 s2 = s1.substr(1, s1.find(
'\"', 1)-1);
98 s1 = s1.substr(s2.length() + 2);
100 else if (s1.substr(0, 2) ==
"0x")
103 s1 = s1.substr(STDMIN(s1.find(
' '), s1.length()));
108 s1 = s1.substr(STDMIN(s1.find(
' '), s1.length()));
113 q.
Put((
const byte *)s2.data(), s2.size());
114 RandomizedTransfer(q, target,
false);
119 RandomizedTransfer(q, target,
true);
122 std::string GetDecodedDatum(
const TestData &data,
const char *name)
125 PutDecodedDatumInto(data, name,
StringSink(s).Ref());
129 std::string GetOptionalDecodedDatum(
const TestData &data,
const char *name)
132 if (DataExists(data, name))
133 PutDecodedDatumInto(data, name,
StringSink(s).Ref());
142 virtual bool GetVoidValue(
const char *name,
const std::type_info &valueType,
void *pValue)
const
144 TestData::const_iterator i = m_data.find(name);
145 if (i == m_data.end())
149 i = m_data.find(
"MAC");
150 if (i == m_data.end())
151 i = m_data.find(
"Digest");
152 if (i == m_data.end())
156 PutDecodedDatumInto(m_data, i->first.c_str(),
StringSink(m_temp).
Ref());
157 *
reinterpret_cast<int *
>(pValue) = (
int)m_temp.size();
164 const std::string &value = i->second;
166 if (valueType ==
typeid(
int))
167 *
reinterpret_cast<int *
>(pValue) = atoi(value.c_str());
168 else if (valueType ==
typeid(
Integer))
169 *reinterpret_cast<Integer *>(pValue) =
Integer((std::string(value) +
"h").c_str());
173 PutDecodedDatumInto(m_data, name,
StringSink(m_temp).Ref());
174 reinterpret_cast<ConstByteArrayParameter *
>(pValue)->Assign((
const byte *)m_temp.data(), m_temp.size(),
false);
183 const TestData &m_data;
184 mutable std::string m_temp;
203 void TestSignatureScheme(TestData &v)
205 std::string name = GetRequiredDatum(v,
"Name");
206 std::string test = GetRequiredDatum(v,
"Test");
212 std::string keyFormat = GetRequiredDatum(v,
"KeyFormat");
214 if (keyFormat ==
"DER")
215 verifier->AccessMaterial().Load(
StringStore(GetDecodedDatum(v,
"PublicKey")).Ref());
216 else if (keyFormat ==
"Component")
217 verifier->AccessMaterial().AssignFrom(pairs);
219 if (test ==
"Verify" || test ==
"NotVerify")
221 VerifierFilter verifierFilter(*verifier, NULL, VerifierFilter::SIGNATURE_AT_BEGIN);
222 PutDecodedDatumInto(v,
"Signature", verifierFilter);
223 PutDecodedDatumInto(v,
"Message", verifierFilter);
224 verifierFilter.MessageEnd();
225 if (verifierFilter.GetLastResult() == (test ==
"NotVerify"))
228 else if (test ==
"PublicKeyValid")
230 if (!verifier->GetMaterial().Validate(GlobalRNG(), 3))
234 goto privateKeyTests;
239 if (keyFormat ==
"DER")
240 signer->AccessMaterial().Load(
StringStore(GetDecodedDatum(v,
"PrivateKey")).Ref());
241 else if (keyFormat ==
"Component")
242 signer->AccessMaterial().AssignFrom(pairs);
244 if (test ==
"KeyPairValidAndConsistent")
246 TestKeyPairValidAndConsistent(verifier->AccessMaterial(), signer->GetMaterial());
248 else if (test ==
"Sign")
254 else if (test ==
"DeterministicSign")
259 else if (test ==
"RandomSign")
264 else if (test ==
"GenerateKey")
276 void TestAsymmetricCipher(TestData &v)
278 std::string name = GetRequiredDatum(v,
"Name");
279 std::string test = GetRequiredDatum(v,
"Test");
284 std::string keyFormat = GetRequiredDatum(v,
"KeyFormat");
286 if (keyFormat ==
"DER")
288 decryptor->AccessMaterial().Load(
StringStore(GetDecodedDatum(v,
"PrivateKey")).Ref());
289 encryptor->AccessMaterial().Load(
StringStore(GetDecodedDatum(v,
"PublicKey")).Ref());
291 else if (keyFormat ==
"Component")
294 decryptor->AccessMaterial().AssignFrom(pairs);
295 encryptor->AccessMaterial().AssignFrom(pairs);
298 if (test ==
"DecryptMatch")
300 std::string decrypted, expected = GetDecodedDatum(v,
"Plaintext");
302 if (decrypted != expected)
305 else if (test ==
"KeyPairValidAndConsistent")
307 TestKeyPairValidAndConsistent(encryptor->AccessMaterial(), decryptor->GetMaterial());
316 void TestSymmetricCipher(TestData &v,
const NameValuePairs &overrideParameters)
318 std::string name = GetRequiredDatum(v,
"Name");
319 std::string test = GetRequiredDatum(v,
"Test");
321 std::string key = GetDecodedDatum(v,
"Key");
322 std::string plaintext = GetDecodedDatum(v,
"Plaintext");
327 if (test ==
"Encrypt" || test ==
"EncryptXorDigest" || test ==
"Resync" || test ==
"EncryptionMCT" || test ==
"DecryptionMCT")
330 static std::string lastName;
332 if (name != lastName)
340 if (pairs.GetValue(
Name::IV(), iv) && iv.size() != encryptor->IVSize())
343 if (test ==
"Resync")
350 encryptor->
SetKey((
const byte *)key.data(), key.size(), pairs);
351 decryptor->
SetKey((
const byte *)key.data(), key.size(), pairs);
354 int seek = pairs.GetIntValueWithDefault(
"Seek", 0);
357 encryptor->
Seek(seek);
358 decryptor->
Seek(seek);
361 std::string encrypted, xorDigest, ciphertext, ciphertextXorDigest;
362 if (test ==
"EncryptionMCT" || test ==
"DecryptionMCT")
365 SecByteBlock buf((byte *)plaintext.data(), plaintext.size()), keybuf((byte *)key.data(), key.size());
367 if (test == "DecryptionMCT")
369 cipher = decryptor.get();
370 ciphertext = GetDecodedDatum(v,
"Ciphertext");
371 buf.Assign((byte *)ciphertext.data(), ciphertext.size());
374 for (
int i=0; i<400; i++)
376 encrypted.reserve(10000 * plaintext.size());
377 for (
int j=0; j<10000; j++)
380 encrypted.append((
char *)buf.begin(), buf.size());
383 encrypted.erase(0, encrypted.size() - keybuf.size());
384 xorbuf(keybuf.begin(), (
const byte *)encrypted.data(), keybuf.size());
385 cipher->
SetKey(keybuf, keybuf.size());
387 encrypted.assign((
char *)buf.begin(), buf.size());
388 ciphertext = GetDecodedDatum(v, test ==
"EncryptionMCT" ?
"Ciphertext" :
"Plaintext");
389 if (encrypted != ciphertext)
391 std::cout <<
"incorrectly encrypted: ";
393 xx.Pump(256); xx.Flush(
false);
401 RandomizedTransfer(
StringStore(plaintext).Ref(), encFilter,
true);
402 encFilter.MessageEnd();
412 if (test !=
"EncryptXorDigest")
413 ciphertext = GetDecodedDatum(v,
"Ciphertext");
416 ciphertextXorDigest = GetDecodedDatum(v,
"CiphertextXorDigest");
417 xorDigest.append(encrypted, 0, 64);
418 for (
size_t i=64; i<encrypted.size(); i++)
419 xorDigest[i%64] ^= encrypted[i];
421 if (test !=
"EncryptXorDigest" ? encrypted != ciphertext : xorDigest != ciphertextXorDigest)
423 std::cout <<
"incorrectly encrypted: ";
425 xx.Pump(2048); xx.Flush(
false);
429 std::string decrypted;
431 RandomizedTransfer(
StringStore(encrypted).Ref(), decFilter,
true);
432 decFilter.MessageEnd();
433 if (decrypted != plaintext)
435 std::cout <<
"incorrectly decrypted: ";
437 xx.Pump(256); xx.Flush(
false);
444 std::cout <<
"unexpected test name\n";
449 void TestAuthenticatedSymmetricCipher(TestData &v,
const NameValuePairs &overrideParameters)
451 std::string type = GetRequiredDatum(v,
"AlgorithmType");
452 std::string name = GetRequiredDatum(v,
"Name");
453 std::string test = GetRequiredDatum(v,
"Test");
454 std::string key = GetDecodedDatum(v,
"Key");
456 std::string plaintext = GetOptionalDecodedDatum(v,
"Plaintext");
457 std::string ciphertext = GetOptionalDecodedDatum(v,
"Ciphertext");
458 std::string header = GetOptionalDecodedDatum(v,
"Header");
459 std::string footer = GetOptionalDecodedDatum(v,
"Footer");
460 std::string mac = GetOptionalDecodedDatum(v,
"MAC");
465 if (test ==
"Encrypt" || test ==
"EncryptXorDigest" || test ==
"NotVerify")
470 asc1->
SetKey((
const byte *)key.data(), key.size(), pairs);
471 asc2->
SetKey((
const byte *)key.data(), key.size(), pairs);
473 std::string encrypted, decrypted;
475 bool macAtBegin = !mac.empty() && !GlobalRNG().
GenerateBit();
484 StringStore sh(header), sp(plaintext), sc(ciphertext), sf(footer), sm(mac);
487 RandomizedTransfer(sm, df,
true);
488 sh.CopyTo(df, LWORD_MAX, AAD_CHANNEL);
489 RandomizedTransfer(sc, df,
true);
490 sf.CopyTo(df, LWORD_MAX, AAD_CHANNEL);
492 RandomizedTransfer(sm, df,
true);
495 RandomizedTransfer(sh, ef,
true, AAD_CHANNEL);
496 RandomizedTransfer(sp, ef,
true);
497 RandomizedTransfer(sf, ef,
true, AAD_CHANNEL);
500 if (test ==
"Encrypt" && encrypted != ciphertext+mac)
502 std::cout <<
"incorrectly encrypted: ";
504 xx.Pump(2048); xx.Flush(
false);
508 if (test ==
"Encrypt" && decrypted != plaintext)
510 std::cout <<
"incorrectly decrypted: ";
512 xx.Pump(256); xx.Flush(
false);
517 if (ciphertext.size()+mac.size()-plaintext.size() != asc1->
DigestSize())
519 std::cout <<
"bad MAC size\n";
522 if (df.GetLastResult() != (test ==
"Encrypt"))
524 std::cout <<
"MAC incorrectly verified\n";
530 std::cout <<
"unexpected test name\n";
535 void TestDigestOrMAC(TestData &v,
bool testDigest)
537 std::string name = GetRequiredDatum(v,
"Name");
538 std::string test = GetRequiredDatum(v,
"Test");
539 const char *digestName = testDigest ?
"Digest" :
"MAC";
556 std::string key = GetDecodedDatum(v,
"Key");
557 mac->
SetKey((
const byte *)key.c_str(), key.size(), pairs);
560 if (test ==
"Verify" || test ==
"VerifyTruncated" || test ==
"NotVerify")
563 if (test ==
"VerifyTruncated")
566 PutDecodedDatumInto(v, digestName, verifierFilter);
567 PutDecodedDatumInto(v,
"Message", verifierFilter);
568 verifierFilter.MessageEnd();
569 if (verifierFilter.GetLastResult() == (test ==
"NotVerify"))
579 bool GetField(std::istream &is, std::string &name, std::string &value)
586 if (name[name.size()-1] !=
':')
594 name.erase(name.size()-1);
596 while (is.peek() ==
' ')
608 is.get(buffer,
sizeof(buffer));
611 while (buffer[0] != 0);
615 if (!value.empty() && value[value.size()-1] ==
'\r')
616 value.resize(value.size()-1);
618 if (!value.empty() && value[value.size()-1] ==
'\\')
620 value.resize(value.size()-1);
624 continueLine =
false;
626 std::string::size_type i = value.find(
'#');
627 if (i != std::string::npos)
630 while (continueLine);
640 cout << name <<
": \\\n ";
648 string::size_type i = 0;
649 while (i < names.size())
651 string::size_type j = names.find_first_of (
';', i);
653 if (j == string::npos)
657 std::string name = names.substr(i, j-i);
658 if (name.find(
':') == string::npos)
659 OutputPair(v, name.c_str());
666 void TestDataFile(
const std::string &filename,
const NameValuePairs &overrideParameters,
unsigned int &totalTests,
unsigned int &failedTests)
668 std::ifstream file(filename.c_str());
672 s_currentTestData = &v;
673 std::string name, value, lastAlgName;
677 while (file.peek() ==
'#')
678 file.ignore(INT_MAX,
'\n');
680 if (file.peek() ==
'\n' || file.peek() ==
'\r')
683 if (!GetField(file, name, value))
690 std::string algType = GetRequiredDatum(v,
"AlgorithmType");
692 if (lastAlgName != GetRequiredDatum(v,
"Name"))
694 lastAlgName = GetRequiredDatum(v,
"Name");
695 cout <<
"\nTesting " << algType.c_str() <<
" algorithm " << lastAlgName.c_str() <<
".\n";
700 if (algType ==
"Signature")
701 TestSignatureScheme(v);
702 else if (algType ==
"SymmetricCipher")
703 TestSymmetricCipher(v, overrideParameters);
704 else if (algType ==
"AuthenticatedSymmetricCipher")
705 TestAuthenticatedSymmetricCipher(v, overrideParameters);
706 else if (algType ==
"AsymmetricCipher")
707 TestAsymmetricCipher(v);
708 else if (algType ==
"MessageDigest")
709 TestDigestOrMAC(v,
true);
710 else if (algType ==
"MAC")
711 TestDigestOrMAC(v,
false);
712 else if (algType ==
"FileList")
713 TestDataFile(GetRequiredDatum(v,
"Test"), g_nullNameValuePairs, totalTests, failedTests);
720 cout <<
"\nTest failed.\n";
722 catch (CryptoPP::Exception &e)
724 cout <<
"\nCryptoPP::Exception caught: " << e.what() << endl;
726 catch (std::exception &e)
728 cout <<
"\nstd::exception caught: " << e.what() << endl;
733 cout <<
"Skipping to next test.\n";
737 cout <<
"." << flush;
744 bool RunTestDataFile(
const char *filename,
const NameValuePairs &overrideParameters)
746 unsigned int totalTests = 0, failedTests = 0;
747 TestDataFile(filename, overrideParameters, totalTests, failedTests);
748 cout << dec <<
"\nTests complete. Total tests = " << totalTests <<
". Failed tests = " << failedTests <<
".\n";
749 if (failedTests != 0)
750 cout <<
"SOME TESTS FAILED!\n";
751 return failedTests == 0;