Crypto++  5.6.4
Free C++ class library of cryptographic schemes
test.cpp
1 // test.cpp - written and placed in the public domain by Wei Dai
2 
3 #define CRYPTOPP_DEFAULT_NO_DLL
4 #define CRYPTOPP_ENABLE_NAMESPACE_WEAK 1
5 
6 #include "dll.h"
7 #include "aes.h"
8 #include "cryptlib.h"
9 #include "filters.h"
10 #include "md5.h"
11 #include "ripemd.h"
12 #include "rng.h"
13 #include "gzip.h"
14 #include "default.h"
15 #include "randpool.h"
16 #include "ida.h"
17 #include "base64.h"
18 #include "socketft.h"
19 #include "wait.h"
20 #include "factory.h"
21 #include "whrlpool.h"
22 #include "tiger.h"
23 #include "smartptr.h"
24 
25 #include "validate.h"
26 #include "bench.h"
27 
28 #include <algorithm>
29 #include <iostream>
30 #include <sstream>
31 #include <string>
32 #include <locale>
33 #include <time.h>
34 
35 #ifdef CRYPTOPP_WIN32_AVAILABLE
36 #define WIN32_LEAN_AND_MEAN
37 #include <windows.h>
38 #endif
39 
40 #if defined(USE_BERKELEY_STYLE_SOCKETS) && !defined(macintosh)
41 #include <netinet/in.h>
42 #include <netinet/tcp.h>
43 #endif
44 
45 #if (_MSC_VER >= 1000)
46 #include <crtdbg.h> // for the debug heap
47 #endif
48 
49 #if defined(__MWERKS__) && defined(macintosh)
50 #include <console.h>
51 #endif
52 
53 #ifdef _OPENMP
54 # include <omp.h>
55 #endif
56 
57 #ifdef __BORLANDC__
58 #pragma comment(lib, "cryptlib_bds.lib")
59 #pragma comment(lib, "ws2_32.lib")
60 #endif
61 
62 // Aggressive stack checking with VS2005 SP1 and above.
63 #if (CRYPTOPP_MSC_VERSION >= 1410)
64 # pragma strict_gs_check (on)
65 #endif
66 
67 // Quiet deprecated warnings intended to benefit users.
68 #if CRYPTOPP_MSC_VERSION
69 # pragma warning(disable: 4996)
70 #endif
71 
72 #if CRYPTOPP_GCC_DIAGNOSTIC_AVAILABLE
73 # pragma GCC diagnostic ignored "-Wdeprecated-declarations"
74 #endif
75 
76 USING_NAMESPACE(CryptoPP)
77 USING_NAMESPACE(std)
78 
79 const int MAX_PHRASE_LENGTH=250;
80 
81 void RegisterFactories();
82 void PrintSeedAndThreads(const std::string& seed);
83 
84 void GenerateRSAKey(unsigned int keyLength, const char *privFilename, const char *pubFilename, const char *seed);
85 string RSAEncryptString(const char *pubFilename, const char *seed, const char *message);
86 string RSADecryptString(const char *privFilename, const char *ciphertext);
87 void RSASignFile(const char *privFilename, const char *messageFilename, const char *signatureFilename);
88 bool RSAVerifyFile(const char *pubFilename, const char *messageFilename, const char *signatureFilename);
89 
90 void DigestFile(const char *file);
91 void HmacFile(const char *hexKey, const char *file);
92 
93 void AES_CTR_Encrypt(const char *hexKey, const char *hexIV, const char *infile, const char *outfile);
94 
95 string EncryptString(const char *plaintext, const char *passPhrase);
96 string DecryptString(const char *ciphertext, const char *passPhrase);
97 
98 void EncryptFile(const char *in, const char *out, const char *passPhrase);
99 void DecryptFile(const char *in, const char *out, const char *passPhrase);
100 
101 void SecretShareFile(int threshold, int nShares, const char *filename, const char *seed);
102 void SecretRecoverFile(int threshold, const char *outFilename, char *const *inFilenames);
103 
104 void InformationDisperseFile(int threshold, int nShares, const char *filename);
105 void InformationRecoverFile(int threshold, const char *outFilename, char *const *inFilenames);
106 
107 void GzipFile(const char *in, const char *out, int deflate_level);
108 void GunzipFile(const char *in, const char *out);
109 
110 void Base64Encode(const char *infile, const char *outfile);
111 void Base64Decode(const char *infile, const char *outfile);
112 void HexEncode(const char *infile, const char *outfile);
113 void HexDecode(const char *infile, const char *outfile);
114 
115 void ForwardTcpPort(const char *sourcePort, const char *destinationHost, const char *destinationPort);
116 
117 void FIPS140_SampleApplication();
118 void FIPS140_GenerateRandomFiles();
119 
120 bool Validate(int, bool, const char *);
121 void PrintSeedAndThreads(const std::string& seed);
122 
123 int (*AdhocTest)(int argc, char *argv[]) = NULL;
124 
125 RandomNumberGenerator & GlobalRNG()
126 {
127  static OFB_Mode<AES>::Encryption s_globalRNG;
128  return dynamic_cast<RandomNumberGenerator&>(s_globalRNG);
129 }
130 
131 int CRYPTOPP_API main(int argc, char *argv[])
132 {
133 #ifdef _CRTDBG_LEAK_CHECK_DF
134  // Turn on leak-checking
135  int tempflag = _CrtSetDbgFlag( _CRTDBG_REPORT_FLAG );
136  tempflag |= _CRTDBG_LEAK_CHECK_DF;
137  _CrtSetDbgFlag( tempflag );
138 #endif
139 
140 #if defined(__MWERKS__) && defined(macintosh)
141  argc = ccommand(&argv);
142 #endif
143 
144  try
145  {
146  RegisterFactories();
147 
148  // Some editors have problems with the '\0' character when redirecting output.
149  std::string seed = IntToString(time(NULL));
150  seed.resize(16, ' ');
151 
152  OFB_Mode<AES>::Encryption& prng = dynamic_cast<OFB_Mode<AES>::Encryption&>(GlobalRNG());
153  prng.SetKeyWithIV((byte *)seed.data(), 16, (byte *)seed.data());
154 
155  std::string command, executableName, macFilename;
156 
157  if (argc < 2)
158  command = 'h';
159  else
160  command = argv[1];
161 
162  if (command == "g")
163  {
164  char thisSeed[1024], privFilename[128], pubFilename[128];
165  unsigned int keyLength;
166 
167  cout << "Key length in bits: ";
168  cin >> keyLength;
169 
170  cout << "\nSave private key to file: ";
171  cin >> privFilename;
172 
173  cout << "\nSave public key to file: ";
174  cin >> pubFilename;
175 
176  cout << "\nRandom Seed: ";
177  ws(cin);
178  cin.getline(thisSeed, 1024);
179 
180  GenerateRSAKey(keyLength, privFilename, pubFilename, thisSeed);
181  }
182  else if (command == "rs")
183  RSASignFile(argv[2], argv[3], argv[4]);
184  else if (command == "rv")
185  {
186  bool verified = RSAVerifyFile(argv[2], argv[3], argv[4]);
187  cout << (verified ? "valid signature" : "invalid signature") << endl;
188  }
189  else if (command == "r")
190  {
191  char privFilename[128], pubFilename[128];
192  char thisSeed[1024], message[1024];
193 
194  cout << "Private key file: ";
195  cin >> privFilename;
196 
197  cout << "\nPublic key file: ";
198  cin >> pubFilename;
199 
200  cout << "\nRandom Seed: ";
201  ws(cin);
202  cin.getline(thisSeed, 1024);
203 
204  cout << "\nMessage: ";
205  cin.getline(message, 1024);
206 
207  string ciphertext = RSAEncryptString(pubFilename, thisSeed, message);
208  cout << "\nCiphertext: " << ciphertext << endl;
209 
210  string decrypted = RSADecryptString(privFilename, ciphertext.c_str());
211  cout << "\nDecrypted: " << decrypted << endl;
212  }
213  else if (command == "mt")
214  {
216  FileStore fs(argv[2]);
217  fs.TransferAllTo(mt);
218  cout << "Maurer Test Value: " << mt.GetTestValue() << endl;
219  }
220  else if (command == "mac_dll")
221  {
222  std::string fname(argv[2] ? argv[2] : "");
223 
224  // sanity check on file size
225  std::fstream dllFile(fname.c_str(), ios::in | ios::out | ios::binary);
226  if (!dllFile.good())
227  {
228  cerr << "Failed to open file \"" << fname << "\"\n";
229  return 1;
230  }
231 
232  std::ifstream::pos_type fileEnd = dllFile.seekg(0, std::ios_base::end).tellg();
233  if (fileEnd > 20*1000*1000)
234  {
235  cerr << "Input file " << fname << " is too large";
236  cerr << "(size is " << fileEnd << ").\n";
237  return 1;
238  }
239 
240  // read file into memory
241  unsigned int fileSize = (unsigned int)fileEnd;
242  SecByteBlock buf(fileSize);
243  dllFile.seekg(0, std::ios_base::beg);
244  dllFile.read((char *)buf.begin(), fileSize);
245 
246  // find positions of relevant sections in the file, based on version 8 of documentation from http://www.microsoft.com/whdc/system/platform/firmware/PECOFF.mspx
247  word32 coffPos = *(word16 *)(void *)(buf+0x3c);
248  word32 optionalHeaderPos = coffPos + 24;
249  word16 optionalHeaderMagic = *(word16 *)(void *)(buf+optionalHeaderPos);
250  if (optionalHeaderMagic != 0x10b && optionalHeaderMagic != 0x20b)
251  {
252  cerr << "Target file is not a PE32 or PE32+ image.\n";
253  return 3;
254  }
255  word32 checksumPos = optionalHeaderPos + 64;
256  word32 certificateTableDirectoryPos = optionalHeaderPos + (optionalHeaderMagic == 0x10b ? 128 : 144);
257  word32 certificateTablePos = *(word32 *)(void *)(buf+certificateTableDirectoryPos);
258  word32 certificateTableSize = *(word32 *)(void *)(buf+certificateTableDirectoryPos+4);
259  if (certificateTableSize != 0)
260  cerr << "Warning: certificate table (IMAGE_DIRECTORY_ENTRY_SECURITY) of target image is not empty.\n";
261 
262  // find where to place computed MAC
263  byte mac[] = CRYPTOPP_DUMMY_DLL_MAC;
264  byte *found = std::search(buf.begin(), buf.end(), mac+0, mac+sizeof(mac));
265  if (found == buf.end())
266  {
267  cerr << "MAC placeholder not found. The MAC may already be placed.\n";
268  return 2;
269  }
270  word32 macPos = (unsigned int)(found-buf.begin());
271 
272  // compute MAC
274  assert(pMac->DigestSize() == sizeof(mac));
275  MeterFilter f(new HashFilter(*pMac, new ArraySink(mac, sizeof(mac))));
276  f.AddRangeToSkip(0, checksumPos, 4);
277  f.AddRangeToSkip(0, certificateTableDirectoryPos, 8);
278  f.AddRangeToSkip(0, macPos, sizeof(mac));
279  f.AddRangeToSkip(0, certificateTablePos, certificateTableSize);
280  f.PutMessageEnd(buf.begin(), buf.size());
281 
282  // place MAC
283  cout << "Placing MAC in file " << fname << ", location " << macPos;
284  cout << " (0x" << std::hex << macPos << std::dec << ").\n";
285  dllFile.seekg(macPos, std::ios_base::beg);
286  dllFile.write((char *)mac, sizeof(mac));
287  }
288  else if (command == "m")
289  DigestFile(argv[2]);
290  else if (command == "tv")
291  {
292  // TestDataFile() adds CRYPTOPP_DATA_DIR as required
293  std::string fname = (argv[2] ? argv[2] : "all");
294  if (fname.find(".txt") == std::string::npos)
295  fname = "TestVectors/" + fname + ".txt";
296 
297  PrintSeedAndThreads(seed);
298  return !RunTestDataFile(fname.c_str());
299  }
300  else if (command == "t")
301  {
302  // VC60 workaround: use char array instead of std::string to workaround MSVC's getline bug
303  char passPhrase[MAX_PHRASE_LENGTH], plaintext[1024];
304 
305  cout << "Passphrase: ";
306  cin.getline(passPhrase, MAX_PHRASE_LENGTH);
307 
308  cout << "\nPlaintext: ";
309  cin.getline(plaintext, 1024);
310 
311  string ciphertext = EncryptString(plaintext, passPhrase);
312  cout << "\nCiphertext: " << ciphertext << endl;
313 
314  string decrypted = DecryptString(ciphertext.c_str(), passPhrase);
315  cout << "\nDecrypted: " << decrypted << endl;
316 
317  return 0;
318  }
319  else if (command == "e64")
320  Base64Encode(argv[2], argv[3]);
321  else if (command == "d64")
322  Base64Decode(argv[2], argv[3]);
323  else if (command == "e16")
324  HexEncode(argv[2], argv[3]);
325  else if (command == "d16")
326  HexDecode(argv[2], argv[3]);
327  else if (command == "e" || command == "d")
328  {
329  char passPhrase[MAX_PHRASE_LENGTH];
330  cout << "Passphrase: ";
331  cin.getline(passPhrase, MAX_PHRASE_LENGTH);
332  if (command == "e")
333  EncryptFile(argv[2], argv[3], passPhrase);
334  else
335  DecryptFile(argv[2], argv[3], passPhrase);
336  }
337  else if (command == "ss")
338  {
339  char thisSeed[1024];
340  cout << "\nRandom Seed: ";
341  ws(cin);
342  cin.getline(thisSeed, 1024);
343  SecretShareFile(StringToValue<int, true>(argv[2]), StringToValue<int, true>(argv[3]), argv[4], thisSeed);
344  }
345  else if (command == "sr")
346  SecretRecoverFile(argc-3, argv[2], argv+3);
347  else if (command == "id")
348  InformationDisperseFile(StringToValue<int, true>(argv[2]), StringToValue<int, true>(argv[3]), argv[4]);
349  else if (command == "ir")
350  InformationRecoverFile(argc-3, argv[2], argv+3);
351  else if (command == "v" || command == "vv")
352  return !Validate(argc>2 ? StringToValue<int, true>(argv[2]) : 0, argv[1][1] == 'v', argc>3 ? argv[3] : NULL);
353  else if (command == "b")
354  BenchmarkAll(argc<3 ? 1 : StringToValue<float, true>(argv[2]), argc<4 ? 0 : StringToValue<float, true>(argv[3])*1e9);
355  else if (command == "b2")
356  BenchmarkAll2(argc<3 ? 1 : StringToValue<float, true>(argv[2]), argc<4 ? 0 : StringToValue<float, true>(argv[3])*1e9);
357  else if (command == "z")
358  GzipFile(argv[3], argv[4], argv[2][0]-'0');
359  else if (command == "u")
360  GunzipFile(argv[2], argv[3]);
361  else if (command == "fips")
362  FIPS140_SampleApplication();
363  else if (command == "fips-rand")
364  FIPS140_GenerateRandomFiles();
365  else if (command == "ft")
366  ForwardTcpPort(argv[2], argv[3], argv[4]);
367  else if (command == "a")
368  {
369  if (AdhocTest)
370  return (*AdhocTest)(argc, argv);
371  else
372  {
373  cerr << "AdhocTest not defined.\n";
374  return 1;
375  }
376  }
377  else if (command == "hmac")
378  HmacFile(argv[2], argv[3]);
379  else if (command == "ae")
380  AES_CTR_Encrypt(argv[2], argv[3], argv[4], argv[5]);
381  else if (command == "h")
382  {
383  FileSource usage(CRYPTOPP_DATA_DIR "TestData/usage.dat", true, new FileSink(cout));
384  return 1;
385  }
386  else if (command == "V")
387  {
388  cout << CRYPTOPP_VERSION / 100 << '.' << (CRYPTOPP_VERSION % 100) / 10 << '.' << CRYPTOPP_VERSION % 10 << endl;
389  }
390  else
391  {
392  cerr << "Unrecognized command. Run \"cryptest h\" to obtain usage information.\n";
393  return 1;
394  }
395  return 0;
396  }
397  catch(const CryptoPP::Exception &e)
398  {
399  cout << "\nCryptoPP::Exception caught: " << e.what() << endl;
400  return -1;
401  }
402  catch(const std::exception &e)
403  {
404  cout << "\nstd::exception caught: " << e.what() << endl;
405  return -2;
406  }
407 } // End main()
408 
409 void FIPS140_GenerateRandomFiles()
410 {
411 #ifdef OS_RNG_AVAILABLE
413  RandomNumberStore store(rng, ULONG_MAX);
414 
415  for (unsigned int i=0; i<100000; i++)
416  store.TransferTo(FileSink((IntToString(i) + ".rnd").c_str()).Ref(), 20000);
417 #else
418  cout << "OS provided RNG not available.\n";
419  exit(-1);
420 #endif
421 }
422 
423 template <class T, bool NON_NEGATIVE>
424 T StringToValue(const std::string& str) {
425  std::istringstream iss(str);
426  T value;
427  iss >> value;
428 
429  // Use fail(), not bad()
430  if (iss.fail())
431  throw InvalidArgument("cryptest.exe: '" + str +"' is not a value");
432 
433 #if NON_NEGATIVE
434  if (value < 0)
435  throw InvalidArgument("cryptest.exe: '" + str +"' is negative");
436 #endif
437 
438  return value;
439 }
440 
441 template<>
442 int StringToValue<int, true>(const std::string& str)
443 {
444  Integer n(str.c_str());
445  long l = n.ConvertToLong();
446 
447  int r;
448  if(!SafeConvert(l, r))
449  throw InvalidArgument("cryptest.exe: '" + str +"' is not an integer value");
450 
451  return r;
452 }
453 
454 void PrintSeedAndThreads(const std::string& seed)
455 {
456  cout << "Using seed: " << seed << endl;
457 
458 #ifdef _OPENMP
459  int tc = 0;
460  #pragma omp parallel
461  {
462  tc = omp_get_num_threads();
463  }
464 
465  std::cout << "Using " << tc << " OMP " << (tc == 1 ? "thread" : "threads") << std::endl;
466 #endif
467 }
468 
469 SecByteBlock HexDecodeString(const char *hex)
470 {
471  StringSource ss(hex, true, new HexDecoder);
472  SecByteBlock result((size_t)ss.MaxRetrievable());
473  ss.Get(result, result.size());
474  return result;
475 }
476 
477 void GenerateRSAKey(unsigned int keyLength, const char *privFilename, const char *pubFilename, const char *seed)
478 {
479  RandomPool randPool;
480  randPool.IncorporateEntropy((byte *)seed, strlen(seed));
481 
482  RSAES_OAEP_SHA_Decryptor priv(randPool, keyLength);
483  HexEncoder privFile(new FileSink(privFilename));
484  priv.DEREncode(privFile);
485  privFile.MessageEnd();
486 
487  RSAES_OAEP_SHA_Encryptor pub(priv);
488  HexEncoder pubFile(new FileSink(pubFilename));
489  pub.DEREncode(pubFile);
490  pubFile.MessageEnd();
491 }
492 
493 string RSAEncryptString(const char *pubFilename, const char *seed, const char *message)
494 {
495  FileSource pubFile(pubFilename, true, new HexDecoder);
496  RSAES_OAEP_SHA_Encryptor pub(pubFile);
497 
498  RandomPool randPool;
499  randPool.IncorporateEntropy((byte *)seed, strlen(seed));
500 
501  string result;
502  StringSource(message, true, new PK_EncryptorFilter(randPool, pub, new HexEncoder(new StringSink(result))));
503  return result;
504 }
505 
506 string RSADecryptString(const char *privFilename, const char *ciphertext)
507 {
508  FileSource privFile(privFilename, true, new HexDecoder);
509  RSAES_OAEP_SHA_Decryptor priv(privFile);
510 
511  string result;
512  StringSource(ciphertext, true, new HexDecoder(new PK_DecryptorFilter(GlobalRNG(), priv, new StringSink(result))));
513  return result;
514 }
515 
516 void RSASignFile(const char *privFilename, const char *messageFilename, const char *signatureFilename)
517 {
518  FileSource privFile(privFilename, true, new HexDecoder);
519  RSASS<PKCS1v15, SHA>::Signer priv(privFile);
520  FileSource f(messageFilename, true, new SignerFilter(GlobalRNG(), priv, new HexEncoder(new FileSink(signatureFilename))));
521 }
522 
523 bool RSAVerifyFile(const char *pubFilename, const char *messageFilename, const char *signatureFilename)
524 {
525  FileSource pubFile(pubFilename, true, new HexDecoder);
526  RSASS<PKCS1v15, SHA>::Verifier pub(pubFile);
527 
528  FileSource signatureFile(signatureFilename, true, new HexDecoder);
529  if (signatureFile.MaxRetrievable() != pub.SignatureLength())
530  return false;
531  SecByteBlock signature(pub.SignatureLength());
532  signatureFile.Get(signature, signature.size());
533 
534  VerifierFilter *verifierFilter = new VerifierFilter(pub);
535  verifierFilter->Put(signature, pub.SignatureLength());
536  FileSource f(messageFilename, true, verifierFilter);
537 
538  return verifierFilter->GetLastResult();
539 }
540 
541 void DigestFile(const char *filename)
542 {
543  SHA1 sha;
544  RIPEMD160 ripemd;
545  SHA256 sha256;
546  Tiger tiger;
547  SHA512 sha512;
548  Whirlpool whirlpool;
550  filters[0].reset(new HashFilter(sha));
551  filters[1].reset(new HashFilter(ripemd));
552  filters[2].reset(new HashFilter(tiger));
553  filters[3].reset(new HashFilter(sha256));
554  filters[4].reset(new HashFilter(sha512));
555  filters[5].reset(new HashFilter(whirlpool));
556 
557  member_ptr<ChannelSwitch> channelSwitch(new ChannelSwitch);
558  size_t i;
559  for (i=0; i<filters.size(); i++)
560  channelSwitch->AddDefaultRoute(*filters[i]);
561  FileSource(filename, true, channelSwitch.release());
562 
563  HexEncoder encoder(new FileSink(cout), false);
564  for (i=0; i<filters.size(); i++)
565  {
566  cout << filters[i]->AlgorithmName() << ": ";
567  filters[i]->TransferTo(encoder);
568  cout << "\n";
569  }
570 }
571 
572 void HmacFile(const char *hexKey, const char *file)
573 {
575  if (strcmp(hexKey, "selftest") == 0)
576  {
577  cerr << "Computing HMAC/SHA1 value for self test.\n";
578  mac.reset(NewIntegrityCheckingMAC());
579  }
580  else
581  {
582  std::string decodedKey;
583  StringSource(hexKey, true, new HexDecoder(new StringSink(decodedKey)));
584  mac.reset(new HMAC<SHA1>((const byte *)decodedKey.data(), decodedKey.size()));
585  }
586  FileSource(file, true, new HashFilter(*mac, new HexEncoder(new FileSink(cout))));
587 }
588 
589 void AES_CTR_Encrypt(const char *hexKey, const char *hexIV, const char *infile, const char *outfile)
590 {
591  SecByteBlock key = HexDecodeString(hexKey);
592  SecByteBlock iv = HexDecodeString(hexIV);
593  CTR_Mode<AES>::Encryption aes(key, key.size(), iv);
594  FileSource(infile, true, new StreamTransformationFilter(aes, new FileSink(outfile)));
595 }
596 
597 string EncryptString(const char *instr, const char *passPhrase)
598 {
599  string outstr;
600 
601  DefaultEncryptorWithMAC encryptor(passPhrase, new HexEncoder(new StringSink(outstr)));
602  encryptor.Put((byte *)instr, strlen(instr));
603  encryptor.MessageEnd();
604 
605  return outstr;
606 }
607 
608 string DecryptString(const char *instr, const char *passPhrase)
609 {
610  string outstr;
611 
612  HexDecoder decryptor(new DefaultDecryptorWithMAC(passPhrase, new StringSink(outstr)));
613  decryptor.Put((byte *)instr, strlen(instr));
614  decryptor.MessageEnd();
615 
616  return outstr;
617 }
618 
619 void EncryptFile(const char *in, const char *out, const char *passPhrase)
620 {
621  FileSource f(in, true, new DefaultEncryptorWithMAC(passPhrase, new FileSink(out)));
622 }
623 
624 void DecryptFile(const char *in, const char *out, const char *passPhrase)
625 {
626  FileSource f(in, true, new DefaultDecryptorWithMAC(passPhrase, new FileSink(out)));
627 }
628 
629 void SecretShareFile(int threshold, int nShares, const char *filename, const char *seed)
630 {
631  assert(nShares >= 1 && nShares<=1000);
632  if (nShares < 1 || nShares > 1000)
633  throw InvalidArgument("SecretShareFile: " + IntToString(nShares) + " is not in range [1, 1000]");
634 
635  RandomPool rng;
636  rng.IncorporateEntropy((byte *)seed, strlen(seed));
637 
638  ChannelSwitch *channelSwitch = NULL;
639  FileSource source(filename, false, new SecretSharing(rng, threshold, nShares, channelSwitch = new ChannelSwitch));
640 
641  vector_member_ptrs<FileSink> fileSinks(nShares);
642  string channel;
643  for (int i=0; i<nShares; i++)
644  {
645  char extension[5] = ".000";
646  extension[1]='0'+byte(i/100);
647  extension[2]='0'+byte((i/10)%10);
648  extension[3]='0'+byte(i%10);
649  fileSinks[i].reset(new FileSink((string(filename)+extension).c_str()));
650 
651  channel = WordToString<word32>(i);
652  fileSinks[i]->Put((const byte *)channel.data(), 4);
653  channelSwitch->AddRoute(channel, *fileSinks[i], DEFAULT_CHANNEL);
654  }
655 
656  source.PumpAll();
657 }
658 
659 void SecretRecoverFile(int threshold, const char *outFilename, char *const *inFilenames)
660 {
661  assert(threshold >= 1 && threshold <=1000);
662  if (threshold < 1 || threshold > 1000)
663  throw InvalidArgument("SecretRecoverFile: " + IntToString(threshold) + " is not in range [1, 1000]");
664 
665  SecretRecovery recovery(threshold, new FileSink(outFilename));
666 
667  vector_member_ptrs<FileSource> fileSources(threshold);
668  SecByteBlock channel(4);
669  int i;
670  for (i=0; i<threshold; i++)
671  {
672  fileSources[i].reset(new FileSource(inFilenames[i], false));
673  fileSources[i]->Pump(4);
674  fileSources[i]->Get(channel, 4);
675  fileSources[i]->Attach(new ChannelSwitch(recovery, string((char *)channel.begin(), 4)));
676  }
677 
678  while (fileSources[0]->Pump(256))
679  for (i=1; i<threshold; i++)
680  fileSources[i]->Pump(256);
681 
682  for (i=0; i<threshold; i++)
683  fileSources[i]->PumpAll();
684 }
685 
686 void InformationDisperseFile(int threshold, int nShares, const char *filename)
687 {
688  assert(threshold >= 1 && threshold <=1000);
689  if (threshold < 1 || threshold > 1000)
690  throw InvalidArgument("InformationDisperseFile: " + IntToString(nShares) + " is not in range [1, 1000]");
691 
692  ChannelSwitch *channelSwitch = NULL;
693  FileSource source(filename, false, new InformationDispersal(threshold, nShares, channelSwitch = new ChannelSwitch));
694 
695  vector_member_ptrs<FileSink> fileSinks(nShares);
696  string channel;
697  for (int i=0; i<nShares; i++)
698  {
699  char extension[5] = ".000";
700  extension[1]='0'+byte(i/100);
701  extension[2]='0'+byte((i/10)%10);
702  extension[3]='0'+byte(i%10);
703  fileSinks[i].reset(new FileSink((string(filename)+extension).c_str()));
704 
705  channel = WordToString<word32>(i);
706  fileSinks[i]->Put((const byte *)channel.data(), 4);
707  channelSwitch->AddRoute(channel, *fileSinks[i], DEFAULT_CHANNEL);
708  }
709 
710  source.PumpAll();
711 }
712 
713 void InformationRecoverFile(int threshold, const char *outFilename, char *const *inFilenames)
714 {
715  assert(threshold<=1000);
716  if (threshold < 1 || threshold > 1000)
717  throw InvalidArgument("InformationRecoverFile: " + IntToString(threshold) + " is not in range [1, 1000]");
718 
719  InformationRecovery recovery(threshold, new FileSink(outFilename));
720 
721  vector_member_ptrs<FileSource> fileSources(threshold);
722  SecByteBlock channel(4);
723  int i;
724  for (i=0; i<threshold; i++)
725  {
726  fileSources[i].reset(new FileSource(inFilenames[i], false));
727  fileSources[i]->Pump(4);
728  fileSources[i]->Get(channel, 4);
729  fileSources[i]->Attach(new ChannelSwitch(recovery, string((char *)channel.begin(), 4)));
730  }
731 
732  while (fileSources[0]->Pump(256))
733  for (i=1; i<threshold; i++)
734  fileSources[i]->Pump(256);
735 
736  for (i=0; i<threshold; i++)
737  fileSources[i]->PumpAll();
738 }
739 
740 void GzipFile(const char *in, const char *out, int deflate_level)
741 {
742 // FileSource(in, true, new Gzip(new FileSink(out), deflate_level));
743 
744  // use a filter graph to compare decompressed data with original
745  //
746  // Source ----> Gzip ------> Sink
747  // \ |
748  // \ Gunzip
749  // \ |
750  // \ v
751  // > ComparisonFilter
752 
753  EqualityComparisonFilter comparison;
754 
755  Gunzip gunzip(new ChannelSwitch(comparison, "0"));
756  gunzip.SetAutoSignalPropagation(0);
757 
758  FileSink sink(out);
759 
760  ChannelSwitch *cs;
761  Gzip gzip(cs = new ChannelSwitch(sink), deflate_level);
762  cs->AddDefaultRoute(gunzip);
763 
764  cs = new ChannelSwitch(gzip);
765  cs->AddDefaultRoute(comparison, "1");
766  FileSource source(in, true, cs);
767 
768  comparison.ChannelMessageSeriesEnd("0");
769  comparison.ChannelMessageSeriesEnd("1");
770 }
771 
772 void GunzipFile(const char *in, const char *out)
773 {
774  FileSource(in, true, new Gunzip(new FileSink(out)));
775 }
776 
777 void Base64Encode(const char *in, const char *out)
778 {
779  FileSource(in, true, new Base64Encoder(new FileSink(out)));
780 }
781 
782 void Base64Decode(const char *in, const char *out)
783 {
784  FileSource(in, true, new Base64Decoder(new FileSink(out)));
785 }
786 
787 void HexEncode(const char *in, const char *out)
788 {
789  FileSource(in, true, new HexEncoder(new FileSink(out)));
790 }
791 
792 void HexDecode(const char *in, const char *out)
793 {
794  FileSource(in, true, new HexDecoder(new FileSink(out)));
795 }
796 
797 void ForwardTcpPort(const char *sourcePortName, const char *destinationHost, const char *destinationPortName)
798 {
799  // Quiet warnings for Windows Phone and Windows Store builds
800  CRYPTOPP_UNUSED(sourcePortName), CRYPTOPP_UNUSED(destinationHost), CRYPTOPP_UNUSED(destinationPortName);
801 
802 #ifdef SOCKETS_AVAILABLE
803  SocketsInitializer sockInit;
804 
805  Socket sockListen, sockSource, sockDestination;
806 
807  int sourcePort = Socket::PortNameToNumber(sourcePortName);
808  int destinationPort = Socket::PortNameToNumber(destinationPortName);
809 
810  sockListen.Create();
811  sockListen.Bind(sourcePort);
812 
813  int err = setsockopt(sockListen, IPPROTO_TCP, TCP_NODELAY, "\x01", 1);
814  assert(err == 0);
815  if(err != 0)
816  throw Socket::Err(sockListen, "setsockopt", sockListen.GetLastError());
817 
818  cout << "Listing on port " << sourcePort << ".\n";
819  sockListen.Listen();
820 
821  sockListen.Accept(sockSource);
822  cout << "Connection accepted on port " << sourcePort << ".\n";
823  sockListen.CloseSocket();
824 
825  cout << "Making connection to " << destinationHost << ", port " << destinationPort << ".\n";
826  sockDestination.Create();
827  sockDestination.Connect(destinationHost, destinationPort);
828 
829  cout << "Connection made to " << destinationHost << ", starting to forward.\n";
830 
831  SocketSource out(sockSource, false, new SocketSink(sockDestination));
832  SocketSource in(sockDestination, false, new SocketSink(sockSource));
833 
834  WaitObjectContainer waitObjects;
835 
836  while (!(in.SourceExhausted() && out.SourceExhausted()))
837  {
838  waitObjects.Clear();
839 
840  out.GetWaitObjects(waitObjects, CallStack("ForwardTcpPort - out", NULL));
841  in.GetWaitObjects(waitObjects, CallStack("ForwardTcpPort - in", NULL));
842 
843  waitObjects.Wait(INFINITE_TIME);
844 
845  if (!out.SourceExhausted())
846  {
847  cout << "o" << flush;
848  out.PumpAll2(false);
849  if (out.SourceExhausted())
850  cout << "EOF received on source socket.\n";
851  }
852 
853  if (!in.SourceExhausted())
854  {
855  cout << "i" << flush;
856  in.PumpAll2(false);
857  if (in.SourceExhausted())
858  cout << "EOF received on destination socket.\n";
859  }
860  }
861 #else
862  cout << "Socket support was not enabled at compile time.\n";
863  exit(-1);
864 #endif
865 }
866 
867 bool Validate(int alg, bool thorough, const char *seedInput)
868 {
869  bool result;
870 
871  // Some editors have problems with the '\0' character when redirecting output.
872  // seedInput is argv[3] when issuing 'cryptest.exe v all <seed>'
873  std::string seed = (seedInput ? seedInput : IntToString(time(NULL)));
874  seed.resize(16, ' ');
875 
876  OFB_Mode<AES>::Encryption& prng = dynamic_cast<OFB_Mode<AES>::Encryption&>(GlobalRNG());
877  prng.SetKeyWithIV((byte *)seed.data(), 16, (byte *)seed.data());
878 
879  PrintSeedAndThreads(seed);
880 
881  switch (alg)
882  {
883  case 0: result = ValidateAll(thorough); break;
884  case 1: result = TestSettings(); break;
885  case 2: result = TestOS_RNG(); break;
886  case 3: result = ValidateMD5(); break;
887  case 4: result = ValidateSHA(); break;
888  case 5: result = ValidateDES(); break;
889  case 6: result = ValidateIDEA(); break;
890  case 7: result = ValidateARC4(); break;
891  case 8: result = ValidateRC5(); break;
892  case 9: result = ValidateBlowfish(); break;
893 // case 10: result = ValidateDiamond2(); break;
894  case 11: result = ValidateThreeWay(); break;
895  case 12: result = ValidateBBS(); break;
896  case 13: result = ValidateDH(); break;
897  case 14: result = ValidateRSA(); break;
898  case 15: result = ValidateElGamal(); break;
899  case 16: result = ValidateDSA(thorough); break;
900 // case 17: result = ValidateHAVAL(); break;
901  case 18: result = ValidateSAFER(); break;
902  case 19: result = ValidateLUC(); break;
903  case 20: result = ValidateRabin(); break;
904 // case 21: result = ValidateBlumGoldwasser(); break;
905  case 22: result = ValidateECP(); break;
906  case 23: result = ValidateEC2N(); break;
907 // case 24: result = ValidateMD5MAC(); break;
908  case 25: result = ValidateGOST(); break;
909  case 26: result = ValidateTiger(); break;
910  case 27: result = ValidateRIPEMD(); break;
911  case 28: result = ValidateHMAC(); break;
912 // case 29: result = ValidateXMACC(); break;
913  case 30: result = ValidateSHARK(); break;
914  case 32: result = ValidateLUC_DH(); break;
915  case 33: result = ValidateLUC_DL(); break;
916  case 34: result = ValidateSEAL(); break;
917  case 35: result = ValidateCAST(); break;
918  case 36: result = ValidateSquare(); break;
919  case 37: result = ValidateRC2(); break;
920  case 38: result = ValidateRC6(); break;
921  case 39: result = ValidateMARS(); break;
922  case 40: result = ValidateRW(); break;
923  case 41: result = ValidateMD2(); break;
924  case 42: result = ValidateNR(); break;
925  case 43: result = ValidateMQV(); break;
926  case 44: result = ValidateRijndael(); break;
927  case 45: result = ValidateTwofish(); break;
928  case 46: result = ValidateSerpent(); break;
929  case 47: result = ValidateCipherModes(); break;
930  case 48: result = ValidateCRC32(); break;
931  case 49: result = ValidateECDSA(); break;
932  case 50: result = ValidateXTR_DH(); break;
933  case 51: result = ValidateSKIPJACK(); break;
934  case 52: result = ValidateSHA2(); break;
935  case 53: result = ValidatePanama(); break;
936  case 54: result = ValidateAdler32(); break;
937  case 55: result = ValidateMD4(); break;
938  case 56: result = ValidatePBKDF(); break;
939  case 57: result = ValidateESIGN(); break;
940  case 58: result = ValidateDLIES(); break;
941  case 59: result = ValidateBaseCode(); break;
942  case 60: result = ValidateSHACAL2(); break;
943  case 61: result = ValidateCamellia(); break;
944  case 62: result = ValidateWhirlpool(); break;
945  case 63: result = ValidateTTMAC(); break;
946  case 64: result = ValidateSalsa(); break;
947  case 65: result = ValidateSosemanuk(); break;
948  case 66: result = ValidateVMAC(); break;
949  case 67: result = ValidateCCM(); break;
950  case 68: result = ValidateGCM(); break;
951  case 69: result = ValidateCMAC(); break;
952  case 70: result = ValidateHKDF(); break;
953  case 71: result = ValidateBLAKE2s(); break;
954  case 72: result = ValidateBLAKE2b(); break;
955  default: return false;
956  }
957 
958 // Safer functions on Windows for C&A, https://github.com/weidai11/cryptopp/issues/55
959 #if (CRYPTOPP_MSC_VERSION >= 1400)
960  tm localTime = {};
961  char timeBuf[64];
962  errno_t err;
963 
964  const time_t endTime = time(NULL);
965  err = localtime_s(&localTime, &endTime);
966  assert(err == 0);
967  err = asctime_s(timeBuf, sizeof(timeBuf), &localTime);
968  assert(err == 0);
969 
970  cout << "\nTest ended at " << timeBuf;
971 #else
972  const time_t endTime = time(NULL);
973  cout << "\nTest ended at " << asctime(localtime(&endTime));
974 #endif
975 
976  cout << "Seed used was: " << seed << endl;
977 
978  return result;
979 }
Base64Decoder
Base64 decodes data.
Definition: base64.h:59
SignerFilter
Filter wrapper for PK_Signer.
Definition: filters.h:668
HexDecoder
Decode base 16 data back to bytes.
Definition: hex.h:36
member_ptr
Pointer that overloads operator ->
Definition: smartptr.h:39
StringSink
Definition: filters.h:991
SecretRecovery
a variant of Shamir's Secret Sharing Algorithm
Definition: ida.h:86
Socket::PortNameToNumber
static unsigned int PortNameToNumber(const char *name, const char *protocol="tcp")
look up the port number given its name, returns 0 if not found
Definition: socketft.cpp:301
HexEncoder
Converts given data to base 16.
Definition: hex.h:16
Gzip
GZIP Compression (RFC 1952)
Definition: gzip.h:18
ChannelSwitch
Route input to different and/or multiple channels based on channel ID.
Definition: channels.h:92
INFINITE_TIME
const unsigned long INFINITE_TIME
Represents infinite time.
Definition: cryptlib.h:110
FileStore
file-based implementation of Store interface
Definition: files.h:15
SocketSink
socket-based implementation of NetworkSink
Definition: socketft.h:208
SHA1
SHA-1
Definition: sha.h:21
PK_DecryptorFilter
Filter wrapper for PK_Decryptor.
Definition: filters.h:943
Base64Encoder
Base64 encodes data.
Definition: base64.h:17
SecByteBlock
SecBlock<byte> typedef.
Definition: secblock.h:731
Gunzip
GZIP Decompression (RFC 1952)
Definition: gzip.h:52
smartptr.h
Classes for automatic resource management.
DefaultAutoSeededRNG
A typedef providing a default generator.
Definition: osrng.h:253
BufferedTransformation::Put
size_t Put(byte inByte, bool blocking=true)
Input a byte for processing.
Definition: cryptlib.h:1378
DEFAULT_CHANNEL
const std::string DEFAULT_CHANNEL
Default channel for BufferedTransformation.
Definition: cryptlib.cpp:63
SafeConvert
bool SafeConvert(T1 from, T2 &to)
Tests whether a conversion from -> to is safe to perform.
Definition: misc.h:517
SHA512
implements the SHA-512 standard
Definition: sha.h:56
RIPEMD160
RIPEMD-160
Definition: ripemd.h:15
ripemd.h
Classes for RIPEMD message digest.
PK_EncryptorFilter
Filter wrapper for PK_Encryptor.
Definition: filters.h:928
FileSink
file-based implementation of Sink interface
Definition: files.h:78
Whirlpool
Whirlpool
Definition: whrlpool.h:10
filters.h
Implementation of BufferedTransformation's attachment interface.
RandomNumberGenerator
Interface for random number generators.
Definition: cryptlib.h:1186
rng.h
Miscellaneous classes for RNGs.
CallStack
Definition: wait.h:124
randpool.h
Class file for Randomness Pool.
SocketSource
socket-based implementation of NetworkSource
Definition: socketft.h:192
Socket::Err
exception thrown by Socket class
Definition: socketft.h:48
aes.h
Class file for the AES cipher (Rijndael)
SignatureVerificationFilter::GetLastResult
bool GetLastResult() const
Retrieves the result of the last verification.
Definition: filters.h:735
RSAES_OAEP_SHA_Decryptor
RSAES<OAEP<SHA>>::Decryptor typedef
Definition: rsa.h:206
ArraySink
Copy input to a memory buffer.
Definition: filters.h:1016
base64.h
Classes for the Base64Encoder, Base64Decoder, Base64URLEncoder and Base64URLDecoder.
IntToString
std::string IntToString(T value, unsigned int base=10)
Converts a value to a string.
Definition: misc.h:530
HashFilter
Filter wrapper for HashTransformation.
Definition: filters.h:508
HMAC
HMAC.
Definition: hmac.h:50
RSAES_OAEP_SHA_Encryptor
RSAES<OAEP<SHA>>::Encryptor typedef
Definition: rsa.h:209
RandomPool::IncorporateEntropy
void IncorporateEntropy(const byte *input, size_t length)
Update RNG state with additional unpredictable values.
Definition: randpool.cpp:26
NewIntegrityCheckingMAC
MessageAuthenticationCode * NewIntegrityCheckingMAC()
Class object that calculates the MAC on the module.
Definition: fipstest.cpp:271
RandomNumberStore
RNG-based implementation of Source interface.
Definition: filters.h:1097
Socket::GetLastError
static int GetLastError()
returns errno or WSAGetLastError
Definition: socketft.cpp:332
CipherModeFinalTemplate_CipherHolder
Block cipher mode of operation aggregate.
Definition: modes.h:296
SocketsInitializer
Definition: socketft.h:120
StreamTransformationFilter
Filter wrapper for StreamTransformation.
Definition: filters.h:476
InformationDispersal
a variant of Rabin's Information Dispersal Algorithm
Definition: ida.h:103
SecBlock::size
size_type size() const
Provides the count of elements in the SecBlock.
Definition: secblock.h:524
DefaultEncryptorWithMAC
Password-Based encryptor using TripleDES and HMAC/SHA-1.
Definition: default.h:109
InvalidArgument
An invalid argument was detected.
Definition: cryptlib.h:182
RandomPool
Randomness Pool.
Definition: randpool.h:25
MaurerRandomnessTest
Maurer's Universal Statistical Test for Random Bit Generators.
Definition: rng.h:84
default.h
Classes for DefaultEncryptor, DefaultDecryptor, DefaultEncryptorWithMAC and DefaultDecryptorWithMAC.
CRYPTOPP_DUMMY_DLL_MAC
#define CRYPTOPP_DUMMY_DLL_MAC
The placeholder used prior to embedding the actual MAC in the module.
Definition: fips140.h:109
Socket
wrapper for Windows or Berkeley Sockets
Definition: socketft.h:44
vector_member_ptrs
Manages resources for an array of objects.
Definition: smartptr.h:284
CryptoPP
Crypto++ library namespace.
SecretSharing
a variant of Shamir's Secret Sharing Algorithm
Definition: ida.h:65
FileSource
file-based implementation of Source interface
Definition: files.h:55
dll.h
Functions and definitions required for building the FIPS-140 DLL on Windows.
EqualityComparisonFilter
A filter that checks messages on two channels for equality.
Definition: mqueue.h:71
InformationRecovery
a variant of Rabin's Information Dispersal Algorithm
Definition: ida.h:124
Tiger
Tiger
Definition: tiger.h:10
WaitObjectContainer
container of wait objects
Definition: wait.h:169
SignatureVerificationFilter
Filter wrapper for PK_Verifier.
Definition: filters.h:694
ida.h
Classes for Information Dispersal Algorithm (IDA)
PK_FinalTemplate
Template implementing constructors for public key algorithm classes.
Definition: pubkey.h:2040
EqualityComparisonFilter::ChannelMessageSeriesEnd
bool ChannelMessageSeriesEnd(const std::string &channel, int propagation=-1, bool blocking=true)
Marks the end of a series of messages on a channel.
Definition: mqueue.cpp:135
DefaultDecryptorWithMAC
Password-Based decryptor using TripleDES and HMAC/SHA-1.
Definition: default.h:141
SHA256
implements the SHA-256 standard
Definition: sha.h:32
StringSource
Definition: filters.h:1252
cryptlib.h
Abstract base classes that provide a uniform interface to this library.
MeterFilter
Measure how many bytes and messages pass through the filter.
Definition: filters.h:220
gzip.h
GZIP compression and decompression (RFC 1952)
Integer
Multiple precision integer with arithmetic operations.
Definition: integer.h:45