00001
00002
00003 #define CRYPTOPP_DEFAULT_NO_DLL
00004 #define CRYPTOPP_ENABLE_NAMESPACE_WEAK 1
00005
00006 #include "dll.h"
00007 #include "aes.h"
00008 #include "cryptlib.h"
00009 #include "filters.h"
00010 #include "md5.h"
00011 #include "ripemd.h"
00012 #include "rng.h"
00013 #include "gzip.h"
00014 #include "default.h"
00015 #include "randpool.h"
00016 #include "ida.h"
00017 #include "base64.h"
00018 #include "socketft.h"
00019 #include "wait.h"
00020 #include "factory.h"
00021 #include "whrlpool.h"
00022 #include "tiger.h"
00023 #include "smartptr.h"
00024
00025 #include "validate.h"
00026 #include "bench.h"
00027
00028 #include <algorithm>
00029 #include <iostream>
00030 #include <sstream>
00031 #include <string>
00032 #include <locale>
00033 #include <time.h>
00034
00035 #ifdef CRYPTOPP_WIN32_AVAILABLE
00036 #include <windows.h>
00037 #endif
00038
00039 #if defined(USE_BERKELEY_STYLE_SOCKETS) && !defined(macintosh)
00040 #include <netinet/in.h>
00041 #include <netinet/tcp.h>
00042 #endif
00043
00044 #if (_MSC_VER >= 1000)
00045 #include <crtdbg.h>
00046 #endif
00047
00048 #if defined(__MWERKS__) && defined(macintosh)
00049 #include <console.h>
00050 #endif
00051
00052 #ifdef _OPENMP
00053 # include <omp.h>
00054 #endif
00055
00056 #ifdef __BORLANDC__
00057 #pragma comment(lib, "cryptlib_bds.lib")
00058 #pragma comment(lib, "ws2_32.lib")
00059 #endif
00060
00061
00062 #if (CRYPTOPP_MSC_VERSION >= 1410)
00063 # pragma strict_gs_check (on)
00064 #endif
00065
00066 USING_NAMESPACE(CryptoPP)
00067 USING_NAMESPACE(std)
00068
00069 const int MAX_PHRASE_LENGTH=250;
00070
00071 void RegisterFactories();
00072 void PrintSeedAndThreads(const std::string& seed);
00073
00074 void GenerateRSAKey(unsigned int keyLength, const char *privFilename, const char *pubFilename, const char *seed);
00075 string RSAEncryptString(const char *pubFilename, const char *seed, const char *message);
00076 string RSADecryptString(const char *privFilename, const char *ciphertext);
00077 void RSASignFile(const char *privFilename, const char *messageFilename, const char *signatureFilename);
00078 bool RSAVerifyFile(const char *pubFilename, const char *messageFilename, const char *signatureFilename);
00079
00080 void DigestFile(const char *file);
00081 void HmacFile(const char *hexKey, const char *file);
00082
00083 void AES_CTR_Encrypt(const char *hexKey, const char *hexIV, const char *infile, const char *outfile);
00084
00085 string EncryptString(const char *plaintext, const char *passPhrase);
00086 string DecryptString(const char *ciphertext, const char *passPhrase);
00087
00088 void EncryptFile(const char *in, const char *out, const char *passPhrase);
00089 void DecryptFile(const char *in, const char *out, const char *passPhrase);
00090
00091 void SecretShareFile(int threshold, int nShares, const char *filename, const char *seed);
00092 void SecretRecoverFile(int threshold, const char *outFilename, char *const *inFilenames);
00093
00094 void InformationDisperseFile(int threshold, int nShares, const char *filename);
00095 void InformationRecoverFile(int threshold, const char *outFilename, char *const *inFilenames);
00096
00097 void GzipFile(const char *in, const char *out, int deflate_level);
00098 void GunzipFile(const char *in, const char *out);
00099
00100 void Base64Encode(const char *infile, const char *outfile);
00101 void Base64Decode(const char *infile, const char *outfile);
00102 void HexEncode(const char *infile, const char *outfile);
00103 void HexDecode(const char *infile, const char *outfile);
00104
00105 void ForwardTcpPort(const char *sourcePort, const char *destinationHost, const char *destinationPort);
00106
00107 void FIPS140_SampleApplication();
00108 void FIPS140_GenerateRandomFiles();
00109
00110 bool Validate(int, bool, const char *);
00111 void PrintSeedAndThreads(const std::string& seed);
00112
00113 int (*AdhocTest)(int argc, char *argv[]) = NULL;
00114
00115 RandomNumberGenerator & GlobalRNG()
00116 {
00117 static OFB_Mode<AES>::Encryption s_globalRNG;
00118 return dynamic_cast<RandomNumberGenerator&>(s_globalRNG);
00119 }
00120
00121 int CRYPTOPP_API main(int argc, char *argv[])
00122 {
00123 #ifdef _CRTDBG_LEAK_CHECK_DF
00124
00125 int tempflag = _CrtSetDbgFlag( _CRTDBG_REPORT_FLAG );
00126 tempflag |= _CRTDBG_LEAK_CHECK_DF;
00127 _CrtSetDbgFlag( tempflag );
00128 #endif
00129
00130 #if defined(__MWERKS__) && defined(macintosh)
00131 argc = ccommand(&argv);
00132 #endif
00133
00134 try
00135 {
00136 RegisterFactories();
00137
00138
00139 std::string seed = IntToString(time(NULL));
00140 seed.resize(16, ' ');
00141
00142 OFB_Mode<AES>::Encryption& prng = dynamic_cast<OFB_Mode<AES>::Encryption&>(GlobalRNG());
00143 prng.SetKeyWithIV((byte *)seed.data(), 16, (byte *)seed.data());
00144
00145 std::string command, executableName, macFilename;
00146
00147 if (argc < 2)
00148 command = 'h';
00149 else
00150 command = argv[1];
00151
00152 if (command == "g")
00153 {
00154 char thisSeed[1024], privFilename[128], pubFilename[128];
00155 unsigned int keyLength;
00156
00157 cout << "Key length in bits: ";
00158 cin >> keyLength;
00159
00160 cout << "\nSave private key to file: ";
00161 cin >> privFilename;
00162
00163 cout << "\nSave public key to file: ";
00164 cin >> pubFilename;
00165
00166 cout << "\nRandom Seed: ";
00167 ws(cin);
00168 cin.getline(thisSeed, 1024);
00169
00170 GenerateRSAKey(keyLength, privFilename, pubFilename, thisSeed);
00171 }
00172 else if (command == "rs")
00173 RSASignFile(argv[2], argv[3], argv[4]);
00174 else if (command == "rv")
00175 {
00176 bool verified = RSAVerifyFile(argv[2], argv[3], argv[4]);
00177 cout << (verified ? "valid signature" : "invalid signature") << endl;
00178 }
00179 else if (command == "r")
00180 {
00181 char privFilename[128], pubFilename[128];
00182 char thisSeed[1024], message[1024];
00183
00184 cout << "Private key file: ";
00185 cin >> privFilename;
00186
00187 cout << "\nPublic key file: ";
00188 cin >> pubFilename;
00189
00190 cout << "\nRandom Seed: ";
00191 ws(cin);
00192 cin.getline(thisSeed, 1024);
00193
00194 cout << "\nMessage: ";
00195 cin.getline(message, 1024);
00196
00197 string ciphertext = RSAEncryptString(pubFilename, thisSeed, message);
00198 cout << "\nCiphertext: " << ciphertext << endl;
00199
00200 string decrypted = RSADecryptString(privFilename, ciphertext.c_str());
00201 cout << "\nDecrypted: " << decrypted << endl;
00202 }
00203 else if (command == "mt")
00204 {
00205 MaurerRandomnessTest mt;
00206 FileStore fs(argv[2]);
00207 fs.TransferAllTo(mt);
00208 cout << "Maurer Test Value: " << mt.GetTestValue() << endl;
00209 }
00210 else if (command == "mac_dll")
00211 {
00212 std::string fname(argv[2] ? argv[2] : "");
00213
00214
00215 std::fstream dllFile(fname.c_str(), ios::in | ios::out | ios::binary);
00216 if (!dllFile.good())
00217 {
00218 cerr << "Failed to open file \"" << fname << "\"\n";
00219 return 1;
00220 }
00221
00222 std::ifstream::pos_type fileEnd = dllFile.seekg(0, std::ios_base::end).tellg();
00223 if (fileEnd > 20*1000*1000)
00224 {
00225 cerr << "Input file " << fname << " is too large";
00226 cerr << "(size is " << fileEnd << ").\n";
00227 return 1;
00228 }
00229
00230
00231 unsigned int fileSize = (unsigned int)fileEnd;
00232 SecByteBlock buf(fileSize);
00233 dllFile.seekg(0, std::ios_base::beg);
00234 dllFile.read((char *)buf.begin(), fileSize);
00235
00236
00237 word32 coffPos = *(word16 *)(buf+0x3c);
00238 word32 optionalHeaderPos = coffPos + 24;
00239 word16 optionalHeaderMagic = *(word16 *)(buf+optionalHeaderPos);
00240 if (optionalHeaderMagic != 0x10b && optionalHeaderMagic != 0x20b)
00241 {
00242 cerr << "Target file is not a PE32 or PE32+ image.\n";
00243 return 3;
00244 }
00245 word32 checksumPos = optionalHeaderPos + 64;
00246 word32 certificateTableDirectoryPos = optionalHeaderPos + (optionalHeaderMagic == 0x10b ? 128 : 144);
00247 word32 certificateTablePos = *(word32 *)(buf+certificateTableDirectoryPos);
00248 word32 certificateTableSize = *(word32 *)(buf+certificateTableDirectoryPos+4);
00249 if (certificateTableSize != 0)
00250 cerr << "Warning: certificate table (IMAGE_DIRECTORY_ENTRY_SECURITY) of target image is not empty.\n";
00251
00252
00253 byte mac[] = CRYPTOPP_DUMMY_DLL_MAC;
00254 byte *found = std::search(buf.begin(), buf.end(), mac+0, mac+sizeof(mac));
00255 if (found == buf.end())
00256 {
00257 cerr << "MAC placeholder not found. The MAC may already be placed.\n";
00258 return 2;
00259 }
00260 word32 macPos = (unsigned int)(found-buf.begin());
00261
00262
00263 member_ptr<MessageAuthenticationCode> pMac(NewIntegrityCheckingMAC());
00264 assert(pMac->DigestSize() == sizeof(mac));
00265 MeterFilter f(new HashFilter(*pMac, new ArraySink(mac, sizeof(mac))));
00266 f.AddRangeToSkip(0, checksumPos, 4);
00267 f.AddRangeToSkip(0, certificateTableDirectoryPos, 8);
00268 f.AddRangeToSkip(0, macPos, sizeof(mac));
00269 f.AddRangeToSkip(0, certificateTablePos, certificateTableSize);
00270 f.PutMessageEnd(buf.begin(), buf.size());
00271
00272
00273 cout << "Placing MAC in file " << fname << ", location " << macPos;
00274 cout << " (0x" << std::hex << macPos << std::dec << ").\n";
00275 dllFile.seekg(macPos, std::ios_base::beg);
00276 dllFile.write((char *)mac, sizeof(mac));
00277 }
00278 else if (command == "m")
00279 DigestFile(argv[2]);
00280 else if (command == "tv")
00281 {
00282 std::string fname = (argv[2] ? argv[2] : "all");
00283 if (fname.find(".txt") == std::string::npos)
00284 fname = PACKAGE_DATA_DIR "TestVectors/" + fname + ".txt";
00285
00286 PrintSeedAndThreads(seed);
00287 return !RunTestDataFile(fname.c_str());
00288 }
00289 else if (command == "t")
00290 {
00291
00292 char passPhrase[MAX_PHRASE_LENGTH], plaintext[1024];
00293
00294 cout << "Passphrase: ";
00295 cin.getline(passPhrase, MAX_PHRASE_LENGTH);
00296
00297 cout << "\nPlaintext: ";
00298 cin.getline(plaintext, 1024);
00299
00300 string ciphertext = EncryptString(plaintext, passPhrase);
00301 cout << "\nCiphertext: " << ciphertext << endl;
00302
00303 string decrypted = DecryptString(ciphertext.c_str(), passPhrase);
00304 cout << "\nDecrypted: " << decrypted << endl;
00305
00306 return 0;
00307 }
00308 else if (command == "e64")
00309 Base64Encode(argv[2], argv[3]);
00310 else if (command == "d64")
00311 Base64Decode(argv[2], argv[3]);
00312 else if (command == "e16")
00313 HexEncode(argv[2], argv[3]);
00314 else if (command == "d16")
00315 HexDecode(argv[2], argv[3]);
00316 else if (command == "e" || command == "d")
00317 {
00318 char passPhrase[MAX_PHRASE_LENGTH];
00319 cout << "Passphrase: ";
00320 cin.getline(passPhrase, MAX_PHRASE_LENGTH);
00321 if (command == "e")
00322 EncryptFile(argv[2], argv[3], passPhrase);
00323 else
00324 DecryptFile(argv[2], argv[3], passPhrase);
00325 }
00326 else if (command == "ss")
00327 {
00328 char thisSeed[1024];
00329 cout << "\nRandom Seed: ";
00330 ws(cin);
00331 cin.getline(thisSeed, 1024);
00332 SecretShareFile(StringToValue<int, true>(argv[2]), StringToValue<int, true>(argv[3]), argv[4], thisSeed);
00333 }
00334 else if (command == "sr")
00335 SecretRecoverFile(argc-3, argv[2], argv+3);
00336 else if (command == "id")
00337 InformationDisperseFile(StringToValue<int, true>(argv[2]), StringToValue<int, true>(argv[3]), argv[4]);
00338 else if (command == "ir")
00339 InformationRecoverFile(argc-3, argv[2], argv+3);
00340 else if (command == "v" || command == "vv")
00341 return !Validate(argc>2 ? StringToValue<int, true>(argv[2]) : 0, argv[1][1] == 'v', argc>3 ? argv[3] : NULL);
00342 else if (command == "b")
00343 BenchmarkAll(argc<3 ? 1 : StringToValue<float, true>(argv[2]), argc<4 ? 0 : StringToValue<float, true>(argv[3])*1e9);
00344 else if (command == "b2")
00345 BenchmarkAll2(argc<3 ? 1 : StringToValue<float, true>(argv[2]), argc<4 ? 0 : StringToValue<float, true>(argv[3])*1e9);
00346 else if (command == "z")
00347 GzipFile(argv[3], argv[4], argv[2][0]-'0');
00348 else if (command == "u")
00349 GunzipFile(argv[2], argv[3]);
00350 else if (command == "fips")
00351 FIPS140_SampleApplication();
00352 else if (command == "fips-rand")
00353 FIPS140_GenerateRandomFiles();
00354 else if (command == "ft")
00355 ForwardTcpPort(argv[2], argv[3], argv[4]);
00356 else if (command == "a")
00357 {
00358 if (AdhocTest)
00359 return (*AdhocTest)(argc, argv);
00360 else
00361 {
00362 cerr << "AdhocTest not defined.\n";
00363 return 1;
00364 }
00365 }
00366 else if (command == "hmac")
00367 HmacFile(argv[2], argv[3]);
00368 else if (command == "ae")
00369 AES_CTR_Encrypt(argv[2], argv[3], argv[4], argv[5]);
00370 else if (command == "h")
00371 {
00372 FileSource usage(PACKAGE_DATA_DIR "TestData/usage.dat", true, new FileSink(cout));
00373 return 1;
00374 }
00375 else if (command == "V")
00376 {
00377 cout << CRYPTOPP_VERSION / 100 << '.' << (CRYPTOPP_VERSION % 100) / 10 << '.' << CRYPTOPP_VERSION % 10 << endl;
00378 }
00379 else
00380 {
00381 cerr << "Unrecognized command. Run \"cryptest h\" to obtain usage information.\n";
00382 return 1;
00383 }
00384 return 0;
00385 }
00386 catch(const CryptoPP::Exception &e)
00387 {
00388 cout << "\nCryptoPP::Exception caught: " << e.what() << endl;
00389 return -1;
00390 }
00391 catch(const std::exception &e)
00392 {
00393 cout << "\nstd::exception caught: " << e.what() << endl;
00394 return -2;
00395 }
00396 }
00397
00398 void FIPS140_GenerateRandomFiles()
00399 {
00400 #ifdef OS_RNG_AVAILABLE
00401 DefaultAutoSeededRNG rng;
00402 RandomNumberStore store(rng, ULONG_MAX);
00403
00404 for (unsigned int i=0; i<100000; i++)
00405 store.TransferTo(FileSink((IntToString(i) + ".rnd").c_str()).Ref(), 20000);
00406 #else
00407 cout << "OS provided RNG not available.\n";
00408 exit(-1);
00409 #endif
00410 }
00411
00412 template <class T, bool NON_NEGATIVE>
00413 T StringToValue(const std::string& str) {
00414 std::istringstream iss(str);
00415 T value;
00416 iss >> value;
00417
00418
00419 if (iss.fail())
00420 throw InvalidArgument("cryptest.exe: '" + str +"' is not a value");
00421
00422 #if NON_NEGATIVE
00423 if (value < 0)
00424 throw InvalidArgument("cryptest.exe: '" + str +"' is negative");
00425 #endif
00426
00427 return value;
00428 }
00429
00430 template<>
00431 int StringToValue<int, true>(const std::string& str)
00432 {
00433 Integer n(str.c_str());
00434 long l = n.ConvertToLong();
00435
00436 int r;
00437 if(!SafeConvert(l, r))
00438 throw InvalidArgument("cryptest.exe: '" + str +"' is not an integer value");
00439
00440 return r;
00441 }
00442
00443 void PrintSeedAndThreads(const std::string& seed)
00444 {
00445 cout << "Using seed: " << seed << endl;
00446
00447 #ifdef _OPENMP
00448 int tc = 0;
00449 #pragma omp parallel
00450 {
00451 tc = omp_get_num_threads();
00452 }
00453
00454 std::cout << "Using " << tc << " OMP " << (tc == 1 ? "thread" : "threads") << std::endl;
00455 #endif
00456 }
00457
00458 SecByteBlock HexDecodeString(const char *hex)
00459 {
00460 StringSource ss(hex, true, new HexDecoder);
00461 SecByteBlock result((size_t)ss.MaxRetrievable());
00462 ss.Get(result, result.size());
00463 return result;
00464 }
00465
00466 void GenerateRSAKey(unsigned int keyLength, const char *privFilename, const char *pubFilename, const char *seed)
00467 {
00468 RandomPool randPool;
00469 randPool.IncorporateEntropy((byte *)seed, strlen(seed));
00470
00471 RSAES_OAEP_SHA_Decryptor priv(randPool, keyLength);
00472 HexEncoder privFile(new FileSink(privFilename));
00473 priv.DEREncode(privFile);
00474 privFile.MessageEnd();
00475
00476 RSAES_OAEP_SHA_Encryptor pub(priv);
00477 HexEncoder pubFile(new FileSink(pubFilename));
00478 pub.DEREncode(pubFile);
00479 pubFile.MessageEnd();
00480 }
00481
00482 string RSAEncryptString(const char *pubFilename, const char *seed, const char *message)
00483 {
00484 FileSource pubFile(pubFilename, true, new HexDecoder);
00485 RSAES_OAEP_SHA_Encryptor pub(pubFile);
00486
00487 RandomPool randPool;
00488 randPool.IncorporateEntropy((byte *)seed, strlen(seed));
00489
00490 string result;
00491 StringSource(message, true, new PK_EncryptorFilter(randPool, pub, new HexEncoder(new StringSink(result))));
00492 return result;
00493 }
00494
00495 string RSADecryptString(const char *privFilename, const char *ciphertext)
00496 {
00497 FileSource privFile(privFilename, true, new HexDecoder);
00498 RSAES_OAEP_SHA_Decryptor priv(privFile);
00499
00500 string result;
00501 StringSource(ciphertext, true, new HexDecoder(new PK_DecryptorFilter(GlobalRNG(), priv, new StringSink(result))));
00502 return result;
00503 }
00504
00505 void RSASignFile(const char *privFilename, const char *messageFilename, const char *signatureFilename)
00506 {
00507 FileSource privFile(privFilename, true, new HexDecoder);
00508 RSASS<PKCS1v15, SHA>::Signer priv(privFile);
00509 FileSource f(messageFilename, true, new SignerFilter(GlobalRNG(), priv, new HexEncoder(new FileSink(signatureFilename))));
00510 }
00511
00512 bool RSAVerifyFile(const char *pubFilename, const char *messageFilename, const char *signatureFilename)
00513 {
00514 FileSource pubFile(pubFilename, true, new HexDecoder);
00515 RSASS<PKCS1v15, SHA>::Verifier pub(pubFile);
00516
00517 FileSource signatureFile(signatureFilename, true, new HexDecoder);
00518 if (signatureFile.MaxRetrievable() != pub.SignatureLength())
00519 return false;
00520 SecByteBlock signature(pub.SignatureLength());
00521 signatureFile.Get(signature, signature.size());
00522
00523 VerifierFilter *verifierFilter = new VerifierFilter(pub);
00524 verifierFilter->Put(signature, pub.SignatureLength());
00525 FileSource f(messageFilename, true, verifierFilter);
00526
00527 return verifierFilter->GetLastResult();
00528 }
00529
00530 void DigestFile(const char *filename)
00531 {
00532 SHA1 sha;
00533 RIPEMD160 ripemd;
00534 SHA256 sha256;
00535 Tiger tiger;
00536 SHA512 sha512;
00537 Whirlpool whirlpool;
00538 vector_member_ptrs<HashFilter> filters(6);
00539 filters[0].reset(new HashFilter(sha));
00540 filters[1].reset(new HashFilter(ripemd));
00541 filters[2].reset(new HashFilter(tiger));
00542 filters[3].reset(new HashFilter(sha256));
00543 filters[4].reset(new HashFilter(sha512));
00544 filters[5].reset(new HashFilter(whirlpool));
00545
00546 member_ptr<ChannelSwitch> channelSwitch(new ChannelSwitch);
00547 size_t i;
00548 for (i=0; i<filters.size(); i++)
00549 channelSwitch->AddDefaultRoute(*filters[i]);
00550 FileSource(filename, true, channelSwitch.release());
00551
00552 HexEncoder encoder(new FileSink(cout), false);
00553 for (i=0; i<filters.size(); i++)
00554 {
00555 cout << filters[i]->AlgorithmName() << ": ";
00556 filters[i]->TransferTo(encoder);
00557 cout << "\n";
00558 }
00559 }
00560
00561 void HmacFile(const char *hexKey, const char *file)
00562 {
00563 member_ptr<MessageAuthenticationCode> mac;
00564 if (strcmp(hexKey, "selftest") == 0)
00565 {
00566 cerr << "Computing HMAC/SHA1 value for self test.\n";
00567 mac.reset(NewIntegrityCheckingMAC());
00568 }
00569 else
00570 {
00571 std::string decodedKey;
00572 StringSource(hexKey, true, new HexDecoder(new StringSink(decodedKey)));
00573 mac.reset(new HMAC<SHA1>((const byte *)decodedKey.data(), decodedKey.size()));
00574 }
00575 FileSource(file, true, new HashFilter(*mac, new HexEncoder(new FileSink(cout))));
00576 }
00577
00578 void AES_CTR_Encrypt(const char *hexKey, const char *hexIV, const char *infile, const char *outfile)
00579 {
00580 SecByteBlock key = HexDecodeString(hexKey);
00581 SecByteBlock iv = HexDecodeString(hexIV);
00582 CTR_Mode<AES>::Encryption aes(key, key.size(), iv);
00583 FileSource(infile, true, new StreamTransformationFilter(aes, new FileSink(outfile)));
00584 }
00585
00586 string EncryptString(const char *instr, const char *passPhrase)
00587 {
00588 string outstr;
00589
00590 DefaultEncryptorWithMAC encryptor(passPhrase, new HexEncoder(new StringSink(outstr)));
00591 encryptor.Put((byte *)instr, strlen(instr));
00592 encryptor.MessageEnd();
00593
00594 return outstr;
00595 }
00596
00597 string DecryptString(const char *instr, const char *passPhrase)
00598 {
00599 string outstr;
00600
00601 HexDecoder decryptor(new DefaultDecryptorWithMAC(passPhrase, new StringSink(outstr)));
00602 decryptor.Put((byte *)instr, strlen(instr));
00603 decryptor.MessageEnd();
00604
00605 return outstr;
00606 }
00607
00608 void EncryptFile(const char *in, const char *out, const char *passPhrase)
00609 {
00610 FileSource f(in, true, new DefaultEncryptorWithMAC(passPhrase, new FileSink(out)));
00611 }
00612
00613 void DecryptFile(const char *in, const char *out, const char *passPhrase)
00614 {
00615 FileSource f(in, true, new DefaultDecryptorWithMAC(passPhrase, new FileSink(out)));
00616 }
00617
00618 void SecretShareFile(int threshold, int nShares, const char *filename, const char *seed)
00619 {
00620 assert(nShares >= 1 && nShares<=1000);
00621 if (nShares < 1 || nShares > 1000)
00622 throw InvalidArgument("SecretShareFile: " + IntToString(nShares) + " is not in range [1, 1000]");
00623
00624 RandomPool rng;
00625 rng.IncorporateEntropy((byte *)seed, strlen(seed));
00626
00627 ChannelSwitch *channelSwitch;
00628 FileSource source(filename, false, new SecretSharing(rng, threshold, nShares, channelSwitch = new ChannelSwitch));
00629
00630 vector_member_ptrs<FileSink> fileSinks(nShares);
00631 string channel;
00632 for (int i=0; i<nShares; i++)
00633 {
00634 char extension[5] = ".000";
00635 extension[1]='0'+byte(i/100);
00636 extension[2]='0'+byte((i/10)%10);
00637 extension[3]='0'+byte(i%10);
00638 fileSinks[i].reset(new FileSink((string(filename)+extension).c_str()));
00639
00640 channel = WordToString<word32>(i);
00641 fileSinks[i]->Put((const byte *)channel.data(), 4);
00642 channelSwitch->AddRoute(channel, *fileSinks[i], DEFAULT_CHANNEL);
00643 }
00644
00645 source.PumpAll();
00646 }
00647
00648 void SecretRecoverFile(int threshold, const char *outFilename, char *const *inFilenames)
00649 {
00650 assert(threshold >= 1 && threshold <=1000);
00651 if (threshold < 1 || threshold > 1000)
00652 throw InvalidArgument("SecretRecoverFile: " + IntToString(threshold) + " is not in range [1, 1000]");
00653
00654 SecretRecovery recovery(threshold, new FileSink(outFilename));
00655
00656 vector_member_ptrs<FileSource> fileSources(threshold);
00657 SecByteBlock channel(4);
00658 int i;
00659 for (i=0; i<threshold; i++)
00660 {
00661 fileSources[i].reset(new FileSource(inFilenames[i], false));
00662 fileSources[i]->Pump(4);
00663 fileSources[i]->Get(channel, 4);
00664 fileSources[i]->Attach(new ChannelSwitch(recovery, string((char *)channel.begin(), 4)));
00665 }
00666
00667 while (fileSources[0]->Pump(256))
00668 for (i=1; i<threshold; i++)
00669 fileSources[i]->Pump(256);
00670
00671 for (i=0; i<threshold; i++)
00672 fileSources[i]->PumpAll();
00673 }
00674
00675 void InformationDisperseFile(int threshold, int nShares, const char *filename)
00676 {
00677 assert(threshold >= 1 && threshold <=1000);
00678 if (threshold < 1 || threshold > 1000)
00679 throw InvalidArgument("InformationDisperseFile: " + IntToString(nShares) + " is not in range [1, 1000]");
00680
00681 ChannelSwitch *channelSwitch;
00682 FileSource source(filename, false, new InformationDispersal(threshold, nShares, channelSwitch = new ChannelSwitch));
00683
00684 vector_member_ptrs<FileSink> fileSinks(nShares);
00685 string channel;
00686 for (int i=0; i<nShares; i++)
00687 {
00688 char extension[5] = ".000";
00689 extension[1]='0'+byte(i/100);
00690 extension[2]='0'+byte((i/10)%10);
00691 extension[3]='0'+byte(i%10);
00692 fileSinks[i].reset(new FileSink((string(filename)+extension).c_str()));
00693
00694 channel = WordToString<word32>(i);
00695 fileSinks[i]->Put((const byte *)channel.data(), 4);
00696 channelSwitch->AddRoute(channel, *fileSinks[i], DEFAULT_CHANNEL);
00697 }
00698
00699 source.PumpAll();
00700 }
00701
00702 void InformationRecoverFile(int threshold, const char *outFilename, char *const *inFilenames)
00703 {
00704 assert(threshold<=1000);
00705 if (threshold < 1 || threshold > 1000)
00706 throw InvalidArgument("InformationRecoverFile: " + IntToString(threshold) + " is not in range [1, 1000]");
00707
00708 InformationRecovery recovery(threshold, new FileSink(outFilename));
00709
00710 vector_member_ptrs<FileSource> fileSources(threshold);
00711 SecByteBlock channel(4);
00712 int i;
00713 for (i=0; i<threshold; i++)
00714 {
00715 fileSources[i].reset(new FileSource(inFilenames[i], false));
00716 fileSources[i]->Pump(4);
00717 fileSources[i]->Get(channel, 4);
00718 fileSources[i]->Attach(new ChannelSwitch(recovery, string((char *)channel.begin(), 4)));
00719 }
00720
00721 while (fileSources[0]->Pump(256))
00722 for (i=1; i<threshold; i++)
00723 fileSources[i]->Pump(256);
00724
00725 for (i=0; i<threshold; i++)
00726 fileSources[i]->PumpAll();
00727 }
00728
00729 void GzipFile(const char *in, const char *out, int deflate_level)
00730 {
00731
00732
00733
00734
00735
00736
00737
00738
00739
00740
00741
00742 EqualityComparisonFilter comparison;
00743
00744 Gunzip gunzip(new ChannelSwitch(comparison, "0"));
00745 gunzip.SetAutoSignalPropagation(0);
00746
00747 FileSink sink(out);
00748
00749 ChannelSwitch *cs;
00750 Gzip gzip(cs = new ChannelSwitch(sink), deflate_level);
00751 cs->AddDefaultRoute(gunzip);
00752
00753 cs = new ChannelSwitch(gzip);
00754 cs->AddDefaultRoute(comparison, "1");
00755 FileSource source(in, true, cs);
00756
00757 comparison.ChannelMessageSeriesEnd("0");
00758 comparison.ChannelMessageSeriesEnd("1");
00759 }
00760
00761 void GunzipFile(const char *in, const char *out)
00762 {
00763 FileSource(in, true, new Gunzip(new FileSink(out)));
00764 }
00765
00766 void Base64Encode(const char *in, const char *out)
00767 {
00768 FileSource(in, true, new Base64Encoder(new FileSink(out)));
00769 }
00770
00771 void Base64Decode(const char *in, const char *out)
00772 {
00773 FileSource(in, true, new Base64Decoder(new FileSink(out)));
00774 }
00775
00776 void HexEncode(const char *in, const char *out)
00777 {
00778 FileSource(in, true, new HexEncoder(new FileSink(out)));
00779 }
00780
00781 void HexDecode(const char *in, const char *out)
00782 {
00783 FileSource(in, true, new HexDecoder(new FileSink(out)));
00784 }
00785
00786 void ForwardTcpPort(const char *sourcePortName, const char *destinationHost, const char *destinationPortName)
00787 {
00788 #ifdef SOCKETS_AVAILABLE
00789 SocketsInitializer sockInit;
00790
00791 Socket sockListen, sockSource, sockDestination;
00792
00793 int sourcePort = Socket::PortNameToNumber(sourcePortName);
00794 int destinationPort = Socket::PortNameToNumber(destinationPortName);
00795
00796 sockListen.Create();
00797 sockListen.Bind(sourcePort);
00798
00799 int err = setsockopt(sockListen, IPPROTO_TCP, TCP_NODELAY, "\x01", 1);
00800 assert(err == 0);
00801 if(err != 0)
00802 throw Socket::Err(sockListen, "setsockopt", sockListen.GetLastError());
00803
00804 cout << "Listing on port " << sourcePort << ".\n";
00805 sockListen.Listen();
00806
00807 sockListen.Accept(sockSource);
00808 cout << "Connection accepted on port " << sourcePort << ".\n";
00809 sockListen.CloseSocket();
00810
00811 cout << "Making connection to " << destinationHost << ", port " << destinationPort << ".\n";
00812 sockDestination.Create();
00813 sockDestination.Connect(destinationHost, destinationPort);
00814
00815 cout << "Connection made to " << destinationHost << ", starting to forward.\n";
00816
00817 SocketSource out(sockSource, false, new SocketSink(sockDestination));
00818 SocketSource in(sockDestination, false, new SocketSink(sockSource));
00819
00820 WaitObjectContainer waitObjects;
00821
00822 while (!(in.SourceExhausted() && out.SourceExhausted()))
00823 {
00824 waitObjects.Clear();
00825
00826 out.GetWaitObjects(waitObjects, CallStack("ForwardTcpPort - out", NULL));
00827 in.GetWaitObjects(waitObjects, CallStack("ForwardTcpPort - in", NULL));
00828
00829 waitObjects.Wait(INFINITE_TIME);
00830
00831 if (!out.SourceExhausted())
00832 {
00833 cout << "o" << flush;
00834 out.PumpAll2(false);
00835 if (out.SourceExhausted())
00836 cout << "EOF received on source socket.\n";
00837 }
00838
00839 if (!in.SourceExhausted())
00840 {
00841 cout << "i" << flush;
00842 in.PumpAll2(false);
00843 if (in.SourceExhausted())
00844 cout << "EOF received on destination socket.\n";
00845 }
00846 }
00847 #else
00848 cout << "Socket support was not enabled at compile time.\n";
00849 exit(-1);
00850 #endif
00851 }
00852
00853 bool Validate(int alg, bool thorough, const char *seedInput)
00854 {
00855 bool result;
00856
00857
00858
00859 std::string seed = (seedInput ? seedInput : IntToString(time(NULL)));
00860 seed.resize(16, ' ');
00861
00862 OFB_Mode<AES>::Encryption& prng = dynamic_cast<OFB_Mode<AES>::Encryption&>(GlobalRNG());
00863 prng.SetKeyWithIV((byte *)seed.data(), 16, (byte *)seed.data());
00864
00865 PrintSeedAndThreads(seed);
00866
00867 switch (alg)
00868 {
00869 case 0: result = ValidateAll(thorough); break;
00870 case 1: result = TestSettings(); break;
00871 case 2: result = TestOS_RNG(); break;
00872 case 3: result = ValidateMD5(); break;
00873 case 4: result = ValidateSHA(); break;
00874 case 5: result = ValidateDES(); break;
00875 case 6: result = ValidateIDEA(); break;
00876 case 7: result = ValidateARC4(); break;
00877 case 8: result = ValidateRC5(); break;
00878 case 9: result = ValidateBlowfish(); break;
00879
00880 case 11: result = ValidateThreeWay(); break;
00881 case 12: result = ValidateBBS(); break;
00882 case 13: result = ValidateDH(); break;
00883 case 14: result = ValidateRSA(); break;
00884 case 15: result = ValidateElGamal(); break;
00885 case 16: result = ValidateDSA(thorough); break;
00886
00887 case 18: result = ValidateSAFER(); break;
00888 case 19: result = ValidateLUC(); break;
00889 case 20: result = ValidateRabin(); break;
00890
00891 case 22: result = ValidateECP(); break;
00892 case 23: result = ValidateEC2N(); break;
00893
00894 case 25: result = ValidateGOST(); break;
00895 case 26: result = ValidateTiger(); break;
00896 case 27: result = ValidateRIPEMD(); break;
00897 case 28: result = ValidateHMAC(); break;
00898
00899 case 30: result = ValidateSHARK(); break;
00900 case 32: result = ValidateLUC_DH(); break;
00901 case 33: result = ValidateLUC_DL(); break;
00902 case 34: result = ValidateSEAL(); break;
00903 case 35: result = ValidateCAST(); break;
00904 case 36: result = ValidateSquare(); break;
00905 case 37: result = ValidateRC2(); break;
00906 case 38: result = ValidateRC6(); break;
00907 case 39: result = ValidateMARS(); break;
00908 case 40: result = ValidateRW(); break;
00909 case 41: result = ValidateMD2(); break;
00910 case 42: result = ValidateNR(); break;
00911 case 43: result = ValidateMQV(); break;
00912 case 44: result = ValidateRijndael(); break;
00913 case 45: result = ValidateTwofish(); break;
00914 case 46: result = ValidateSerpent(); break;
00915 case 47: result = ValidateCipherModes(); break;
00916 case 48: result = ValidateCRC32(); break;
00917 case 49: result = ValidateECDSA(); break;
00918 case 50: result = ValidateXTR_DH(); break;
00919 case 51: result = ValidateSKIPJACK(); break;
00920 case 52: result = ValidateSHA2(); break;
00921 case 53: result = ValidatePanama(); break;
00922 case 54: result = ValidateAdler32(); break;
00923 case 55: result = ValidateMD4(); break;
00924 case 56: result = ValidatePBKDF(); break;
00925 case 57: result = ValidateESIGN(); break;
00926 case 58: result = ValidateDLIES(); break;
00927 case 59: result = ValidateBaseCode(); break;
00928 case 60: result = ValidateSHACAL2(); break;
00929 case 61: result = ValidateCamellia(); break;
00930 case 62: result = ValidateWhirlpool(); break;
00931 case 63: result = ValidateTTMAC(); break;
00932 case 64: result = ValidateSalsa(); break;
00933 case 65: result = ValidateSosemanuk(); break;
00934 case 66: result = ValidateVMAC(); break;
00935 case 67: result = ValidateCCM(); break;
00936 case 68: result = ValidateGCM(); break;
00937 case 69: result = ValidateCMAC(); break;
00938 case 70: result = ValidateHKDF(); break;
00939 default: return false;
00940 }
00941
00942
00943 #if (CRYPTOPP_MSC_VERSION >= 1400)
00944 tm localTime = {};
00945 char timeBuf[64];
00946 errno_t err;
00947
00948 const time_t endTime = time(NULL);
00949 err = localtime_s(&localTime, &endTime);
00950 assert(err == 0);
00951 err = asctime_s(timeBuf, sizeof(timeBuf), &localTime);
00952 assert(err == 0);
00953
00954 cout << "\nTest ended at " << timeBuf;
00955 #else
00956 const time_t endTime = time(NULL);
00957 cout << "\nTest ended at " << asctime(localtime(&endTime));
00958 #endif
00959
00960 cout << "Seed used was: " << seed << endl;
00961
00962 return result;
00963 }