Crypto++  5.6.3
Free C++ class library of cryptographic schemes
validat1.cpp
1 // validat1.cpp - written and placed in the public domain by Wei Dai
2 
3 #include "pch.h"
4 
5 #define CRYPTOPP_ENABLE_NAMESPACE_WEAK 1
6 
7 #include "cryptlib.h"
8 #include "pubkey.h"
9 #include "gfpcrypt.h"
10 #include "eccrypto.h"
11 #include "filters.h"
12 #include "files.h"
13 #include "hex.h"
14 #include "base32.h"
15 #include "base64.h"
16 #include "modes.h"
17 #include "cbcmac.h"
18 #include "dmac.h"
19 #include "idea.h"
20 #include "des.h"
21 #include "rc2.h"
22 #include "arc4.h"
23 #include "rc5.h"
24 #include "blowfish.h"
25 #include "3way.h"
26 #include "safer.h"
27 #include "gost.h"
28 #include "shark.h"
29 #include "cast.h"
30 #include "square.h"
31 #include "seal.h"
32 #include "rc6.h"
33 #include "mars.h"
34 #include "aes.h"
35 #include "rijndael.h"
36 #include "twofish.h"
37 #include "serpent.h"
38 #include "skipjack.h"
39 #include "shacal2.h"
40 #include "camellia.h"
41 #include "osrng.h"
42 #include "rdrand.h"
43 #include "zdeflate.h"
44 #include "smartptr.h"
45 #include "cpu.h"
46 #include "rng.h"
47 
48 #include <time.h>
49 #include <memory>
50 #include <iostream>
51 #include <iomanip>
52 
53 #include "validate.h"
54 
55 // Aggressive stack checking with VS2005 SP1 and above.
56 #if (CRYPTOPP_MSC_VERSION >= 1410)
57 # pragma strict_gs_check (on)
58 #endif
59 
60 USING_NAMESPACE(CryptoPP)
61 USING_NAMESPACE(std)
62 
63 bool ValidateAll(bool thorough)
64 {
65  bool pass=TestSettings();
66  pass=TestOS_RNG() && pass;
67  pass=TestAutoSeeded() && pass;
68 
69 #if (CRYPTOPP_BOOL_X86 || CRYPTOPP_BOOL_X32 || CRYPTOPP_BOOL_X64)
70  pass=TestRDRAND() && pass;
71  pass=TestRDSEED() && pass;
72 #endif
73 
74 #if !defined(NDEBUG) && !defined(CRYPTOPP_IMPORTS)
75  // http://github.com/weidai11/cryptopp/issues/92
76  pass=TestSecBlock() && pass;
77  // http://github.com/weidai11/cryptopp/issues/64
78  pass=TestPolynomialMod2() && pass;
79 #endif
80 
81  pass=ValidateCRC32() && pass;
82  pass=ValidateAdler32() && pass;
83  pass=ValidateMD2() && pass;
84  pass=ValidateMD5() && pass;
85  pass=ValidateSHA() && pass;
86  pass=RunTestDataFile(PACKAGE_DATA_DIR "TestVectors/sha3.txt") && pass;
87  pass=ValidateTiger() && pass;
88  pass=ValidateRIPEMD() && pass;
89  pass=ValidatePanama() && pass;
90  pass=ValidateWhirlpool() && pass;
91 
92  pass=ValidateHMAC() && pass;
93  pass=ValidateTTMAC() && pass;
94 
95  pass=ValidatePBKDF() && pass;
96  pass=ValidateHKDF() && pass;
97 
98  pass=ValidateDES() && pass;
99  pass=ValidateCipherModes() && pass;
100  pass=ValidateIDEA() && pass;
101  pass=ValidateSAFER() && pass;
102  pass=ValidateRC2() && pass;
103  pass=ValidateARC4() && pass;
104  pass=ValidateRC5() && pass;
105  pass=ValidateBlowfish() && pass;
106  pass=ValidateThreeWay() && pass;
107  pass=ValidateGOST() && pass;
108  pass=ValidateSHARK() && pass;
109  pass=ValidateCAST() && pass;
110  pass=ValidateSquare() && pass;
111  pass=ValidateSKIPJACK() && pass;
112  pass=ValidateSEAL() && pass;
113  pass=ValidateRC6() && pass;
114  pass=ValidateMARS() && pass;
115  pass=ValidateRijndael() && pass;
116  pass=ValidateTwofish() && pass;
117  pass=ValidateSerpent() && pass;
118  pass=ValidateSHACAL2() && pass;
119  pass=ValidateCamellia() && pass;
120  pass=ValidateSalsa() && pass;
121  pass=ValidateSosemanuk() && pass;
122  pass=ValidateVMAC() && pass;
123  pass=ValidateCCM() && pass;
124  pass=ValidateGCM() && pass;
125  pass=ValidateCMAC() && pass;
126  pass=RunTestDataFile(PACKAGE_DATA_DIR "TestVectors/eax.txt") && pass;
127  pass=RunTestDataFile(PACKAGE_DATA_DIR "TestVectors/seed.txt") && pass;
128 
129  pass=ValidateBBS() && pass;
130  pass=ValidateDH() && pass;
131  pass=ValidateMQV() && pass;
132  pass=ValidateRSA() && pass;
133  pass=ValidateElGamal() && pass;
134  pass=ValidateDLIES() && pass;
135  pass=ValidateNR() && pass;
136  pass=ValidateDSA(thorough) && pass;
137  pass=ValidateLUC() && pass;
138  pass=ValidateLUC_DH() && pass;
139  pass=ValidateLUC_DL() && pass;
140  pass=ValidateXTR_DH() && pass;
141  pass=ValidateRabin() && pass;
142  pass=ValidateRW() && pass;
143 // pass=ValidateBlumGoldwasser() && pass;
144  pass=ValidateECP() && pass;
145  pass=ValidateEC2N() && pass;
146  pass=ValidateECDSA() && pass;
147  pass=ValidateESIGN() && pass;
148 
149  if (pass)
150  cout << "\nAll tests passed!\n";
151  else
152  cout << "\nOops! Not all tests passed.\n";
153 
154  return pass;
155 }
156 
157 bool TestSettings()
158 {
159  // Thanks to IlyaBizyaev and Zireael, http://github.com/weidai11/cryptopp/issues/28
160 #if defined(__MINGW32__)
161  using CryptoPP::memcpy_s;
162 #endif
163 
164  bool pass = true;
165 
166  cout << "\nTesting Settings...\n\n";
167 
168  word32 w;
169  memcpy_s(&w, sizeof(w), "\x01\x02\x03\x04", 4);
170 
171  if (w == 0x04030201L)
172  {
173 #ifdef IS_LITTLE_ENDIAN
174  cout << "passed: ";
175 #else
176  cout << "FAILED: ";
177  pass = false;
178 #endif
179  cout << "Your machine is little endian.\n";
180  }
181  else if (w == 0x01020304L)
182  {
183 #ifndef IS_LITTLE_ENDIAN
184  cout << "passed: ";
185 #else
186  cout << "FAILED: ";
187  pass = false;
188 #endif
189  cout << "Your machine is big endian.\n";
190  }
191  else
192  {
193  cout << "FAILED: Your machine is neither big endian nor little endian.\n";
194  pass = false;
195  }
196 
197 #ifdef CRYPTOPP_ALLOW_UNALIGNED_DATA_ACCESS
198  byte testvals[10] = {1,2,2,3,3,3,3,2,2,1};
199  if (*(word32 *)(testvals+3) == 0x03030303 && *(word64 *)(testvals+1) == W64LIT(0x0202030303030202))
200  cout << "passed: Your machine allows unaligned data access.\n";
201  else
202  {
203  cout << "FAILED: Unaligned data access gave incorrect results.\n";
204  pass = false;
205  }
206 #else
207  cout << "passed: CRYPTOPP_ALLOW_UNALIGNED_DATA_ACCESS is not defined. Will restrict to aligned data access.\n";
208 #endif
209 
210  if (sizeof(byte) == 1)
211  cout << "passed: ";
212  else
213  {
214  cout << "FAILED: ";
215  pass = false;
216  }
217  cout << "sizeof(byte) == " << sizeof(byte) << endl;
218 
219  if (sizeof(word16) == 2)
220  cout << "passed: ";
221  else
222  {
223  cout << "FAILED: ";
224  pass = false;
225  }
226  cout << "sizeof(word16) == " << sizeof(word16) << endl;
227 
228  if (sizeof(word32) == 4)
229  cout << "passed: ";
230  else
231  {
232  cout << "FAILED: ";
233  pass = false;
234  }
235  cout << "sizeof(word32) == " << sizeof(word32) << endl;
236 
237  if (sizeof(word64) == 8)
238  cout << "passed: ";
239  else
240  {
241  cout << "FAILED: ";
242  pass = false;
243  }
244  cout << "sizeof(word64) == " << sizeof(word64) << endl;
245 
246 #ifdef CRYPTOPP_WORD128_AVAILABLE
247  if (sizeof(word128) == 16)
248  cout << "passed: ";
249  else
250  {
251  cout << "FAILED: ";
252  pass = false;
253  }
254  cout << "sizeof(word128) == " << sizeof(word128) << endl;
255 #endif
256 
257  if (sizeof(word) == 2*sizeof(hword)
258 #ifdef CRYPTOPP_NATIVE_DWORD_AVAILABLE
259  && sizeof(dword) == 2*sizeof(word)
260 #endif
261  )
262  cout << "passed: ";
263  else
264  {
265  cout << "FAILED: ";
266  pass = false;
267  }
268  cout << "sizeof(hword) == " << sizeof(hword) << ", sizeof(word) == " << sizeof(word);
269 #ifdef CRYPTOPP_NATIVE_DWORD_AVAILABLE
270  cout << ", sizeof(dword) == " << sizeof(dword);
271 #endif
272  cout << endl;
273 
274 #ifdef CRYPTOPP_CPUID_AVAILABLE
275  bool hasMMX = HasMMX();
276  bool hasISSE = HasISSE();
277  bool hasSSE2 = HasSSE2();
278  bool hasSSSE3 = HasSSSE3();
279  bool isP4 = IsP4();
280  int cacheLineSize = GetCacheLineSize();
281 
282  if ((isP4 && (!hasMMX || !hasSSE2)) || (hasSSE2 && !hasMMX) || (cacheLineSize < 16 || cacheLineSize > 256 || !IsPowerOf2(cacheLineSize)))
283  {
284  cout << "FAILED: ";
285  pass = false;
286  }
287  else
288  cout << "passed: ";
289 
290  cout << "hasMMX == " << hasMMX << ", hasISSE == " << hasISSE << ", hasSSE2 == " << hasSSE2 << ", hasSSSE3 == " << hasSSSE3 << ", hasAESNI == " << HasAESNI() << ", hasRDRAND == " << HasRDRAND() << ", hasRDSEED == " << HasRDSEED() << ", hasCLMUL == " << HasCLMUL() << ", isP4 == " << isP4 << ", cacheLineSize == " << cacheLineSize;
291  cout << ", AESNI_INTRINSICS == " << CRYPTOPP_BOOL_AESNI_INTRINSICS_AVAILABLE << endl;
292 #endif
293 
294  if (!pass)
295  {
296  cout << "Some critical setting in config.h is in error. Please fix it and recompile." << endl;
297  abort();
298  }
299  return pass;
300 }
301 
302 #if !defined(NDEBUG) && !defined(CRYPTOPP_IMPORTS)
303 bool TestSecBlock()
304 {
305  // SecBlock Assign, append and concatenate are not exercised in the library.
306  cout << "\nTesting SecBlock...\n\n";
307  bool r1 = true, r2 = true, r3 = true;
308  bool r4 = true, r5 = true, r6 = true;
309 
310  //********************** Assign
311 
312  try
313  {
314  SecByteBlock a, b;
315  a.Assign((const byte*)"a", 1);
316  b.Assign((const byte*)"b", 1);
317 
318  r1 &= (a.SizeInBytes() == 1);
319  r1 &= (b.SizeInBytes() == 1);
320  r1 &= (a[0] == 'a');
321  r1 &= (b[0] == 'b');
322 
323  a.Assign((const byte*)"ab", 2);
324  b.Assign((const byte*)"cd", 2);
325 
326  r1 &= (a.SizeInBytes() == 2);
327  r1 &= (b.SizeInBytes() == 2);
328  r1 &= (a[0] == 'a' && a[1] == 'b');
329  r1 &= (b[0] == 'c' && b[1] == 'd');
330  }
331  catch(const Exception& ex)
332  {
333  r1 = false;
334  }
335 
336  if (!r1)
337  cout << "FAILED:";
338  else
339  cout << "passed:";
340  cout << " Assign byte" << endl;
341 
342  try
343  {
344  SecBlock<word32> a, b;
345  word32 one[1] = {1}, two[1] = {2};
346 
347  a.Assign(one, 1);
348  b.Assign(two, 1);
349 
350  r2 &= (a.SizeInBytes() == 4);
351  r2 &= (b.SizeInBytes() == 4);
352  r2 &= (a[0] == 1);
353  r2 &= (b[0] == 2);
354 
355  word32 three[2] = {1,2}, four[2] = {3,4};
356 
357  a.Assign(three, 2);
358  b.Assign(four, 2);
359 
360  r2 &= (a.SizeInBytes() == 8);
361  r2 &= (b.SizeInBytes() == 8);
362  r2 &= (a[0] == 1 && a[1] == 2);
363  r2 &= (b[0] == 3 && b[1] == 4);
364  }
365  catch(const Exception& ex)
366  {
367  r2 = false;
368  }
369 
370  if (!r2)
371  cout << "FAILED:";
372  else
373  cout << "passed:";
374  cout << " Assign word32" << endl;
375 
376  //********************** Append
377 
378  try
379  {
380  SecByteBlock a, b;
381  a.Assign((const byte*)"a", 1);
382  b.Assign((const byte*)"b", 1);
383 
384  a += b;
385  r3 &= (a.SizeInBytes() == 2);
386  r3 &= (a[0] == 'a' && a[1] == 'b');
387 
388  a.Assign((const byte*)"ab", 2);
389  b.Assign((const byte*)"cd", 2);
390 
391  a += b;
392  r3 &= (a.SizeInBytes() == 4);
393  r3 &= (a[0] == 'a' && a[1] == 'b' && a[2] == 'c' && a[3] == 'd');
394 
395  a.Assign((const byte*)"a", 1);
396 
397  a += a;
398  r3 &= (a.SizeInBytes() == 2);
399  r3 &= (a[0] == 'a' && a[1] == 'a');
400 
401  a.Assign((const byte*)"ab", 2);
402 
403  a += a;
404  r3 &= (a.SizeInBytes() == 4);
405  r3 &= (a[0] == 'a' && a[1] == 'b' && a[2] == 'a' && a[3] == 'b');
406  }
407  catch(const Exception& ex)
408  {
409  r3 = false;
410  }
411 
412  if (!r3)
413  cout << "FAILED:";
414  else
415  cout << "passed:";
416  cout << " Append byte" << endl;
417 
418  try
419  {
420  SecBlock<word32> a, b;
421  word32 one[1] = {1}, two[1] = {2};
422 
423  a.Assign(one, 1);
424  b.Assign(two, 1);
425 
426  a += b;
427  r4 &= (a.SizeInBytes() == 8);
428  r4 &= (a[0] == 1 && a[1] == 2);
429 
430  word32 three[2] = {1,2}, four[2] = {3,4};
431 
432  a.Assign(three, 2);
433  b.Assign(four, 2);
434 
435  a += b;
436  r4 &= (a.SizeInBytes() == 16);
437  r4 &= (a[0] == 1 && a[1] == 2 && a[2] == 3 && a[3] == 4);
438 
439  a.Assign(one, 1);
440 
441  a += a;
442  r4 &= (a.SizeInBytes() == 8);
443  r4 &= (a[0] == 1 && a[1] == 1);
444 
445  a.Assign(three, 2);
446 
447  a += a;
448  r4 &= (a.SizeInBytes() == 16);
449  r4 &= (a[0] == 1 && a[1] == 2 && a[2] == 1 && a[3] == 2);
450 
451  }
452  catch(const Exception& ex)
453  {
454  r2 = false;
455  }
456 
457  if (!r4)
458  cout << "FAILED:";
459  else
460  cout << "passed:";
461  cout << " Append word32" << endl;
462 
463  //********************** Concatenate
464 
465  try
466  {
467  SecByteBlock a, b, c;
468  a.Assign((const byte*)"a", 1);
469  b.Assign((const byte*)"b", 1);
470 
471  c = a + b;
472  r5 &= (a[0] == 'a');
473  r5 &= (b[0] == 'b');
474  r5 &= (c.SizeInBytes() == 2);
475  r5 &= (c[0] == 'a' && c[1] == 'b');
476 
477  a.Assign((const byte*)"ab", 2);
478  b.Assign((const byte*)"cd", 2);
479 
480  c = a + b;
481  r5 &= (a[0] == 'a' && a[1] == 'b');
482  r5 &= (b[0] == 'c' && b[1] == 'd');
483  r5 &= (c.SizeInBytes() == 4);
484  r5 &= (c[0] == 'a' && c[1] == 'b' && c[2] == 'c' && c[3] == 'd');
485  }
486  catch(const Exception& ex)
487  {
488  r5 = false;
489  }
490 
491  if (!r5)
492  cout << "FAILED:";
493  else
494  cout << "passed:";
495  cout << " Concatenate byte" << endl;
496 
497  try
498  {
499  SecBlock<word32> a, b, c;
500  word32 one[1] = {1}, two[1] = {2};
501 
502  a.Assign(one, 1);
503  b.Assign(two, 1);
504 
505  c = a + b;
506  r6 &= (a[0] == 1);
507  r6 &= (b[0] == 2);
508  r6 &= (c.SizeInBytes() == 8);
509  r6 &= (c[0] == 1 && c[1] == 2);
510 
511  word32 three[2] = {1,2}, four[2] = {3,4};
512 
513  a.Assign(three, 2);
514  b.Assign(four, 2);
515 
516  c = a + b;
517  r6 &= (a[0] == 1 && a[1] == 2);
518  r6 &= (b[0] == 3 && b[1] == 4);
519  r6 &= (c.SizeInBytes() == 16);
520  r6 &= (c[0] == 1 && c[1] == 2 && c[2] == 3 && c[3] == 4);
521  }
522  catch(const Exception& ex)
523  {
524  r6 = false;
525  }
526 
527  if (!r6)
528  cout << "FAILED:";
529  else
530  cout << "passed:";
531  cout << " Concatenate word32" << endl;
532 
533 
534  return r1 && r2 && r3 && r4 && r5 && r6;
535 }
536 #endif
537 
538 bool TestOS_RNG()
539 {
540  bool pass = true;
541 
543 
544 #ifdef BLOCKING_RNG_AVAILABLE
545  try {rng.reset(new BlockingRng);}
546  catch (OS_RNG_Err &) {}
547 #endif
548 
549  if (rng.get())
550  {
551  cout << "\nTesting operating system provided blocking random number generator...\n\n";
552 
553  MeterFilter meter(new Redirector(TheBitBucket()));
554  RandomNumberSource test(*rng, UINT_MAX, false, new Deflator(new Redirector(meter)));
555  unsigned long total=0, length=0;
556  time_t t = time(NULL), t1 = 0;
557  CRYPTOPP_UNUSED(length);
558 
559  // check that it doesn't take too long to generate a reasonable amount of randomness
560  while (total < 16 && (t1 < 10 || total*8 > (unsigned long)t1))
561  {
562  test.Pump(1);
563  total += 1;
564  t1 = time(NULL) - t;
565  }
566 
567  if (total < 16)
568  {
569  cout << "FAILED:";
570  pass = false;
571  }
572  else
573  cout << "passed:";
574  cout << " it took " << long(t1) << " seconds to generate " << total << " bytes" << endl;
575 
576 #if 0 // disable this part. it's causing an unpredictable pause during the validation testing
577  if (t1 < 2)
578  {
579  // that was fast, are we really blocking?
580  // first exhaust the extropy reserve
581  t = time(NULL);
582  while (time(NULL) - t < 2)
583  {
584  test.Pump(1);
585  total += 1;
586  }
587 
588  // if it generates too many bytes in a certain amount of time,
589  // something's probably wrong
590  t = time(NULL);
591  while (time(NULL) - t < 2)
592  {
593  test.Pump(1);
594  total += 1;
595  length += 1;
596  }
597  if (length > 1024)
598  {
599  cout << "FAILED:";
600  pass = false;
601  }
602  else
603  cout << "passed:";
604  cout << " it generated " << length << " bytes in " << long(time(NULL) - t) << " seconds" << endl;
605  }
606 #endif
607 
608  test.AttachedTransformation()->MessageEnd();
609 
610  if (meter.GetTotalBytes() < total)
611  {
612  cout << "FAILED:";
613  pass = false;
614  }
615  else
616  cout << "passed:";
617  cout << " " << total << " generated bytes compressed to " << meter.GetTotalBytes() << " bytes by DEFLATE" << endl;
618  }
619  else
620  cout << "\nNo operating system provided blocking random number generator, skipping test." << endl;
621 
622  rng.reset(NULL);
623 #ifdef NONBLOCKING_RNG_AVAILABLE
624  try {rng.reset(new NonblockingRng);}
625  catch (OS_RNG_Err &) {}
626 #endif
627 
628  if (rng.get())
629  {
630  cout << "\nTesting operating system provided nonblocking random number generator...\n\n";
631 
632  MeterFilter meter(new Redirector(TheBitBucket()));
633  RandomNumberSource test(*rng, 100000, true, new Deflator(new Redirector(meter)));
634 
635  if (meter.GetTotalBytes() < 100000)
636  {
637  cout << "FAILED:";
638  pass = false;
639  }
640  else
641  cout << "passed:";
642  cout << " 100000 generated bytes compressed to " << meter.GetTotalBytes() << " bytes by DEFLATE" << endl;
643  }
644  else
645  cout << "\nNo operating system provided nonblocking random number generator, skipping test." << endl;
646 
647  return pass;
648 }
649 
650 #if NO_OS_DEPENDENCE
651 bool TestAutoSeeded()
652 {
653  return true;
654 }
655 #else
656 bool TestAutoSeeded()
657 {
658  // This tests Auto-Seeding and GenerateIntoBufferedTransformation.
659  cout << "\nTesting AutoSeeded generator...\n\n";
660 
662  bool generate = true, discard = true;
663 
664  MeterFilter meter(new Redirector(TheBitBucket()));
665  RandomNumberSource test(prng, 100000, true, new Deflator(new Redirector(meter)));
666 
667  if (meter.GetTotalBytes() < 100000)
668  {
669  cout << "FAILED:";
670  generate = false;
671  }
672  else
673  cout << "passed:";
674  cout << " 100000 generated bytes compressed to " << meter.GetTotalBytes() << " bytes by DEFLATE" << endl;
675 
676  try
677  {
678  prng.DiscardBytes(100000);
679  }
680  catch(const Exception&)
681  {
682  discard = false;
683  }
684 
685  if (!discard)
686  cout << "FAILED:";
687  else
688  cout << "passed:";
689  cout << " discarded 10000 bytes" << endl;
690 
691  return generate && discard;
692 }
693 #endif // NO_OS_DEPENDENCE
694 
695 #if (CRYPTOPP_BOOL_X86 || CRYPTOPP_BOOL_X32 || CRYPTOPP_BOOL_X64)
696 bool TestRDRAND()
697 {
698  RDRAND rdrand;
699  bool maurer = true, generate = true, discard = true;
700  static const unsigned int SIZE = 10000;
701 
702  if (HasRDRAND())
703  {
704  cout << "\nTesting RDRAND generator...\n\n";
705 
706  vector_ptr<byte> rdbytes(SIZE);
707  RandomNumberSource rns(rdrand, SIZE, true, new ArraySink(rdbytes, rdbytes.size()));
708  ArraySource as(rdbytes, rdbytes.size(), true);
709 
711  as.CopyTo(mt);
712 
713  const double mv = mt.GetTestValue();
714  if (mv < 0.98f)
715  {
716  cout << "FAILED:";
717  maurer = false;
718  }
719  else
720  cout << "passed:";
721 
722  const std::streamsize oldp = cout.precision(5);
723  const std::ios::fmtflags oldf = cout.setf(std::ios::fixed, std::ios::floatfield);
724  cout << " Maurer Randomness Test value of " << mv << endl;
725  cout.precision(oldp);
726  cout.setf(oldf, std::ios::floatfield);
727 
728  MeterFilter meter(new Redirector(TheBitBucket()));
729  as.CopyTo(meter);
730 
731  if (meter.GetTotalBytes() < SIZE)
732  {
733  cout << "FAILED:";
734  generate = false;
735  }
736  else
737  cout << "passed:";
738  cout << " " << SIZE << " generated bytes compressed to " << meter.GetTotalBytes() << " bytes by DEFLATE\n";
739 
740  try
741  {
742  rdrand.DiscardBytes(SIZE);
743  }
744  catch(const Exception&)
745  {
746  discard = false;
747  }
748 
749  if (!discard)
750  cout << "FAILED:";
751  else
752  cout << "passed:";
753  cout << " discarded " << SIZE << " bytes\n";
754  }
755  else
756  cout << "\nRDRAND generator not available, skipping test.\n";
757 
758  if (!(maurer && generate && discard))
759  cout.flush();
760 
761  return maurer && generate && discard;
762 }
763 #endif
764 
765 #if (CRYPTOPP_BOOL_X86 || CRYPTOPP_BOOL_X32 || CRYPTOPP_BOOL_X64)
766 bool TestRDSEED()
767 {
768  RDSEED rdseed;
769  bool maurer = true, generate = true, discard = true;
770  static const unsigned int SIZE = 10000;
771 
772  if (HasRDSEED())
773  {
774  cout << "\nTesting RDSEED generator...\n\n";
775 
776  vector_ptr<byte> rdbytes(SIZE);
777  RandomNumberSource rns(rdseed, SIZE, true, new ArraySink(rdbytes, rdbytes.size()));
778  ArraySource as(rdbytes, rdbytes.size(), true);
779 
781  as.CopyTo(mt);
782 
783  const double mv = mt.GetTestValue();
784  if (mv < 0.98f)
785  {
786  cout << "FAILED:";
787  maurer = false;
788  }
789  else
790  cout << "passed:";
791 
792  const std::streamsize oldp = cout.precision(5);
793  const std::ios::fmtflags oldf = cout.setf(std::ios::fixed, std::ios::floatfield);
794  cout << " Maurer Randomness Test value of " << mv << endl;
795  cout.precision(oldp);
796  cout.setf(oldf, std::ios::floatfield);
797 
798  MeterFilter meter(new Redirector(TheBitBucket()));
799  as.CopyTo(meter);
800 
801  if (meter.GetTotalBytes() < SIZE)
802  {
803  cout << "FAILED:";
804  generate = false;
805  }
806  else
807  cout << "passed:";
808  cout << " " << SIZE << " generated bytes compressed to " << meter.GetTotalBytes() << " bytes by DEFLATE\n";
809 
810  try
811  {
812  rdseed.DiscardBytes(SIZE);
813  }
814  catch(const Exception&)
815  {
816  discard = false;
817  }
818 
819  if (!discard)
820  cout << "FAILED:";
821  else
822  cout << "passed:";
823  cout << " discarded " << SIZE << " bytes\n";
824  }
825  else
826  cout << "\nRDSEED generator not available, skipping test.\n";
827 
828  if (!(maurer && generate && discard))
829  cout.flush();
830 
831  return maurer && generate && discard;
832 }
833 #endif
834 
835 // VC50 workaround
836 typedef auto_ptr<BlockTransformation> apbt;
837 
839 {
840 public:
841  virtual unsigned int BlockSize() const =0;
842  virtual unsigned int KeyLength() const =0;
843 
844  virtual apbt NewEncryption(const byte *key) const =0;
845  virtual apbt NewDecryption(const byte *key) const =0;
846 };
847 
848 template <class E, class D> class FixedRoundsCipherFactory : public CipherFactory
849 {
850 public:
851  FixedRoundsCipherFactory(unsigned int keylen=0) : m_keylen(keylen?keylen:E::DEFAULT_KEYLENGTH) {}
852  unsigned int BlockSize() const {return E::BLOCKSIZE;}
853  unsigned int KeyLength() const {return m_keylen;}
854 
855  apbt NewEncryption(const byte *key) const
856  {return apbt(new E(key, m_keylen));}
857  apbt NewDecryption(const byte *key) const
858  {return apbt(new D(key, m_keylen));}
859 
860  unsigned int m_keylen;
861 };
862 
863 template <class E, class D> class VariableRoundsCipherFactory : public CipherFactory
864 {
865 public:
866  VariableRoundsCipherFactory(unsigned int keylen=0, unsigned int rounds=0)
867  : m_keylen(keylen ? keylen : E::DEFAULT_KEYLENGTH), m_rounds(rounds ? rounds : E::DEFAULT_ROUNDS) {}
868  unsigned int BlockSize() const {return E::BLOCKSIZE;}
869  unsigned int KeyLength() const {return m_keylen;}
870 
871  apbt NewEncryption(const byte *key) const
872  {return apbt(new E(key, m_keylen, m_rounds));}
873  apbt NewDecryption(const byte *key) const
874  {return apbt(new D(key, m_keylen, m_rounds));}
875 
876  unsigned int m_keylen, m_rounds;
877 };
878 
879 bool BlockTransformationTest(const CipherFactory &cg, BufferedTransformation &valdata, unsigned int tuples = 0xffff)
880 {
881  HexEncoder output(new FileSink(cout));
882  SecByteBlock plain(cg.BlockSize()), cipher(cg.BlockSize()), out(cg.BlockSize()), outplain(cg.BlockSize());
883  SecByteBlock key(cg.KeyLength());
884  bool pass=true, fail;
885 
886  while (valdata.MaxRetrievable() && tuples--)
887  {
888  valdata.Get(key, cg.KeyLength());
889  valdata.Get(plain, cg.BlockSize());
890  valdata.Get(cipher, cg.BlockSize());
891 
892  apbt transE = cg.NewEncryption(key);
893  transE->ProcessBlock(plain, out);
894  fail = memcmp(out, cipher, cg.BlockSize()) != 0;
895 
896  apbt transD = cg.NewDecryption(key);
897  transD->ProcessBlock(out, outplain);
898  fail=fail || memcmp(outplain, plain, cg.BlockSize());
899 
900  pass = pass && !fail;
901 
902  cout << (fail ? "FAILED " : "passed ");
903  output.Put(key, cg.KeyLength());
904  cout << " ";
905  output.Put(outplain, cg.BlockSize());
906  cout << " ";
907  output.Put(out, cg.BlockSize());
908  cout << endl;
909  }
910  return pass;
911 }
912 
913 class FilterTester : public Unflushable<Sink>
914 {
915 public:
916  FilterTester(const byte *validOutput, size_t outputLen)
917  : validOutput(validOutput), outputLen(outputLen), counter(0), fail(false) {}
918  void PutByte(byte inByte)
919  {
920  if (counter >= outputLen || validOutput[counter] != inByte)
921  {
922  std::cerr << "incorrect output " << counter << ", " << (word16)validOutput[counter] << ", " << (word16)inByte << "\n";
923  fail = true;
924  assert(false);
925  }
926  counter++;
927  }
928  size_t Put2(const byte *inString, size_t length, int messageEnd, bool blocking)
929  {
930  CRYPTOPP_UNUSED(messageEnd), CRYPTOPP_UNUSED(blocking);
931 
932  while (length--)
933  FilterTester::PutByte(*inString++);
934 
935  if (messageEnd)
936  if (counter != outputLen)
937  {
938  fail = true;
939  assert(false);
940  }
941 
942  return 0;
943  }
944  bool GetResult()
945  {
946  return !fail;
947  }
948 
949  const byte *validOutput;
950  size_t outputLen, counter;
951  bool fail;
952 };
953 
954 bool TestFilter(BufferedTransformation &bt, const byte *in, size_t inLen, const byte *out, size_t outLen)
955 {
956  FilterTester *ft;
957  bt.Attach(ft = new FilterTester(out, outLen));
958 
959  while (inLen)
960  {
961  size_t randomLen = GlobalRNG().GenerateWord32(0, (word32)inLen);
962  bt.Put(in, randomLen);
963  in += randomLen;
964  inLen -= randomLen;
965  }
966  bt.MessageEnd();
967  return ft->GetResult();
968 }
969 
970 bool ValidateDES()
971 {
972  cout << "\nDES validation suite running...\n\n";
973 
974  FileSource valdata(PACKAGE_DATA_DIR "TestData/descert.dat", true, new HexDecoder);
975  bool pass = BlockTransformationTest(FixedRoundsCipherFactory<DESEncryption, DESDecryption>(), valdata);
976 
977  cout << "\nTesting EDE2, EDE3, and XEX3 variants...\n\n";
978 
979  FileSource valdata1(PACKAGE_DATA_DIR "TestData/3desval.dat", true, new HexDecoder);
980  pass = BlockTransformationTest(FixedRoundsCipherFactory<DES_EDE2_Encryption, DES_EDE2_Decryption>(), valdata1, 1) && pass;
981  pass = BlockTransformationTest(FixedRoundsCipherFactory<DES_EDE3_Encryption, DES_EDE3_Decryption>(), valdata1, 1) && pass;
982  pass = BlockTransformationTest(FixedRoundsCipherFactory<DES_XEX3_Encryption, DES_XEX3_Decryption>(), valdata1, 1) && pass;
983 
984  return pass;
985 }
986 
987 bool TestModeIV(SymmetricCipher &e, SymmetricCipher &d)
988 {
989  SecByteBlock lastIV, iv(e.IVSize());
991 
992  // vector_ptr<byte> due to Enterprise Analysis finding on the stack based array.
993  vector_ptr<byte> plaintext(20480);
994 
995  for (unsigned int i=1; i<20480; i*=2)
996  {
997  e.GetNextIV(GlobalRNG(), iv);
998  if (iv == lastIV)
999  return false;
1000  else
1001  lastIV = iv;
1002 
1003  e.Resynchronize(iv);
1004  d.Resynchronize(iv);
1005 
1006  unsigned int length = STDMAX(GlobalRNG().GenerateWord32(0, i), (word32)e.MinLastBlockSize());
1007  GlobalRNG().GenerateBlock(plaintext, length);
1008 
1009  if (!TestFilter(filter, plaintext, length, plaintext, length))
1010  return false;
1011  }
1012 
1013  return true;
1014 }
1015 
1016 bool ValidateCipherModes()
1017 {
1018  cout << "\nTesting DES modes...\n\n";
1019  const byte key[] = {0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef};
1020  const byte iv[] = {0x12,0x34,0x56,0x78,0x90,0xab,0xcd,0xef};
1021  const byte plain[] = { // "Now is the time for all " without tailing 0
1022  0x4e,0x6f,0x77,0x20,0x69,0x73,0x20,0x74,
1023  0x68,0x65,0x20,0x74,0x69,0x6d,0x65,0x20,
1024  0x66,0x6f,0x72,0x20,0x61,0x6c,0x6c,0x20};
1025  DESEncryption desE(key);
1026  DESDecryption desD(key);
1027  bool pass=true, fail;
1028 
1029  {
1030  // from FIPS 81
1031  const byte encrypted[] = {
1032  0x3f, 0xa4, 0x0e, 0x8a, 0x98, 0x4d, 0x48, 0x15,
1033  0x6a, 0x27, 0x17, 0x87, 0xab, 0x88, 0x83, 0xf9,
1034  0x89, 0x3d, 0x51, 0xec, 0x4b, 0x56, 0x3b, 0x53};
1035 
1037  fail = !TestFilter(StreamTransformationFilter(modeE, NULL, StreamTransformationFilter::NO_PADDING).Ref(),
1038  plain, sizeof(plain), encrypted, sizeof(encrypted));
1039  pass = pass && !fail;
1040  cout << (fail ? "FAILED " : "passed ") << "ECB encryption" << endl;
1041 
1043  fail = !TestFilter(StreamTransformationFilter(modeD, NULL, StreamTransformationFilter::NO_PADDING).Ref(),
1044  encrypted, sizeof(encrypted), plain, sizeof(plain));
1045  pass = pass && !fail;
1046  cout << (fail ? "FAILED " : "passed ") << "ECB decryption" << endl;
1047  }
1048  {
1049  // from FIPS 81
1050  const byte encrypted[] = {
1051  0xE5, 0xC7, 0xCD, 0xDE, 0x87, 0x2B, 0xF2, 0x7C,
1052  0x43, 0xE9, 0x34, 0x00, 0x8C, 0x38, 0x9C, 0x0F,
1053  0x68, 0x37, 0x88, 0x49, 0x9A, 0x7C, 0x05, 0xF6};
1054 
1055  CBC_Mode_ExternalCipher::Encryption modeE(desE, iv);
1056  fail = !TestFilter(StreamTransformationFilter(modeE, NULL, StreamTransformationFilter::NO_PADDING).Ref(),
1057  plain, sizeof(plain), encrypted, sizeof(encrypted));
1058  pass = pass && !fail;
1059  cout << (fail ? "FAILED " : "passed ") << "CBC encryption with no padding" << endl;
1060 
1061  CBC_Mode_ExternalCipher::Decryption modeD(desD, iv);
1062  fail = !TestFilter(StreamTransformationFilter(modeD, NULL, StreamTransformationFilter::NO_PADDING).Ref(),
1063  encrypted, sizeof(encrypted), plain, sizeof(plain));
1064  pass = pass && !fail;
1065  cout << (fail ? "FAILED " : "passed ") << "CBC decryption with no padding" << endl;
1066 
1067  fail = !TestModeIV(modeE, modeD);
1068  pass = pass && !fail;
1069  cout << (fail ? "FAILED " : "passed ") << "CBC mode IV generation" << endl;
1070  }
1071  {
1072  // generated with Crypto++, matches FIPS 81
1073  // but has extra 8 bytes as result of padding
1074  const byte encrypted[] = {
1075  0xE5, 0xC7, 0xCD, 0xDE, 0x87, 0x2B, 0xF2, 0x7C,
1076  0x43, 0xE9, 0x34, 0x00, 0x8C, 0x38, 0x9C, 0x0F,
1077  0x68, 0x37, 0x88, 0x49, 0x9A, 0x7C, 0x05, 0xF6,
1078  0x62, 0xC1, 0x6A, 0x27, 0xE4, 0xFC, 0xF2, 0x77};
1079 
1080  CBC_Mode_ExternalCipher::Encryption modeE(desE, iv);
1081  fail = !TestFilter(StreamTransformationFilter(modeE).Ref(),
1082  plain, sizeof(plain), encrypted, sizeof(encrypted));
1083  pass = pass && !fail;
1084  cout << (fail ? "FAILED " : "passed ") << "CBC encryption with PKCS #7 padding" << endl;
1085 
1086  CBC_Mode_ExternalCipher::Decryption modeD(desD, iv);
1087  fail = !TestFilter(StreamTransformationFilter(modeD).Ref(),
1088  encrypted, sizeof(encrypted), plain, sizeof(plain));
1089  pass = pass && !fail;
1090  cout << (fail ? "FAILED " : "passed ") << "CBC decryption with PKCS #7 padding" << endl;
1091  }
1092  {
1093  // generated with Crypto++ 5.2, matches FIPS 81
1094  // but has extra 8 bytes as result of padding
1095  const byte encrypted[] = {
1096  0xE5, 0xC7, 0xCD, 0xDE, 0x87, 0x2B, 0xF2, 0x7C,
1097  0x43, 0xE9, 0x34, 0x00, 0x8C, 0x38, 0x9C, 0x0F,
1098  0x68, 0x37, 0x88, 0x49, 0x9A, 0x7C, 0x05, 0xF6,
1099  0xcf, 0xb7, 0xc7, 0x64, 0x0e, 0x7c, 0xd9, 0xa7};
1100 
1101  CBC_Mode_ExternalCipher::Encryption modeE(desE, iv);
1103  plain, sizeof(plain), encrypted, sizeof(encrypted));
1104  pass = pass && !fail;
1105  cout << (fail ? "FAILED " : "passed ") << "CBC encryption with one-and-zeros padding" << endl;
1106 
1107  CBC_Mode_ExternalCipher::Decryption modeD(desD, iv);
1109  encrypted, sizeof(encrypted), plain, sizeof(plain));
1110  pass = pass && !fail;
1111  cout << (fail ? "FAILED " : "passed ") << "CBC decryption with one-and-zeros padding" << endl;
1112  }
1113  {
1114  const byte plain_1[] = {'a', 0, 0, 0, 0, 0, 0, 0};
1115  // generated with Crypto++
1116  const byte encrypted[] = {
1117  0x9B, 0x47, 0x57, 0x59, 0xD6, 0x9C, 0xF6, 0xD0};
1118 
1119  CBC_Mode_ExternalCipher::Encryption modeE(desE, iv);
1120  fail = !TestFilter(StreamTransformationFilter(modeE, NULL, StreamTransformationFilter::ZEROS_PADDING).Ref(),
1121  plain_1, 1, encrypted, sizeof(encrypted));
1122  pass = pass && !fail;
1123  cout << (fail ? "FAILED " : "passed ") << "CBC encryption with zeros padding" << endl;
1124 
1125  CBC_Mode_ExternalCipher::Decryption modeD(desD, iv);
1126  fail = !TestFilter(StreamTransformationFilter(modeD, NULL, StreamTransformationFilter::ZEROS_PADDING).Ref(),
1127  encrypted, sizeof(encrypted), plain_1, sizeof(plain_1));
1128  pass = pass && !fail;
1129  cout << (fail ? "FAILED " : "passed ") << "CBC decryption with zeros padding" << endl;
1130  }
1131  {
1132  // generated with Crypto++, matches FIPS 81
1133  // but with last two blocks swapped as result of CTS
1134  const byte encrypted[] = {
1135  0xE5, 0xC7, 0xCD, 0xDE, 0x87, 0x2B, 0xF2, 0x7C,
1136  0x68, 0x37, 0x88, 0x49, 0x9A, 0x7C, 0x05, 0xF6,
1137  0x43, 0xE9, 0x34, 0x00, 0x8C, 0x38, 0x9C, 0x0F};
1138 
1140  fail = !TestFilter(StreamTransformationFilter(modeE).Ref(),
1141  plain, sizeof(plain), encrypted, sizeof(encrypted));
1142  pass = pass && !fail;
1143  cout << (fail ? "FAILED " : "passed ") << "CBC encryption with ciphertext stealing (CTS)" << endl;
1144 
1146  fail = !TestFilter(StreamTransformationFilter(modeD).Ref(),
1147  encrypted, sizeof(encrypted), plain, sizeof(plain));
1148  pass = pass && !fail;
1149  cout << (fail ? "FAILED " : "passed ") << "CBC decryption with ciphertext stealing (CTS)" << endl;
1150 
1151  fail = !TestModeIV(modeE, modeD);
1152  pass = pass && !fail;
1153  cout << (fail ? "FAILED " : "passed ") << "CBC CTS IV generation" << endl;
1154  }
1155  {
1156  // generated with Crypto++
1157  const byte decryptionIV[] = {0x4D, 0xD0, 0xAC, 0x8F, 0x47, 0xCF, 0x79, 0xCE};
1158  const byte encrypted[] = {0x12, 0x34, 0x56};
1159 
1160  byte stolenIV[8];
1161 
1163  modeE.SetStolenIV(stolenIV);
1164  fail = !TestFilter(StreamTransformationFilter(modeE).Ref(),
1165  plain, 3, encrypted, sizeof(encrypted));
1166  fail = memcmp(stolenIV, decryptionIV, 8) != 0 || fail;
1167  pass = pass && !fail;
1168  cout << (fail ? "FAILED " : "passed ") << "CBC encryption with ciphertext and IV stealing" << endl;
1169 
1170  CBC_CTS_Mode_ExternalCipher::Decryption modeD(desD, stolenIV);
1171  fail = !TestFilter(StreamTransformationFilter(modeD).Ref(),
1172  encrypted, sizeof(encrypted), plain, 3);
1173  pass = pass && !fail;
1174  cout << (fail ? "FAILED " : "passed ") << "CBC decryption with ciphertext and IV stealing" << endl;
1175  }
1176  {
1177  const byte encrypted[] = { // from FIPS 81
1178  0xF3,0x09,0x62,0x49,0xC7,0xF4,0x6E,0x51,
1179  0xA6,0x9E,0x83,0x9B,0x1A,0x92,0xF7,0x84,
1180  0x03,0x46,0x71,0x33,0x89,0x8E,0xA6,0x22};
1181 
1182  CFB_Mode_ExternalCipher::Encryption modeE(desE, iv);
1183  fail = !TestFilter(StreamTransformationFilter(modeE).Ref(),
1184  plain, sizeof(plain), encrypted, sizeof(encrypted));
1185  pass = pass && !fail;
1186  cout << (fail ? "FAILED " : "passed ") << "CFB encryption" << endl;
1187 
1188  CFB_Mode_ExternalCipher::Decryption modeD(desE, iv);
1189  fail = !TestFilter(StreamTransformationFilter(modeD).Ref(),
1190  encrypted, sizeof(encrypted), plain, sizeof(plain));
1191  pass = pass && !fail;
1192  cout << (fail ? "FAILED " : "passed ") << "CFB decryption" << endl;
1193 
1194  fail = !TestModeIV(modeE, modeD);
1195  pass = pass && !fail;
1196  cout << (fail ? "FAILED " : "passed ") << "CFB mode IV generation" << endl;
1197  }
1198  {
1199  const byte plain_2[] = { // "Now is the." without tailing 0
1200  0x4e,0x6f,0x77,0x20,0x69,0x73,0x20,0x74,0x68,0x65};
1201  const byte encrypted[] = { // from FIPS 81
1202  0xf3,0x1f,0xda,0x07,0x01,0x14,0x62,0xee,0x18,0x7f};
1203 
1204  CFB_Mode_ExternalCipher::Encryption modeE(desE, iv, 1);
1205  fail = !TestFilter(StreamTransformationFilter(modeE).Ref(),
1206  plain_2, sizeof(plain_2), encrypted, sizeof(encrypted));
1207  pass = pass && !fail;
1208  cout << (fail ? "FAILED " : "passed ") << "CFB (8-bit feedback) encryption" << endl;
1209 
1210  CFB_Mode_ExternalCipher::Decryption modeD(desE, iv, 1);
1211  fail = !TestFilter(StreamTransformationFilter(modeD).Ref(),
1212  encrypted, sizeof(encrypted), plain_2, sizeof(plain_2));
1213  pass = pass && !fail;
1214  cout << (fail ? "FAILED " : "passed ") << "CFB (8-bit feedback) decryption" << endl;
1215 
1216  fail = !TestModeIV(modeE, modeD);
1217  pass = pass && !fail;
1218  cout << (fail ? "FAILED " : "passed ") << "CFB (8-bit feedback) IV generation" << endl;
1219  }
1220  {
1221  const byte encrypted[] = { // from Eric Young's libdes
1222  0xf3,0x09,0x62,0x49,0xc7,0xf4,0x6e,0x51,
1223  0x35,0xf2,0x4a,0x24,0x2e,0xeb,0x3d,0x3f,
1224  0x3d,0x6d,0x5b,0xe3,0x25,0x5a,0xf8,0xc3};
1225 
1226  OFB_Mode_ExternalCipher::Encryption modeE(desE, iv);
1227  fail = !TestFilter(StreamTransformationFilter(modeE).Ref(),
1228  plain, sizeof(plain), encrypted, sizeof(encrypted));
1229  pass = pass && !fail;
1230  cout << (fail ? "FAILED " : "passed ") << "OFB encryption" << endl;
1231 
1232  OFB_Mode_ExternalCipher::Decryption modeD(desE, iv);
1233  fail = !TestFilter(StreamTransformationFilter(modeD).Ref(),
1234  encrypted, sizeof(encrypted), plain, sizeof(plain));
1235  pass = pass && !fail;
1236  cout << (fail ? "FAILED " : "passed ") << "OFB decryption" << endl;
1237 
1238  fail = !TestModeIV(modeE, modeD);
1239  pass = pass && !fail;
1240  cout << (fail ? "FAILED " : "passed ") << "OFB IV generation" << endl;
1241  }
1242  {
1243  const byte encrypted[] = { // generated with Crypto++
1244  0xF3, 0x09, 0x62, 0x49, 0xC7, 0xF4, 0x6E, 0x51,
1245  0x16, 0x3A, 0x8C, 0xA0, 0xFF, 0xC9, 0x4C, 0x27,
1246  0xFA, 0x2F, 0x80, 0xF4, 0x80, 0xB8, 0x6F, 0x75};
1247 
1248  CTR_Mode_ExternalCipher::Encryption modeE(desE, iv);
1249  fail = !TestFilter(StreamTransformationFilter(modeE).Ref(),
1250  plain, sizeof(plain), encrypted, sizeof(encrypted));
1251  pass = pass && !fail;
1252  cout << (fail ? "FAILED " : "passed ") << "Counter Mode encryption" << endl;
1253 
1254  CTR_Mode_ExternalCipher::Decryption modeD(desE, iv);
1255  fail = !TestFilter(StreamTransformationFilter(modeD).Ref(),
1256  encrypted, sizeof(encrypted), plain, sizeof(plain));
1257  pass = pass && !fail;
1258  cout << (fail ? "FAILED " : "passed ") << "Counter Mode decryption" << endl;
1259 
1260  fail = !TestModeIV(modeE, modeD);
1261  pass = pass && !fail;
1262  cout << (fail ? "FAILED " : "passed ") << "Counter Mode IV generation" << endl;
1263  }
1264  {
1265  const byte plain_3[] = { // "7654321 Now is the time for "
1266  0x37, 0x36, 0x35, 0x34, 0x33, 0x32, 0x31, 0x20,
1267  0x4e, 0x6f, 0x77, 0x20, 0x69, 0x73, 0x20, 0x74,
1268  0x68, 0x65, 0x20, 0x74, 0x69, 0x6d, 0x65, 0x20,
1269  0x66, 0x6f, 0x72, 0x20};
1270  const byte mac1[] = { // from FIPS 113
1271  0xf1, 0xd3, 0x0f, 0x68, 0x49, 0x31, 0x2c, 0xa4};
1272  const byte mac2[] = { // generated with Crypto++
1273  0x35, 0x80, 0xC5, 0xC4, 0x6B, 0x81, 0x24, 0xE2};
1274 
1275  CBC_MAC<DES> cbcmac(key);
1276  HashFilter cbcmacFilter(cbcmac);
1277  fail = !TestFilter(cbcmacFilter, plain_3, sizeof(plain_3), mac1, sizeof(mac1));
1278  pass = pass && !fail;
1279  cout << (fail ? "FAILED " : "passed ") << "CBC MAC" << endl;
1280 
1281  DMAC<DES> dmac(key);
1282  HashFilter dmacFilter(dmac);
1283  fail = !TestFilter(dmacFilter, plain_3, sizeof(plain_3), mac2, sizeof(mac2));
1284  pass = pass && !fail;
1285  cout << (fail ? "FAILED " : "passed ") << "DMAC" << endl;
1286  }
1287  {
1288  CTR_Mode<AES>::Encryption modeE(plain, 16, plain);
1289  CTR_Mode<AES>::Decryption modeD(plain, 16, plain);
1290  fail = !TestModeIV(modeE, modeD);
1291  pass = pass && !fail;
1292  cout << (fail ? "FAILED " : "passed ") << "AES CTR Mode" << endl;
1293  }
1294  {
1295  OFB_Mode<AES>::Encryption modeE(plain, 16, plain);
1296  OFB_Mode<AES>::Decryption modeD(plain, 16, plain);
1297  fail = !TestModeIV(modeE, modeD);
1298  pass = pass && !fail;
1299  cout << (fail ? "FAILED " : "passed ") << "AES OFB Mode" << endl;
1300  }
1301  {
1302  CFB_Mode<AES>::Encryption modeE(plain, 16, plain);
1303  CFB_Mode<AES>::Decryption modeD(plain, 16, plain);
1304  fail = !TestModeIV(modeE, modeD);
1305  pass = pass && !fail;
1306  cout << (fail ? "FAILED " : "passed ") << "AES CFB Mode" << endl;
1307  }
1308  {
1309  CBC_Mode<AES>::Encryption modeE(plain, 16, plain);
1310  CBC_Mode<AES>::Decryption modeD(plain, 16, plain);
1311  fail = !TestModeIV(modeE, modeD);
1312  pass = pass && !fail;
1313  cout << (fail ? "FAILED " : "passed ") << "AES CBC Mode" << endl;
1314  }
1315 
1316  return pass;
1317 }
1318 
1319 bool ValidateIDEA()
1320 {
1321  cout << "\nIDEA validation suite running...\n\n";
1322 
1323  FileSource valdata(PACKAGE_DATA_DIR "TestData/ideaval.dat", true, new HexDecoder);
1324  return BlockTransformationTest(FixedRoundsCipherFactory<IDEAEncryption, IDEADecryption>(), valdata);
1325 }
1326 
1327 bool ValidateSAFER()
1328 {
1329  cout << "\nSAFER validation suite running...\n\n";
1330 
1331  FileSource valdata(PACKAGE_DATA_DIR "TestData/saferval.dat", true, new HexDecoder);
1332  bool pass = true;
1333  pass = BlockTransformationTest(VariableRoundsCipherFactory<SAFER_K_Encryption, SAFER_K_Decryption>(8,6), valdata, 4) && pass;
1334  pass = BlockTransformationTest(VariableRoundsCipherFactory<SAFER_K_Encryption, SAFER_K_Decryption>(16,12), valdata, 4) && pass;
1335  pass = BlockTransformationTest(VariableRoundsCipherFactory<SAFER_SK_Encryption, SAFER_SK_Decryption>(8,6), valdata, 4) && pass;
1336  pass = BlockTransformationTest(VariableRoundsCipherFactory<SAFER_SK_Encryption, SAFER_SK_Decryption>(16,10), valdata, 4) && pass;
1337  return pass;
1338 }
1339 
1340 bool ValidateRC2()
1341 {
1342  cout << "\nRC2 validation suite running...\n\n";
1343 
1344  FileSource valdata(PACKAGE_DATA_DIR "TestData/rc2val.dat", true, new HexDecoder);
1345  HexEncoder output(new FileSink(cout));
1346  SecByteBlock plain(RC2Encryption::BLOCKSIZE), cipher(RC2Encryption::BLOCKSIZE), out(RC2Encryption::BLOCKSIZE), outplain(RC2Encryption::BLOCKSIZE);
1347  SecByteBlock key(128);
1348  bool pass=true, fail;
1349 
1350  while (valdata.MaxRetrievable())
1351  {
1352  byte keyLen, effectiveLen;
1353 
1354  valdata.Get(keyLen);
1355  valdata.Get(effectiveLen);
1356  valdata.Get(key, keyLen);
1357  valdata.Get(plain, RC2Encryption::BLOCKSIZE);
1358  valdata.Get(cipher, RC2Encryption::BLOCKSIZE);
1359 
1360  apbt transE(new RC2Encryption(key, keyLen, effectiveLen));
1361  transE->ProcessBlock(plain, out);
1362  fail = memcmp(out, cipher, RC2Encryption::BLOCKSIZE) != 0;
1363 
1364  apbt transD(new RC2Decryption(key, keyLen, effectiveLen));
1365  transD->ProcessBlock(out, outplain);
1366  fail=fail || memcmp(outplain, plain, RC2Encryption::BLOCKSIZE);
1367 
1368  pass = pass && !fail;
1369 
1370  cout << (fail ? "FAILED " : "passed ");
1371  output.Put(key, keyLen);
1372  cout << " ";
1373  output.Put(outplain, RC2Encryption::BLOCKSIZE);
1374  cout << " ";
1375  output.Put(out, RC2Encryption::BLOCKSIZE);
1376  cout << endl;
1377  }
1378  return pass;
1379 }
1380 
1381 bool ValidateARC4()
1382 {
1383  unsigned char Key0[] = {0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef };
1384  unsigned char Input0[]={0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef};
1385  unsigned char Output0[] = {0x75,0xb7,0x87,0x80,0x99,0xe0,0xc5,0x96};
1386 
1387  unsigned char Key1[]={0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef};
1388  unsigned char Input1[]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
1389  unsigned char Output1[]={0x74,0x94,0xc2,0xe7,0x10,0x4b,0x08,0x79};
1390 
1391  unsigned char Key2[]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
1392  unsigned char Input2[]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
1393  unsigned char Output2[]={0xde,0x18,0x89,0x41,0xa3,0x37,0x5d,0x3a};
1394 
1395  unsigned char Key3[]={0xef,0x01,0x23,0x45};
1396  unsigned char Input3[]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
1397  unsigned char Output3[]={0xd6,0xa1,0x41,0xa7,0xec,0x3c,0x38,0xdf,0xbd,0x61};
1398 
1399  unsigned char Key4[]={ 0x01,0x23,0x45,0x67,0x89,0xab, 0xcd,0xef };
1400  unsigned char Input4[] =
1401  {0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
1402  0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
1403  0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
1404  0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
1405  0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
1406  0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
1407  0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
1408  0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
1409  0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
1410  0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
1411  0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
1412  0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
1413  0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
1414  0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
1415  0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
1416  0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
1417  0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
1418  0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
1419  0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
1420  0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
1421  0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
1422  0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
1423  0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
1424  0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
1425  0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
1426  0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
1427  0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
1428  0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
1429  0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
1430  0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
1431  0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
1432  0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
1433  0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
1434  0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
1435  0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
1436  0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
1437  0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
1438  0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
1439  0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
1440  0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
1441  0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
1442  0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
1443  0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
1444  0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
1445  0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
1446  0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
1447  0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
1448  0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
1449  0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
1450  0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
1451  0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
1452  0x01};
1453  unsigned char Output4[]= {
1454  0x75,0x95,0xc3,0xe6,0x11,0x4a,0x09,0x78,0x0c,0x4a,0xd4,
1455  0x52,0x33,0x8e,0x1f,0xfd,0x9a,0x1b,0xe9,0x49,0x8f,
1456  0x81,0x3d,0x76,0x53,0x34,0x49,0xb6,0x77,0x8d,0xca,
1457  0xd8,0xc7,0x8a,0x8d,0x2b,0xa9,0xac,0x66,0x08,0x5d,
1458  0x0e,0x53,0xd5,0x9c,0x26,0xc2,0xd1,0xc4,0x90,0xc1,
1459  0xeb,0xbe,0x0c,0xe6,0x6d,0x1b,0x6b,0x1b,0x13,0xb6,
1460  0xb9,0x19,0xb8,0x47,0xc2,0x5a,0x91,0x44,0x7a,0x95,
1461  0xe7,0x5e,0x4e,0xf1,0x67,0x79,0xcd,0xe8,0xbf,0x0a,
1462  0x95,0x85,0x0e,0x32,0xaf,0x96,0x89,0x44,0x4f,0xd3,
1463  0x77,0x10,0x8f,0x98,0xfd,0xcb,0xd4,0xe7,0x26,0x56,
1464  0x75,0x00,0x99,0x0b,0xcc,0x7e,0x0c,0xa3,0xc4,0xaa,
1465  0xa3,0x04,0xa3,0x87,0xd2,0x0f,0x3b,0x8f,0xbb,0xcd,
1466  0x42,0xa1,0xbd,0x31,0x1d,0x7a,0x43,0x03,0xdd,0xa5,
1467  0xab,0x07,0x88,0x96,0xae,0x80,0xc1,0x8b,0x0a,0xf6,
1468  0x6d,0xff,0x31,0x96,0x16,0xeb,0x78,0x4e,0x49,0x5a,
1469  0xd2,0xce,0x90,0xd7,0xf7,0x72,0xa8,0x17,0x47,0xb6,
1470  0x5f,0x62,0x09,0x3b,0x1e,0x0d,0xb9,0xe5,0xba,0x53,
1471  0x2f,0xaf,0xec,0x47,0x50,0x83,0x23,0xe6,0x71,0x32,
1472  0x7d,0xf9,0x44,0x44,0x32,0xcb,0x73,0x67,0xce,0xc8,
1473  0x2f,0x5d,0x44,0xc0,0xd0,0x0b,0x67,0xd6,0x50,0xa0,
1474  0x75,0xcd,0x4b,0x70,0xde,0xdd,0x77,0xeb,0x9b,0x10,
1475  0x23,0x1b,0x6b,0x5b,0x74,0x13,0x47,0x39,0x6d,0x62,
1476  0x89,0x74,0x21,0xd4,0x3d,0xf9,0xb4,0x2e,0x44,0x6e,
1477  0x35,0x8e,0x9c,0x11,0xa9,0xb2,0x18,0x4e,0xcb,0xef,
1478  0x0c,0xd8,0xe7,0xa8,0x77,0xef,0x96,0x8f,0x13,0x90,
1479  0xec,0x9b,0x3d,0x35,0xa5,0x58,0x5c,0xb0,0x09,0x29,
1480  0x0e,0x2f,0xcd,0xe7,0xb5,0xec,0x66,0xd9,0x08,0x4b,
1481  0xe4,0x40,0x55,0xa6,0x19,0xd9,0xdd,0x7f,0xc3,0x16,
1482  0x6f,0x94,0x87,0xf7,0xcb,0x27,0x29,0x12,0x42,0x64,
1483  0x45,0x99,0x85,0x14,0xc1,0x5d,0x53,0xa1,0x8c,0x86,
1484  0x4c,0xe3,0xa2,0xb7,0x55,0x57,0x93,0x98,0x81,0x26,
1485  0x52,0x0e,0xac,0xf2,0xe3,0x06,0x6e,0x23,0x0c,0x91,
1486  0xbe,0xe4,0xdd,0x53,0x04,0xf5,0xfd,0x04,0x05,0xb3,
1487  0x5b,0xd9,0x9c,0x73,0x13,0x5d,0x3d,0x9b,0xc3,0x35,
1488  0xee,0x04,0x9e,0xf6,0x9b,0x38,0x67,0xbf,0x2d,0x7b,
1489  0xd1,0xea,0xa5,0x95,0xd8,0xbf,0xc0,0x06,0x6f,0xf8,
1490  0xd3,0x15,0x09,0xeb,0x0c,0x6c,0xaa,0x00,0x6c,0x80,
1491  0x7a,0x62,0x3e,0xf8,0x4c,0x3d,0x33,0xc1,0x95,0xd2,
1492  0x3e,0xe3,0x20,0xc4,0x0d,0xe0,0x55,0x81,0x57,0xc8,
1493  0x22,0xd4,0xb8,0xc5,0x69,0xd8,0x49,0xae,0xd5,0x9d,
1494  0x4e,0x0f,0xd7,0xf3,0x79,0x58,0x6b,0x4b,0x7f,0xf6,
1495  0x84,0xed,0x6a,0x18,0x9f,0x74,0x86,0xd4,0x9b,0x9c,
1496  0x4b,0xad,0x9b,0xa2,0x4b,0x96,0xab,0xf9,0x24,0x37,
1497  0x2c,0x8a,0x8f,0xff,0xb1,0x0d,0x55,0x35,0x49,0x00,
1498  0xa7,0x7a,0x3d,0xb5,0xf2,0x05,0xe1,0xb9,0x9f,0xcd,
1499  0x86,0x60,0x86,0x3a,0x15,0x9a,0xd4,0xab,0xe4,0x0f,
1500  0xa4,0x89,0x34,0x16,0x3d,0xdd,0xe5,0x42,0xa6,0x58,
1501  0x55,0x40,0xfd,0x68,0x3c,0xbf,0xd8,0xc0,0x0f,0x12,
1502  0x12,0x9a,0x28,0x4d,0xea,0xcc,0x4c,0xde,0xfe,0x58,
1503  0xbe,0x71,0x37,0x54,0x1c,0x04,0x71,0x26,0xc8,0xd4,
1504  0x9e,0x27,0x55,0xab,0x18,0x1a,0xb7,0xe9,0x40,0xb0,
1505  0xc0};
1506 
1507  // VC60 workaround: auto_ptr lacks reset()
1509  bool pass=true, fail;
1510  unsigned int i;
1511 
1512  cout << "\nARC4 validation suite running...\n\n";
1513 
1514  arc4.reset(new Weak::ARC4(Key0, sizeof(Key0)));
1515  arc4->ProcessString(Input0, sizeof(Input0));
1516  fail = memcmp(Input0, Output0, sizeof(Input0)) != 0;
1517  cout << (fail ? "FAILED" : "passed") << " Test 0" << endl;
1518  pass = pass && !fail;
1519 
1520  arc4.reset(new Weak::ARC4(Key1, sizeof(Key1)));
1521  arc4->ProcessString(Key1, Input1, sizeof(Key1));
1522  fail = memcmp(Output1, Key1, sizeof(Key1)) != 0;
1523  cout << (fail ? "FAILED" : "passed") << " Test 1" << endl;
1524  pass = pass && !fail;
1525 
1526  arc4.reset(new Weak::ARC4(Key2, sizeof(Key2)));
1527  for (i=0, fail=false; i<sizeof(Input2); i++)
1528  if (arc4->ProcessByte(Input2[i]) != Output2[i])
1529  fail = true;
1530  cout << (fail ? "FAILED" : "passed") << " Test 2" << endl;
1531  pass = pass && !fail;
1532 
1533  arc4.reset(new Weak::ARC4(Key3, sizeof(Key3)));
1534  for (i=0, fail=false; i<sizeof(Input3); i++)
1535  if (arc4->ProcessByte(Input3[i]) != Output3[i])
1536  fail = true;
1537  cout << (fail ? "FAILED" : "passed") << " Test 3" << endl;
1538  pass = pass && !fail;
1539 
1540  arc4.reset(new Weak::ARC4(Key4, sizeof(Key4)));
1541  for (i=0, fail=false; i<sizeof(Input4); i++)
1542  if (arc4->ProcessByte(Input4[i]) != Output4[i])
1543  fail = true;
1544  cout << (fail ? "FAILED" : "passed") << " Test 4" << endl;
1545  pass = pass && !fail;
1546 
1547  return pass;
1548 }
1549 
1550 bool ValidateRC5()
1551 {
1552  cout << "\nRC5 validation suite running...\n\n";
1553 
1554  FileSource valdata(PACKAGE_DATA_DIR "TestData/rc5val.dat", true, new HexDecoder);
1555  return BlockTransformationTest(VariableRoundsCipherFactory<RC5Encryption, RC5Decryption>(16, 12), valdata);
1556 }
1557 
1558 bool ValidateRC6()
1559 {
1560  cout << "\nRC6 validation suite running...\n\n";
1561 
1562  FileSource valdata(PACKAGE_DATA_DIR "TestData/rc6val.dat", true, new HexDecoder);
1563  bool pass = true;
1564  pass = BlockTransformationTest(FixedRoundsCipherFactory<RC6Encryption, RC6Decryption>(16), valdata, 2) && pass;
1565  pass = BlockTransformationTest(FixedRoundsCipherFactory<RC6Encryption, RC6Decryption>(24), valdata, 2) && pass;
1566  pass = BlockTransformationTest(FixedRoundsCipherFactory<RC6Encryption, RC6Decryption>(32), valdata, 2) && pass;
1567  return pass;
1568 }
1569 
1570 bool ValidateMARS()
1571 {
1572  cout << "\nMARS validation suite running...\n\n";
1573 
1574  FileSource valdata(PACKAGE_DATA_DIR "TestData/marsval.dat", true, new HexDecoder);
1575  bool pass = true;
1576  pass = BlockTransformationTest(FixedRoundsCipherFactory<MARSEncryption, MARSDecryption>(16), valdata, 4) && pass;
1577  pass = BlockTransformationTest(FixedRoundsCipherFactory<MARSEncryption, MARSDecryption>(24), valdata, 3) && pass;
1578  pass = BlockTransformationTest(FixedRoundsCipherFactory<MARSEncryption, MARSDecryption>(32), valdata, 2) && pass;
1579  return pass;
1580 }
1581 
1582 bool ValidateRijndael()
1583 {
1584  cout << "\nRijndael (AES) validation suite running...\n\n";
1585 
1586  FileSource valdata(PACKAGE_DATA_DIR "TestData/rijndael.dat", true, new HexDecoder);
1587  bool pass = true;
1588  pass = BlockTransformationTest(FixedRoundsCipherFactory<RijndaelEncryption, RijndaelDecryption>(16), valdata, 4) && pass;
1589  pass = BlockTransformationTest(FixedRoundsCipherFactory<RijndaelEncryption, RijndaelDecryption>(24), valdata, 3) && pass;
1590  pass = BlockTransformationTest(FixedRoundsCipherFactory<RijndaelEncryption, RijndaelDecryption>(32), valdata, 2) && pass;
1591  pass = RunTestDataFile(PACKAGE_DATA_DIR "TestVectors/aes.txt") && pass;
1592  return pass;
1593 }
1594 
1595 bool ValidateTwofish()
1596 {
1597  cout << "\nTwofish validation suite running...\n\n";
1598 
1599  FileSource valdata(PACKAGE_DATA_DIR "TestData/twofishv.dat", true, new HexDecoder);
1600  bool pass = true;
1601  pass = BlockTransformationTest(FixedRoundsCipherFactory<TwofishEncryption, TwofishDecryption>(16), valdata, 4) && pass;
1602  pass = BlockTransformationTest(FixedRoundsCipherFactory<TwofishEncryption, TwofishDecryption>(24), valdata, 3) && pass;
1603  pass = BlockTransformationTest(FixedRoundsCipherFactory<TwofishEncryption, TwofishDecryption>(32), valdata, 2) && pass;
1604  return pass;
1605 }
1606 
1607 bool ValidateSerpent()
1608 {
1609  cout << "\nSerpent validation suite running...\n\n";
1610 
1611  FileSource valdata(PACKAGE_DATA_DIR "TestData/serpentv.dat", true, new HexDecoder);
1612  bool pass = true;
1613  pass = BlockTransformationTest(FixedRoundsCipherFactory<SerpentEncryption, SerpentDecryption>(16), valdata, 5) && pass;
1614  pass = BlockTransformationTest(FixedRoundsCipherFactory<SerpentEncryption, SerpentDecryption>(24), valdata, 4) && pass;
1615  pass = BlockTransformationTest(FixedRoundsCipherFactory<SerpentEncryption, SerpentDecryption>(32), valdata, 3) && pass;
1616  return pass;
1617 }
1618 
1619 bool ValidateBlowfish()
1620 {
1621  cout << "\nBlowfish validation suite running...\n\n";
1622 
1623  HexEncoder output(new FileSink(cout));
1624  const char *key[]={"abcdefghijklmnopqrstuvwxyz", "Who is John Galt?"};
1625  byte *plain[]={(byte *)"BLOWFISH", (byte *)"\xfe\xdc\xba\x98\x76\x54\x32\x10"};
1626  byte *cipher[]={(byte *)"\x32\x4e\xd0\xfe\xf4\x13\xa2\x03", (byte *)"\xcc\x91\x73\x2b\x80\x22\xf6\x84"};
1627  byte out[8], outplain[8];
1628  bool pass=true, fail;
1629 
1630  for (int i=0; i<2; i++)
1631  {
1632  ECB_Mode<Blowfish>::Encryption enc((byte *)key[i], strlen(key[i]));
1633  enc.ProcessData(out, plain[i], 8);
1634  fail = memcmp(out, cipher[i], 8) != 0;
1635 
1636  ECB_Mode<Blowfish>::Decryption dec((byte *)key[i], strlen(key[i]));
1637  dec.ProcessData(outplain, cipher[i], 8);
1638  fail = fail || memcmp(outplain, plain[i], 8);
1639  pass = pass && !fail;
1640 
1641  cout << (fail ? "FAILED " : "passed ");
1642  cout << '\"' << key[i] << '\"';
1643  for (int j=0; j<(signed int)(30-strlen(key[i])); j++)
1644  cout << ' ';
1645  output.Put(outplain, 8);
1646  cout << " ";
1647  output.Put(out, 8);
1648  cout << endl;
1649  }
1650  return pass;
1651 }
1652 
1653 bool ValidateThreeWay()
1654 {
1655  cout << "\n3-WAY validation suite running...\n\n";
1656 
1657  FileSource valdata(PACKAGE_DATA_DIR "TestData/3wayval.dat", true, new HexDecoder);
1658  return BlockTransformationTest(FixedRoundsCipherFactory<ThreeWayEncryption, ThreeWayDecryption>(), valdata);
1659 }
1660 
1661 bool ValidateGOST()
1662 {
1663  cout << "\nGOST validation suite running...\n\n";
1664 
1665  FileSource valdata(PACKAGE_DATA_DIR "TestData/gostval.dat", true, new HexDecoder);
1666  return BlockTransformationTest(FixedRoundsCipherFactory<GOSTEncryption, GOSTDecryption>(), valdata);
1667 }
1668 
1669 bool ValidateSHARK()
1670 {
1671  cout << "\nSHARK validation suite running...\n\n";
1672 
1673  FileSource valdata(PACKAGE_DATA_DIR "TestData/sharkval.dat", true, new HexDecoder);
1674  return BlockTransformationTest(FixedRoundsCipherFactory<SHARKEncryption, SHARKDecryption>(), valdata);
1675 }
1676 
1677 bool ValidateCAST()
1678 {
1679  bool pass = true;
1680 
1681  cout << "\nCAST-128 validation suite running...\n\n";
1682 
1683  FileSource val128(PACKAGE_DATA_DIR "TestData/cast128v.dat", true, new HexDecoder);
1684  pass = BlockTransformationTest(FixedRoundsCipherFactory<CAST128Encryption, CAST128Decryption>(16), val128, 1) && pass;
1685  pass = BlockTransformationTest(FixedRoundsCipherFactory<CAST128Encryption, CAST128Decryption>(10), val128, 1) && pass;
1686  pass = BlockTransformationTest(FixedRoundsCipherFactory<CAST128Encryption, CAST128Decryption>(5), val128, 1) && pass;
1687 
1688  cout << "\nCAST-256 validation suite running...\n\n";
1689 
1690  FileSource val256(PACKAGE_DATA_DIR "TestData/cast256v.dat", true, new HexDecoder);
1691  pass = BlockTransformationTest(FixedRoundsCipherFactory<CAST256Encryption, CAST256Decryption>(16), val256, 1) && pass;
1692  pass = BlockTransformationTest(FixedRoundsCipherFactory<CAST256Encryption, CAST256Decryption>(24), val256, 1) && pass;
1693  pass = BlockTransformationTest(FixedRoundsCipherFactory<CAST256Encryption, CAST256Decryption>(32), val256, 1) && pass;
1694 
1695  return pass;
1696 }
1697 
1698 bool ValidateSquare()
1699 {
1700  cout << "\nSquare validation suite running...\n\n";
1701 
1702  FileSource valdata(PACKAGE_DATA_DIR "TestData/squareva.dat", true, new HexDecoder);
1703  return BlockTransformationTest(FixedRoundsCipherFactory<SquareEncryption, SquareDecryption>(), valdata);
1704 }
1705 
1706 bool ValidateSKIPJACK()
1707 {
1708  cout << "\nSKIPJACK validation suite running...\n\n";
1709 
1710  FileSource valdata(PACKAGE_DATA_DIR "TestData/skipjack.dat", true, new HexDecoder);
1711  return BlockTransformationTest(FixedRoundsCipherFactory<SKIPJACKEncryption, SKIPJACKDecryption>(), valdata);
1712 }
1713 
1714 bool ValidateSEAL()
1715 {
1716  byte input[] = {0x37,0xa0,0x05,0x95,0x9b,0x84,0xc4,0x9c,0xa4,0xbe,0x1e,0x05,0x06,0x73,0x53,0x0f,0x5f,0xb0,0x97,0xfd,0xf6,0xa1,0x3f,0xbd,0x6c,0x2c,0xde,0xcd,0x81,0xfd,0xee,0x7c};
1717  byte output[32];
1718  byte key[] = {0x67, 0x45, 0x23, 0x01, 0xef, 0xcd, 0xab, 0x89, 0x98, 0xba, 0xdc, 0xfe, 0x10, 0x32, 0x54, 0x76, 0xc3, 0xd2, 0xe1, 0xf0};
1719  byte iv[] = {0x01, 0x35, 0x77, 0xaf};
1720 
1721  cout << "\nSEAL validation suite running...\n\n";
1722 
1723  SEAL<>::Encryption seal(key, sizeof(key), iv);
1724  unsigned int size = sizeof(input);
1725  bool pass = true;
1726 
1727  memset(output, 1, size);
1728  seal.ProcessString(output, input, size);
1729  for (unsigned int i=0; i<size; i++)
1730  if (output[i] != 0)
1731  pass = false;
1732 
1733  seal.Seek(1);
1734  output[1] = seal.ProcessByte(output[1]);
1735  seal.ProcessString(output+2, size-2);
1736  pass = pass && memcmp(output+1, input+1, size-1) == 0;
1737 
1738  cout << (pass ? "passed" : "FAILED") << endl;
1739  return pass;
1740 }
1741 
1742 bool ValidateBaseCode()
1743 {
1744  bool pass = true, fail;
1745  byte data[255];
1746  for (unsigned int i=0; i<255; i++)
1747  data[i] = byte(i);
1748  static const char hexEncoded[] =
1749 "000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F2021222324252627"
1750 "28292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D4E4F"
1751 "505152535455565758595A5B5C5D5E5F606162636465666768696A6B6C6D6E6F7071727374757677"
1752 "78797A7B7C7D7E7F808182838485868788898A8B8C8D8E8F909192939495969798999A9B9C9D9E9F"
1753 "A0A1A2A3A4A5A6A7A8A9AAABACADAEAFB0B1B2B3B4B5B6B7B8B9BABBBCBDBEBFC0C1C2C3C4C5C6C7"
1754 "C8C9CACBCCCDCECFD0D1D2D3D4D5D6D7D8D9DADBDCDDDEDFE0E1E2E3E4E5E6E7E8E9EAEBECEDEEEF"
1755 "F0F1F2F3F4F5F6F7F8F9FAFBFCFDFE";
1756  static const char base32Encoded[] =
1757 "AAASEA2EAWDAQCAJBIFS2DIQB6IBCESVCSKTNF22DEPBYHA7D2RUAIJCENUCKJTHFAWUWK3NFWZC8NBT"
1758 "GI3VIPJYG66DUQT5HS8V6R4AIFBEGTCFI3DWSUKKJPGE4VURKBIXEW4WKXMFQYC3MJPX2ZK8M7SGC2VD"
1759 "NTUYN35IPFXGY5DPP3ZZA6MUQP4HK7VZRB6ZW856RX9H9AEBSKB2JBNGS8EIVCWMTUG27D6SUGJJHFEX"
1760 "U4M3TGN4VQQJ5HW9WCS4FI7EWYVKRKFJXKX43MPQX82MDNXVYU45PP72ZG7MZRF7Z496BSQC2RCNMTYH"
1761 "3DE6XU8N3ZHN9WGT4MJ7JXQY49NPVYY55VQ77Z9A6HTQH3HF65V8T4RK7RYQ55ZR8D29F69W8Z5RR8H3"
1762 "9M7939R8";
1763  const char *base64AndHexEncoded =
1764 "41414543417751464267634943516F4C4441304F4478415245684D554652595847426B6147787764"
1765 "486838674953496A4A43556D4A7967704B6973734C5334764D4445794D7A51310A4E6A63344F546F"
1766 "375044302B50304242516B4E4552555A4853456C4B5330784E546B395155564A5456465657563168"
1767 "5A576C746358563566594746695932526C5A6D646F615770720A6247317562334278636E4E306458"
1768 "5A3365486C3665337839666E2B4167594B44684957476834694A696F754D6A5936506B4A47536B35"
1769 "53566C7065596D5A71626E4A32656E3643680A6F714F6B7061616E714B6D717136797472712B7773"
1770 "624B7A744C573274376935757275387662362F774D484377385446787366497963724C7A4D334F7A"
1771 "39445230745055316462580A324E6E6132397A6433742F6734654C6A354F586D352B6A7036757673"
1772 "3765377638504879382F5431397666342B6672372F50332B0A";
1773 
1774  cout << "\nBase64, base32 and hex coding validation suite running...\n\n";
1775 
1776  fail = !TestFilter(HexEncoder().Ref(), data, 255, (const byte *)hexEncoded, strlen(hexEncoded));
1777  cout << (fail ? "FAILED " : "passed ");
1778  cout << "Hex Encoding\n";
1779  pass = pass && !fail;
1780 
1781  fail = !TestFilter(HexDecoder().Ref(), (const byte *)hexEncoded, strlen(hexEncoded), data, 255);
1782  cout << (fail ? "FAILED " : "passed ");
1783  cout << "Hex Decoding\n";
1784  pass = pass && !fail;
1785 
1786  fail = !TestFilter(Base32Encoder().Ref(), data, 255, (const byte *)base32Encoded, strlen(base32Encoded));
1787  cout << (fail ? "FAILED " : "passed ");
1788  cout << "Base32 Encoding\n";
1789  pass = pass && !fail;
1790 
1791  fail = !TestFilter(Base32Decoder().Ref(), (const byte *)base32Encoded, strlen(base32Encoded), data, 255);
1792  cout << (fail ? "FAILED " : "passed ");
1793  cout << "Base32 Decoding\n";
1794  pass = pass && !fail;
1795 
1796  fail = !TestFilter(Base64Encoder(new HexEncoder).Ref(), data, 255, (const byte *)base64AndHexEncoded, strlen(base64AndHexEncoded));
1797  cout << (fail ? "FAILED " : "passed ");
1798  cout << "Base64 Encoding\n";
1799  pass = pass && !fail;
1800 
1801  fail = !TestFilter(HexDecoder(new Base64Decoder).Ref(), (const byte *)base64AndHexEncoded, strlen(base64AndHexEncoded), data, 255);
1802  cout << (fail ? "FAILED " : "passed ");
1803  cout << "Base64 Decoding\n";
1804  pass = pass && !fail;
1805 
1806  return pass;
1807 }
1808 
1809 bool ValidateSHACAL2()
1810 {
1811  cout << "\nSHACAL-2 validation suite running...\n\n";
1812 
1813  bool pass = true;
1814  FileSource valdata(PACKAGE_DATA_DIR "TestData/shacal2v.dat", true, new HexDecoder);
1815  pass = BlockTransformationTest(FixedRoundsCipherFactory<SHACAL2Encryption, SHACAL2Decryption>(16), valdata, 4) && pass;
1816  pass = BlockTransformationTest(FixedRoundsCipherFactory<SHACAL2Encryption, SHACAL2Decryption>(64), valdata, 10) && pass;
1817  return pass;
1818 }
1819 
1820 bool ValidateCamellia()
1821 {
1822  cout << "\nCamellia validation suite running...\n\n";
1823 
1824  bool pass = true;
1825  FileSource valdata(PACKAGE_DATA_DIR "TestData/camellia.dat", true, new HexDecoder);
1826  pass = BlockTransformationTest(FixedRoundsCipherFactory<CamelliaEncryption, CamelliaDecryption>(16), valdata, 15) && pass;
1827  pass = BlockTransformationTest(FixedRoundsCipherFactory<CamelliaEncryption, CamelliaDecryption>(24), valdata, 15) && pass;
1828  pass = BlockTransformationTest(FixedRoundsCipherFactory<CamelliaEncryption, CamelliaDecryption>(32), valdata, 15) && pass;
1829  return pass;
1830 }
1831 
1832 bool ValidateSalsa()
1833 {
1834  cout << "\nSalsa validation suite running...\n";
1835 
1836  return RunTestDataFile(PACKAGE_DATA_DIR "TestVectors/salsa.txt");
1837 }
1838 
1839 bool ValidateSosemanuk()
1840 {
1841  cout << "\nSosemanuk validation suite running...\n";
1842  return RunTestDataFile(PACKAGE_DATA_DIR "TestVectors/sosemanuk.txt");
1843 }
1844 
1845 bool ValidateVMAC()
1846 {
1847  cout << "\nVMAC validation suite running...\n";
1848  return RunTestDataFile(PACKAGE_DATA_DIR "TestVectors/vmac.txt");
1849 }
1850 
1851 bool ValidateCCM()
1852 {
1853  cout << "\nAES/CCM validation suite running...\n";
1854  return RunTestDataFile(PACKAGE_DATA_DIR "TestVectors/ccm.txt");
1855 }
1856 
1857 bool ValidateGCM()
1858 {
1859  cout << "\nAES/GCM validation suite running...\n";
1860  cout << "\n2K tables:";
1861  bool pass = RunTestDataFile(PACKAGE_DATA_DIR "TestVectors/gcm.txt", MakeParameters(Name::TableSize(), (int)2048));
1862  cout << "\n64K tables:";
1863  return RunTestDataFile(PACKAGE_DATA_DIR "TestVectors/gcm.txt", MakeParameters(Name::TableSize(), (int)64*1024)) && pass;
1864 }
1865 
1866 bool ValidateCMAC()
1867 {
1868  cout << "\nCMAC validation suite running...\n";
1869  return RunTestDataFile(PACKAGE_DATA_DIR "TestVectors/cmac.txt");
1870 }
Base class for all exceptions thrown by Crypto++.
Definition: cryptlib.h:124
Base32 encodes data.
Definition: base32.h:18
OFB block cipher mode of operation.
Definition: modes.h:302
Wrapper class for /dev/random and /dev/srandom.
Definition: osrng.h:75
Class file for modes of operation.
virtual void GenerateBlock(byte *output, size_t size)
Generate random array of bytes.
Definition: cryptlib.cpp:329
This file contains helper classes/functions for implementing public key algorithms.
DMAC.
Definition: dmac.h:45
Hardware generated random numbers using RDRAND instruction.
Definition: rdrand.h:37
file-based implementation of Source interface
Definition: files.h:55
Converts given data to base 16.
Definition: hex.h:15
Classes for the RC5 block cipher.
virtual word32 GenerateWord32(word32 min=0, word32 max=0xffffffffUL)
Generate a random 32 bit word in the range min to max, inclusive.
Definition: cryptlib.cpp:301
Base64 decodes data.
Definition: base64.h:52
Decode base 16 data back to bytes.
Definition: hex.h:28
Abstract base classes that provide a uniform interface to this library.
void memcpy_s(void *dest, size_t sizeInBytes, const void *src, size_t count)
Bounds checking replacement for memcpy()
Definition: misc.h:296
Classes for the RC2 block cipher.
BufferedTransformation & TheBitBucket()
An input discarding BufferedTransformation.
Definition: cryptlib.cpp:82
Manages resources for an array of objects.
Definition: smartptr.h:229
size_t Put2(const byte *inString, size_t length, int messageEnd, bool blocking)
Input multiple bytes for processing.
Definition: validat1.cpp:928
virtual void DiscardBytes(size_t n)
Generate and discard n bytes.
Definition: cryptlib.cpp:342
Classes for automatic resource management.
DEFLATE (RFC 1951) compressor.
Definition: zdeflate.h:65
Classes for the GIST block cipher.
STL namespace.
Classes for the Cameliia block cipher.
Classes for RDRAND and RDSEED.
Classes for Base32Encoder and Base32Decoder.
SecByteBlock is a SecBlock<byte> typedef.
Definition: secblock.h:727
Interface for buffered transformations.
Definition: cryptlib.h:1247
Classes for CBC MAC.
Classes for the RC6 block cipher.
Classes for the Twofish block cipher.
1 and 0&#39;s padding added to a block
Definition: filters.h:391
Base64 encodes data.
Definition: base64.h:18
bool MessageEnd(int propagation=-1, bool blocking=true)
Signals the end of messages to the object.
Definition: cryptlib.h:1326
Classes for the Blowfish block cipher.
Copy input to a memory buffer.
Definition: filters.h:775
Classes for the MARS block cipher (IBM AES submission)
Alleged RC4
Definition: arc4.h:49
const char * TableSize()
int, in bytes
Definition: argnames.h:80
Classes for the SKIPJACK block cipher.
virtual void Attach(BufferedTransformation *newAttachment)
Add newAttachment to the end of attachment chain.
Definition: cryptlib.cpp:763
virtual void DiscardBytes(size_t n)
Generate and discard n bytes.
Definition: rdrand.h:163
Filter Wrapper for HashTransformation.
Definition: filters.h:424
size_t Put(byte inByte, bool blocking=true)
Input a byte for processing.
Definition: cryptlib.h:1268
AlgorithmParameters MakeParameters(const char *name, const T &value, bool throwIfNotUsed=true)
Create an object that implements NameValuePairs.
Definition: algparam.h:487
Exception thrown when an operating system error is encountered.
Definition: osrng.h:26
virtual void Resynchronize(const byte *iv, int ivLength=-1)
resynchronize with an IV. ivLength=-1 means use IVSize()
Definition: cryptlib.h:592
Classes for HexEncoder and HexDecoder.
Maurer&#39;s Universal Statistical Test for Random Bit Generators.
Definition: rng.h:80
virtual void DiscardBytes(size_t n)
Generate and discard n bytes.
Definition: rdrand.h:84
Automatically Seeded Randomness Pool.
Definition: osrng.h:140
void Assign(const T *ptr, size_type len)
Set contents and size from an array.
Definition: secblock.h:529
Class file for the AES cipher (Rijndael)
Classes for the CAST-128 and CAST-256 block ciphers.
Interface for one direction (encryption or decryption) of a stream cipher or cipher mode...
Definition: cryptlib.h:1020
Provides class member functions to key a block cipher.
Definition: seckey.h:305
Classes for DMAC message authentication code.
Implementation of schemes based on DL over GF(p)
bool IsPowerOf2(const T &value)
Tests whether a value is a power of 2.
Definition: misc.h:718
Miscellaneous classes for RNGs.
Classes for SEAL stream cipher.
Redirect input to another BufferedTransformation without owning it.
Definition: filters.h:574
Classes for Rijndael encryption algorithm.
Classes, functions, intrinsics and features for X86, X32 nd X64 assembly.
Classes for DES, 2-key Triple-DES, 3-key Triple-DES and DESX.
Implementation of BufferedTransformation&#39;s attachment interface in cryptlib.h.
Hardware generated random numbers using RDSEED instruction.
Definition: rdrand.h:116
Classes for the Base64Encoder, Base64Decoder, Base64URLEncoder and Base64URLDecoder.
Filter Wrapper for StreamTransformation, optionally handling padding/unpadding when needed...
Definition: filters.h:398
Classes for the SAFER block cipher.
Base class for unflushable filters.
Definition: simple.h:78
Wrapper class for /dev/random and /dev/srandom.
Definition: osrng.h:105
0&#39;s padding added to a block
Definition: filters.h:387
measure how many byte and messages pass through, also serves as valve
Definition: filters.h:187
virtual lword MaxRetrievable() const
Provides the number of bytes ready for retrieval.
Definition: cryptlib.cpp:499
const T & STDMAX(const T &a, const T &b)
Replacement function for std::max.
Definition: misc.h:396
Base32 decodes data.
Definition: base32.h:54
Classes for the 3-Way block cipher.
No padding added to a block.
Definition: filters.h:385
Classes and functions for Elliptic Curves over prime and binary fields.
virtual size_t Get(byte &outByte)
Retrieve a 8-bit byte.
Definition: cryptlib.cpp:518
Classes for the Serpent block cipher.
Crypto++ library namespace.
lword CopyTo(BufferedTransformation &target, lword copyMax=LWORD_MAX, const std::string &channel=DEFAULT_CHANNEL) const
copy copyMax bytes of the buffered output to target as input
Definition: cryptlib.h:1560
Class specific methods used to operate the cipher in the reverse direction.
Definition: rc2.h:78
RNG-based implementation of Source interface.
Definition: filters.h:965
size_type SizeInBytes() const
Provides the number of bytes in the SecBlock.
Definition: secblock.h:523
Classes for the SHARK block cipher.
Class specific methods used to operate the cipher in the forward direction.
Definition: rc2.h:65
file-based implementation of Sink interface
Definition: files.h:78
CBC-MAC
Definition: cbcmac.h:40
Classes for the Square block cipher.
virtual void GetNextIV(RandomNumberGenerator &rng, byte *iv)
Gets a secure IV for the next message.
Definition: cryptlib.cpp:176
Classes for ARC4 cipher.
virtual unsigned int IVSize() const
Returns length of the IV accepted by this object.
Definition: cryptlib.h:583
virtual unsigned int MinLastBlockSize() const
returns the minimum size of the last block, 0 indicating the last block is not special ...
Definition: cryptlib.h:795
Classes for access to the operating system&#39;s random number generators.
Classes for the IDEA block cipher.