Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Namespace Members | Class Members | File Members

validat1.cpp

00001 // validat1.cpp - written and placed in the public domain by Wei Dai 00002 00003 #include "pch.h" 00004 00005 #include "files.h" 00006 #include "hex.h" 00007 #include "base32.h" 00008 #include "base64.h" 00009 #include "modes.h" 00010 #include "cbcmac.h" 00011 #include "dmac.h" 00012 #include "idea.h" 00013 #include "des.h" 00014 #include "rc2.h" 00015 #include "arc4.h" 00016 #include "rc5.h" 00017 #include "blowfish.h" 00018 #include "wake.h" 00019 #include "3way.h" 00020 #include "safer.h" 00021 #include "gost.h" 00022 #include "shark.h" 00023 #include "cast.h" 00024 #include "square.h" 00025 #include "seal.h" 00026 #include "rc6.h" 00027 #include "mars.h" 00028 #include "rijndael.h" 00029 #include "twofish.h" 00030 #include "serpent.h" 00031 #include "skipjack.h" 00032 #include "shacal2.h" 00033 #include "camellia.h" 00034 #include "osrng.h" 00035 #include "zdeflate.h" 00036 00037 #include <stdlib.h> 00038 #include <time.h> 00039 #include <memory> 00040 #include <iostream> 00041 #include <iomanip> 00042 00043 #include "validate.h" 00044 00045 USING_NAMESPACE(CryptoPP) 00046 USING_NAMESPACE(std) 00047 00048 bool ValidateAll(bool thorough) 00049 { 00050 bool pass=TestSettings(); 00051 pass=TestOS_RNG() && pass; 00052 00053 pass=ValidateCRC32() && pass; 00054 pass=ValidateAdler32() && pass; 00055 pass=ValidateMD2() && pass; 00056 pass=ValidateMD5() && pass; 00057 pass=ValidateSHA() && pass; 00058 pass=ValidateSHA2() && pass; 00059 pass=ValidateHAVAL() && pass; 00060 pass=ValidateTiger() && pass; 00061 pass=ValidateRIPEMD() && pass; 00062 pass=ValidatePanama() && pass; 00063 pass=ValidateWhirlpool() && pass; 00064 00065 pass=ValidateMD5MAC() && pass; 00066 pass=ValidateHMAC() && pass; 00067 pass=ValidateXMACC() && pass; 00068 pass=ValidateTTMAC() && pass; 00069 00070 pass=ValidatePBKDF() && pass; 00071 00072 pass=ValidateDES() && pass; 00073 pass=ValidateCipherModes() && pass; 00074 pass=ValidateIDEA() && pass; 00075 pass=ValidateSAFER() && pass; 00076 pass=ValidateRC2() && pass; 00077 pass=ValidateARC4() && pass; 00078 pass=ValidateRC5() && pass; 00079 pass=ValidateBlowfish() && pass; 00080 pass=ValidateThreeWay() && pass; 00081 pass=ValidateGOST() && pass; 00082 pass=ValidateSHARK() && pass; 00083 pass=ValidateCAST() && pass; 00084 pass=ValidateSquare() && pass; 00085 pass=ValidateSKIPJACK() && pass; 00086 pass=ValidateSEAL() && pass; 00087 pass=ValidateRC6() && pass; 00088 pass=ValidateMARS() && pass; 00089 pass=ValidateRijndael() && pass; 00090 pass=ValidateTwofish() && pass; 00091 pass=ValidateSerpent() && pass; 00092 pass=ValidateSHACAL2() && pass; 00093 pass=ValidateCamellia() && pass; 00094 00095 pass=ValidateBBS() && pass; 00096 pass=ValidateDH() && pass; 00097 pass=ValidateMQV() && pass; 00098 pass=ValidateRSA() && pass; 00099 pass=ValidateElGamal() && pass; 00100 pass=ValidateDLIES() && pass; 00101 pass=ValidateNR() && pass; 00102 pass=ValidateDSA(thorough) && pass; 00103 pass=ValidateLUC() && pass; 00104 pass=ValidateLUC_DH() && pass; 00105 pass=ValidateLUC_DL() && pass; 00106 pass=ValidateXTR_DH() && pass; 00107 pass=ValidateRabin() && pass; 00108 pass=ValidateRW() && pass; 00109 // pass=ValidateBlumGoldwasser() && pass; 00110 pass=ValidateECP() && pass; 00111 pass=ValidateEC2N() && pass; 00112 pass=ValidateECDSA() && pass; 00113 pass=ValidateESIGN() && pass; 00114 00115 if (pass) 00116 cout << "\nAll tests passed!\n"; 00117 else 00118 cout << "\nOops! Not all tests passed.\n"; 00119 00120 return pass; 00121 } 00122 00123 bool TestSettings() 00124 { 00125 bool pass = true; 00126 00127 cout << "\nTesting Settings...\n\n"; 00128 00129 if (*(word32 *)"\x01\x02\x03\x04" == 0x04030201L) 00130 { 00131 #ifdef IS_LITTLE_ENDIAN 00132 cout << "passed: "; 00133 #else 00134 cout << "FAILED: "; 00135 pass = false; 00136 #endif 00137 cout << "Your machine is little endian.\n"; 00138 } 00139 else if (*(word32 *)"\x01\x02\x03\x04" == 0x01020304L) 00140 { 00141 #ifndef IS_LITTLE_ENDIAN 00142 cout << "passed: "; 00143 #else 00144 cout << "FAILED: "; 00145 pass = false; 00146 #endif 00147 cout << "Your machine is big endian.\n"; 00148 } 00149 else 00150 { 00151 cout << "FAILED: Your machine is neither big endian nor little endian.\n"; 00152 pass = false; 00153 } 00154 00155 if (sizeof(byte) == 1) 00156 cout << "passed: "; 00157 else 00158 { 00159 cout << "FAILED: "; 00160 pass = false; 00161 } 00162 cout << "sizeof(byte) == " << sizeof(byte) << endl; 00163 00164 if (sizeof(word16) == 2) 00165 cout << "passed: "; 00166 else 00167 { 00168 cout << "FAILED: "; 00169 pass = false; 00170 } 00171 cout << "sizeof(word16) == " << sizeof(word16) << endl; 00172 00173 if (sizeof(word32) == 4) 00174 cout << "passed: "; 00175 else 00176 { 00177 cout << "FAILED: "; 00178 pass = false; 00179 } 00180 cout << "sizeof(word32) == " << sizeof(word32) << endl; 00181 00182 #ifdef WORD64_AVAILABLE 00183 if (sizeof(word64) == 8) 00184 cout << "passed: "; 00185 else 00186 { 00187 cout << "FAILED: "; 00188 pass = false; 00189 } 00190 cout << "sizeof(word64) == " << sizeof(word64) << endl; 00191 #elif CRYPTOPP_NATIVE_DWORD_AVAILABLE 00192 if (sizeof(dword) >= 8) 00193 { 00194 cout << "FAILED: sizeof(dword) >= 8, but WORD64_AVAILABLE not defined" << endl; 00195 pass = false; 00196 } 00197 else 00198 cout << "passed: word64 not available" << endl; 00199 #endif 00200 00201 #ifdef CRYPTOPP_NATIVE_DWORD_AVAILABLE 00202 if (sizeof(dword) == 2*sizeof(word)) 00203 cout << "passed: "; 00204 else 00205 { 00206 cout << "FAILED: "; 00207 pass = false; 00208 } 00209 cout << "sizeof(word) == " << sizeof(word) << ", sizeof(dword) == " << sizeof(dword) << endl; 00210 #endif 00211 00212 if (!pass) 00213 { 00214 cout << "Some critical setting in config.h is in error. Please fix it and recompile." << endl; 00215 abort(); 00216 } 00217 return pass; 00218 } 00219 00220 bool TestOS_RNG() 00221 { 00222 bool pass = true; 00223 00224 member_ptr<RandomNumberGenerator> rng; 00225 #ifdef BLOCKING_RNG_AVAILABLE 00226 try {rng.reset(new BlockingRng);} 00227 catch (OS_RNG_Err &) {} 00228 #endif 00229 00230 if (rng.get()) 00231 { 00232 cout << "\nTesting operating system provided blocking random number generator...\n\n"; 00233 00234 ArraySink *sink; 00235 RandomNumberSource test(*rng, UINT_MAX, false, new Deflator(sink=new ArraySink(NULL,0))); 00236 unsigned long total=0, length=0; 00237 time_t t = time(NULL), t1 = 0; 00238 00239 // check that it doesn't take too long to generate a reasonable amount of randomness 00240 while (total < 16 && (t1 < 10 || total*8 > (unsigned long)t1)) 00241 { 00242 test.Pump(1); 00243 total += 1; 00244 t1 = time(NULL) - t; 00245 } 00246 00247 if (total < 16) 00248 { 00249 cout << "FAILED:"; 00250 pass = false; 00251 } 00252 else 00253 cout << "passed:"; 00254 cout << " it took " << t1 << " seconds to generate " << total << " bytes" << endl; 00255 00256 if (t1 < 2) 00257 { 00258 // that was fast, are we really blocking? 00259 // first exhaust the extropy reserve 00260 t = time(NULL); 00261 while (time(NULL) - t < 2) 00262 { 00263 test.Pump(1); 00264 total += 1; 00265 } 00266 00267 // if it generates too many bytes in a certain amount of time, 00268 // something's probably wrong 00269 t = time(NULL); 00270 while (time(NULL) - t < 2) 00271 { 00272 test.Pump(1); 00273 total += 1; 00274 length += 1; 00275 } 00276 // turn off this test because it fails on several systems, including Darwin 00277 // they don't block, or gather entropy too fast? 00278 if (false) // (length > 1024) 00279 { 00280 cout << "FAILED:"; 00281 pass = false; 00282 } 00283 else 00284 cout << "passed:"; 00285 cout << " it generated " << length << " bytes in " << time(NULL) - t << " seconds" << endl; 00286 } 00287 00288 test.AttachedTransformation()->MessageEnd(); 00289 00290 if (sink->TotalPutLength() < total) 00291 { 00292 cout << "FAILED:"; 00293 pass = false; 00294 } 00295 else 00296 cout << "passed:"; 00297 cout << " " << total << " generated bytes compressed to " << sink->TotalPutLength() << " bytes by DEFLATE" << endl; 00298 } 00299 else 00300 cout << "\nNo operating system provided blocking random number generator, skipping test." << endl; 00301 00302 rng.reset(NULL); 00303 #ifdef NONBLOCKING_RNG_AVAILABLE 00304 try {rng.reset(new NonblockingRng);} 00305 catch (OS_RNG_Err &) {} 00306 #endif 00307 00308 if (rng.get()) 00309 { 00310 cout << "\nTesting operating system provided nonblocking random number generator...\n\n"; 00311 00312 ArraySink *sink; 00313 RandomNumberSource test(*rng, 100000, true, new Deflator(sink=new ArraySink(NULL, 0))); 00314 00315 if (sink->TotalPutLength() < 100000) 00316 { 00317 cout << "FAILED:"; 00318 pass = false; 00319 } 00320 else 00321 cout << "passed:"; 00322 cout << " 100000 generated bytes compressed to " << sink->TotalPutLength() << " bytes by DEFLATE" << endl; 00323 } 00324 else 00325 cout << "\nNo operating system provided nonblocking random number generator, skipping test." << endl; 00326 00327 return pass; 00328 } 00329 00330 // VC50 workaround 00331 typedef auto_ptr<BlockTransformation> apbt; 00332 00333 class CipherFactory 00334 { 00335 public: 00336 virtual unsigned int BlockSize() const =0; 00337 virtual unsigned int KeyLength() const =0; 00338 00339 virtual apbt NewEncryption(const byte *key) const =0; 00340 virtual apbt NewDecryption(const byte *key) const =0; 00341 }; 00342 00343 template <class E, class D> class FixedRoundsCipherFactory : public CipherFactory 00344 { 00345 public: 00346 FixedRoundsCipherFactory(unsigned int keylen=0) : m_keylen(keylen?keylen:E::DEFAULT_KEYLENGTH) {} 00347 unsigned int BlockSize() const {return E::BLOCKSIZE;} 00348 unsigned int KeyLength() const {return m_keylen;} 00349 00350 apbt NewEncryption(const byte *key) const 00351 {return apbt(new E(key, m_keylen));} 00352 apbt NewDecryption(const byte *key) const 00353 {return apbt(new D(key, m_keylen));} 00354 00355 unsigned int m_keylen; 00356 }; 00357 00358 template <class E, class D> class VariableRoundsCipherFactory : public CipherFactory 00359 { 00360 public: 00361 VariableRoundsCipherFactory(unsigned int keylen=0, unsigned int rounds=0) 00362 : m_keylen(keylen ? keylen : E::DEFAULT_KEYLENGTH), m_rounds(rounds ? rounds : E::DEFAULT_ROUNDS) {} 00363 unsigned int BlockSize() const {return E::BLOCKSIZE;} 00364 unsigned int KeyLength() const {return m_keylen;} 00365 00366 apbt NewEncryption(const byte *key) const 00367 {return apbt(new E(key, m_keylen, m_rounds));} 00368 apbt NewDecryption(const byte *key) const 00369 {return apbt(new D(key, m_keylen, m_rounds));} 00370 00371 unsigned int m_keylen, m_rounds; 00372 }; 00373 00374 bool BlockTransformationTest(const CipherFactory &cg, BufferedTransformation &valdata, unsigned int tuples = 0xffff) 00375 { 00376 HexEncoder output(new FileSink(cout)); 00377 SecByteBlock plain(cg.BlockSize()), cipher(cg.BlockSize()), out(cg.BlockSize()), outplain(cg.BlockSize()); 00378 SecByteBlock key(cg.KeyLength()); 00379 bool pass=true, fail; 00380 00381 while (valdata.MaxRetrievable() && tuples--) 00382 { 00383 valdata.Get(key, cg.KeyLength()); 00384 valdata.Get(plain, cg.BlockSize()); 00385 valdata.Get(cipher, cg.BlockSize()); 00386 00387 apbt transE = cg.NewEncryption(key); 00388 transE->ProcessBlock(plain, out); 00389 fail = memcmp(out, cipher, cg.BlockSize()) != 0; 00390 00391 apbt transD = cg.NewDecryption(key); 00392 transD->ProcessBlock(out, outplain); 00393 fail=fail || memcmp(outplain, plain, cg.BlockSize()); 00394 00395 pass = pass && !fail; 00396 00397 cout << (fail ? "FAILED " : "passed "); 00398 output.Put(key, cg.KeyLength()); 00399 cout << " "; 00400 output.Put(outplain, cg.BlockSize()); 00401 cout << " "; 00402 output.Put(out, cg.BlockSize()); 00403 cout << endl; 00404 } 00405 return pass; 00406 } 00407 00408 class FilterTester : public Unflushable<Sink> 00409 { 00410 public: 00411 FilterTester(const byte *validOutput, unsigned int outputLen) 00412 : validOutput(validOutput), outputLen(outputLen), counter(0), fail(false) {} 00413 void PutByte(byte inByte) 00414 { 00415 if (counter >= outputLen || validOutput[counter] != inByte) 00416 { 00417 fail = true; 00418 assert(false); 00419 } 00420 counter++; 00421 } 00422 unsigned int Put2(const byte *inString, unsigned int length, int messageEnd, bool blocking) 00423 { 00424 while (length--) 00425 FilterTester::PutByte(*inString++); 00426 00427 if (messageEnd) 00428 if (counter != outputLen) 00429 { 00430 fail = true; 00431 assert(false); 00432 } 00433 00434 return 0; 00435 } 00436 bool GetResult() 00437 { 00438 return !fail; 00439 } 00440 00441 const byte *validOutput; 00442 unsigned int outputLen, counter; 00443 bool fail; 00444 }; 00445 00446 bool TestFilter(BufferedTransformation &bt, const byte *in, unsigned int inLen, const byte *out, unsigned int outLen) 00447 { 00448 FilterTester *ft; 00449 bt.Attach(ft = new FilterTester(out, outLen)); 00450 00451 while (inLen) 00452 { 00453 unsigned int randomLen = GlobalRNG().GenerateWord32(0, inLen); 00454 bt.Put(in, randomLen); 00455 in += randomLen; 00456 inLen -= randomLen; 00457 } 00458 bt.MessageEnd(); 00459 return ft->GetResult(); 00460 } 00461 00462 bool ValidateDES() 00463 { 00464 cout << "\nDES validation suite running...\n\n"; 00465 00466 FileSource valdata(PKGDATA("descert.dat"), true, new HexDecoder); 00467 bool pass = BlockTransformationTest(FixedRoundsCipherFactory<DESEncryption, DESDecryption>(), valdata); 00468 00469 cout << "\nTesting EDE2, EDE3, and XEX3 variants...\n\n"; 00470 00471 FileSource valdata1(PKGDATA("3desval.dat"), true, new HexDecoder); 00472 pass = BlockTransformationTest(FixedRoundsCipherFactory<DES_EDE2_Encryption, DES_EDE2_Decryption>(), valdata1, 1) && pass; 00473 pass = BlockTransformationTest(FixedRoundsCipherFactory<DES_EDE3_Encryption, DES_EDE3_Decryption>(), valdata1, 1) && pass; 00474 pass = BlockTransformationTest(FixedRoundsCipherFactory<DES_XEX3_Encryption, DES_XEX3_Decryption>(), valdata1, 1) && pass; 00475 00476 return pass; 00477 } 00478 00479 bool TestModeIV(SymmetricCipher &e, SymmetricCipher &d) 00480 { 00481 SecByteBlock lastIV; 00482 StreamTransformationFilter filter(e, new StreamTransformationFilter(d)); 00483 byte plaintext[20480]; 00484 00485 for (unsigned int i=1; i<sizeof(plaintext); i*=2) 00486 { 00487 SecByteBlock iv(e.IVSize()); 00488 e.GetNextIV(iv); 00489 00490 if (iv == lastIV) 00491 return false; 00492 else 00493 lastIV = iv; 00494 00495 e.Resynchronize(iv); 00496 d.Resynchronize(iv); 00497 00498 unsigned int length = STDMAX(GlobalRNG().GenerateWord32(0, i), (word32)e.MinLastBlockSize()); 00499 GlobalRNG().GenerateBlock(plaintext, length); 00500 00501 if (!TestFilter(filter, plaintext, length, plaintext, length)) 00502 return false; 00503 } 00504 00505 return true; 00506 } 00507 00508 bool ValidateCipherModes() 00509 { 00510 cout << "\nTesting DES modes...\n\n"; 00511 const byte key[] = {0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef}; 00512 const byte iv[] = {0x12,0x34,0x56,0x78,0x90,0xab,0xcd,0xef}; 00513 const byte plain[] = { // "Now is the time for all " without tailing 0 00514 0x4e,0x6f,0x77,0x20,0x69,0x73,0x20,0x74, 00515 0x68,0x65,0x20,0x74,0x69,0x6d,0x65,0x20, 00516 0x66,0x6f,0x72,0x20,0x61,0x6c,0x6c,0x20}; 00517 DESEncryption desE(key); 00518 DESDecryption desD(key); 00519 bool pass=true, fail; 00520 00521 { 00522 // from FIPS 81 00523 const byte encrypted[] = { 00524 0x3f, 0xa4, 0x0e, 0x8a, 0x98, 0x4d, 0x48, 0x15, 00525 0x6a, 0x27, 0x17, 0x87, 0xab, 0x88, 0x83, 0xf9, 00526 0x89, 0x3d, 0x51, 0xec, 0x4b, 0x56, 0x3b, 0x53}; 00527 00528 ECB_Mode_ExternalCipher::Encryption modeE(desE); 00529 fail = !TestFilter(StreamTransformationFilter(modeE, NULL, StreamTransformationFilter::NO_PADDING).Ref(), 00530 plain, sizeof(plain), encrypted, sizeof(encrypted)); 00531 pass = pass && !fail; 00532 cout << (fail ? "FAILED " : "passed ") << "ECB encryption" << endl; 00533 00534 ECB_Mode_ExternalCipher::Decryption modeD(desD); 00535 fail = !TestFilter(StreamTransformationFilter(modeD, NULL, StreamTransformationFilter::NO_PADDING).Ref(), 00536 encrypted, sizeof(encrypted), plain, sizeof(plain)); 00537 pass = pass && !fail; 00538 cout << (fail ? "FAILED " : "passed ") << "ECB decryption" << endl; 00539 } 00540 { 00541 // from FIPS 81 00542 const byte encrypted[] = { 00543 0xE5, 0xC7, 0xCD, 0xDE, 0x87, 0x2B, 0xF2, 0x7C, 00544 0x43, 0xE9, 0x34, 0x00, 0x8C, 0x38, 0x9C, 0x0F, 00545 0x68, 0x37, 0x88, 0x49, 0x9A, 0x7C, 0x05, 0xF6}; 00546 00547 CBC_Mode_ExternalCipher::Encryption modeE(desE, iv); 00548 fail = !TestFilter(StreamTransformationFilter(modeE, NULL, StreamTransformationFilter::NO_PADDING).Ref(), 00549 plain, sizeof(plain), encrypted, sizeof(encrypted)); 00550 pass = pass && !fail; 00551 cout << (fail ? "FAILED " : "passed ") << "CBC encryption with no padding" << endl; 00552 00553 CBC_Mode_ExternalCipher::Decryption modeD(desD, iv); 00554 fail = !TestFilter(StreamTransformationFilter(modeD, NULL, StreamTransformationFilter::NO_PADDING).Ref(), 00555 encrypted, sizeof(encrypted), plain, sizeof(plain)); 00556 pass = pass && !fail; 00557 cout << (fail ? "FAILED " : "passed ") << "CBC decryption with no padding" << endl; 00558 00559 fail = !TestModeIV(modeE, modeD); 00560 pass = pass && !fail; 00561 cout << (fail ? "FAILED " : "passed ") << "CBC mode IV generation" << endl; 00562 } 00563 { 00564 // generated with Crypto++, matches FIPS 81 00565 // but has extra 8 bytes as result of padding 00566 const byte encrypted[] = { 00567 0xE5, 0xC7, 0xCD, 0xDE, 0x87, 0x2B, 0xF2, 0x7C, 00568 0x43, 0xE9, 0x34, 0x00, 0x8C, 0x38, 0x9C, 0x0F, 00569 0x68, 0x37, 0x88, 0x49, 0x9A, 0x7C, 0x05, 0xF6, 00570 0x62, 0xC1, 0x6A, 0x27, 0xE4, 0xFC, 0xF2, 0x77}; 00571 00572 CBC_Mode_ExternalCipher::Encryption modeE(desE, iv); 00573 fail = !TestFilter(StreamTransformationFilter(modeE).Ref(), 00574 plain, sizeof(plain), encrypted, sizeof(encrypted)); 00575 pass = pass && !fail; 00576 cout << (fail ? "FAILED " : "passed ") << "CBC encryption with PKCS #7 padding" << endl; 00577 00578 CBC_Mode_ExternalCipher::Decryption modeD(desD, iv); 00579 fail = !TestFilter(StreamTransformationFilter(modeD).Ref(), 00580 encrypted, sizeof(encrypted), plain, sizeof(plain)); 00581 pass = pass && !fail; 00582 cout << (fail ? "FAILED " : "passed ") << "CBC decryption with PKCS #7 padding" << endl; 00583 } 00584 { 00585 // generated with Crypto++ 5.2, matches FIPS 81 00586 // but has extra 8 bytes as result of padding 00587 const byte encrypted[] = { 00588 0xE5, 0xC7, 0xCD, 0xDE, 0x87, 0x2B, 0xF2, 0x7C, 00589 0x43, 0xE9, 0x34, 0x00, 0x8C, 0x38, 0x9C, 0x0F, 00590 0x68, 0x37, 0x88, 0x49, 0x9A, 0x7C, 0x05, 0xF6, 00591 0xcf, 0xb7, 0xc7, 0x64, 0x0e, 0x7c, 0xd9, 0xa7}; 00592 00593 CBC_Mode_ExternalCipher::Encryption modeE(desE, iv); 00594 fail = !TestFilter(StreamTransformationFilter(modeE, NULL, StreamTransformationFilter::ONE_AND_ZEROS_PADDING).Ref(), 00595 plain, sizeof(plain), encrypted, sizeof(encrypted)); 00596 pass = pass && !fail; 00597 cout << (fail ? "FAILED " : "passed ") << "CBC encryption with one-and-zeros padding" << endl; 00598 00599 CBC_Mode_ExternalCipher::Decryption modeD(desD, iv); 00600 fail = !TestFilter(StreamTransformationFilter(modeD, NULL, StreamTransformationFilter::ONE_AND_ZEROS_PADDING).Ref(), 00601 encrypted, sizeof(encrypted), plain, sizeof(plain)); 00602 pass = pass && !fail; 00603 cout << (fail ? "FAILED " : "passed ") << "CBC decryption with one-and-zeros padding" << endl; 00604 } 00605 { 00606 const byte plain[] = {'a', 0, 0, 0, 0, 0, 0, 0}; 00607 // generated with Crypto++ 00608 const byte encrypted[] = { 00609 0x9B, 0x47, 0x57, 0x59, 0xD6, 0x9C, 0xF6, 0xD0}; 00610 00611 CBC_Mode_ExternalCipher::Encryption modeE(desE, iv); 00612 fail = !TestFilter(StreamTransformationFilter(modeE, NULL, StreamTransformationFilter::ZEROS_PADDING).Ref(), 00613 plain, 1, encrypted, sizeof(encrypted)); 00614 pass = pass && !fail; 00615 cout << (fail ? "FAILED " : "passed ") << "CBC encryption with zeros padding" << endl; 00616 00617 CBC_Mode_ExternalCipher::Decryption modeD(desD, iv); 00618 fail = !TestFilter(StreamTransformationFilter(modeD, NULL, StreamTransformationFilter::ZEROS_PADDING).Ref(), 00619 encrypted, sizeof(encrypted), plain, sizeof(plain)); 00620 pass = pass && !fail; 00621 cout << (fail ? "FAILED " : "passed ") << "CBC decryption with zeros padding" << endl; 00622 } 00623 { 00624 // generated with Crypto++, matches FIPS 81 00625 // but with last two blocks swapped as result of CTS 00626 const byte encrypted[] = { 00627 0xE5, 0xC7, 0xCD, 0xDE, 0x87, 0x2B, 0xF2, 0x7C, 00628 0x68, 0x37, 0x88, 0x49, 0x9A, 0x7C, 0x05, 0xF6, 00629 0x43, 0xE9, 0x34, 0x00, 0x8C, 0x38, 0x9C, 0x0F}; 00630 00631 CBC_CTS_Mode_ExternalCipher::Encryption modeE(desE, iv); 00632 fail = !TestFilter(StreamTransformationFilter(modeE).Ref(), 00633 plain, sizeof(plain), encrypted, sizeof(encrypted)); 00634 pass = pass && !fail; 00635 cout << (fail ? "FAILED " : "passed ") << "CBC encryption with ciphertext stealing (CTS)" << endl; 00636 00637 CBC_CTS_Mode_ExternalCipher::Decryption modeD(desD, iv); 00638 fail = !TestFilter(StreamTransformationFilter(modeD).Ref(), 00639 encrypted, sizeof(encrypted), plain, sizeof(plain)); 00640 pass = pass && !fail; 00641 cout << (fail ? "FAILED " : "passed ") << "CBC decryption with ciphertext stealing (CTS)" << endl; 00642 00643 fail = !TestModeIV(modeE, modeD); 00644 pass = pass && !fail; 00645 cout << (fail ? "FAILED " : "passed ") << "CBC CTS IV generation" << endl; 00646 } 00647 { 00648 // generated with Crypto++ 00649 const byte decryptionIV[] = {0x4D, 0xD0, 0xAC, 0x8F, 0x47, 0xCF, 0x79, 0xCE}; 00650 const byte encrypted[] = {0x12, 0x34, 0x56}; 00651 00652 byte stolenIV[8]; 00653 00654 CBC_CTS_Mode_ExternalCipher::Encryption modeE(desE, iv); 00655 modeE.SetStolenIV(stolenIV); 00656 fail = !TestFilter(StreamTransformationFilter(modeE).Ref(), 00657 plain, 3, encrypted, sizeof(encrypted)); 00658 fail = memcmp(stolenIV, decryptionIV, 8) != 0 || fail; 00659 pass = pass && !fail; 00660 cout << (fail ? "FAILED " : "passed ") << "CBC encryption with ciphertext and IV stealing" << endl; 00661 00662 CBC_CTS_Mode_ExternalCipher::Decryption modeD(desD, stolenIV); 00663 fail = !TestFilter(StreamTransformationFilter(modeD).Ref(), 00664 encrypted, sizeof(encrypted), plain, 3); 00665 pass = pass && !fail; 00666 cout << (fail ? "FAILED " : "passed ") << "CBC decryption with ciphertext and IV stealing" << endl; 00667 } 00668 { 00669 const byte encrypted[] = { // from FIPS 81 00670 0xF3,0x09,0x62,0x49,0xC7,0xF4,0x6E,0x51, 00671 0xA6,0x9E,0x83,0x9B,0x1A,0x92,0xF7,0x84, 00672 0x03,0x46,0x71,0x33,0x89,0x8E,0xA6,0x22}; 00673 00674 CFB_Mode_ExternalCipher::Encryption modeE(desE, iv); 00675 fail = !TestFilter(StreamTransformationFilter(modeE).Ref(), 00676 plain, sizeof(plain), encrypted, sizeof(encrypted)); 00677 pass = pass && !fail; 00678 cout << (fail ? "FAILED " : "passed ") << "CFB encryption" << endl; 00679 00680 CFB_Mode_ExternalCipher::Decryption modeD(desE, iv); 00681 fail = !TestFilter(StreamTransformationFilter(modeD).Ref(), 00682 encrypted, sizeof(encrypted), plain, sizeof(plain)); 00683 pass = pass && !fail; 00684 cout << (fail ? "FAILED " : "passed ") << "CFB decryption" << endl; 00685 00686 fail = !TestModeIV(modeE, modeD); 00687 pass = pass && !fail; 00688 cout << (fail ? "FAILED " : "passed ") << "CFB mode IV generation" << endl; 00689 } 00690 { 00691 const byte plain[] = { // "Now is the." without tailing 0 00692 0x4e,0x6f,0x77,0x20,0x69,0x73,0x20,0x74,0x68,0x65}; 00693 const byte encrypted[] = { // from FIPS 81 00694 0xf3,0x1f,0xda,0x07,0x01,0x14,0x62,0xee,0x18,0x7f}; 00695 00696 CFB_Mode_ExternalCipher::Encryption modeE(desE, iv, 1); 00697 fail = !TestFilter(StreamTransformationFilter(modeE).Ref(), 00698 plain, sizeof(plain), encrypted, sizeof(encrypted)); 00699 pass = pass && !fail; 00700 cout << (fail ? "FAILED " : "passed ") << "CFB (8-bit feedback) encryption" << endl; 00701 00702 CFB_Mode_ExternalCipher::Decryption modeD(desE, iv, 1); 00703 fail = !TestFilter(StreamTransformationFilter(modeD).Ref(), 00704 encrypted, sizeof(encrypted), plain, sizeof(plain)); 00705 pass = pass && !fail; 00706 cout << (fail ? "FAILED " : "passed ") << "CFB (8-bit feedback) decryption" << endl; 00707 00708 fail = !TestModeIV(modeE, modeD); 00709 pass = pass && !fail; 00710 cout << (fail ? "FAILED " : "passed ") << "CFB (8-bit feedback) IV generation" << endl; 00711 } 00712 { 00713 const byte encrypted[] = { // from Eric Young's libdes 00714 0xf3,0x09,0x62,0x49,0xc7,0xf4,0x6e,0x51, 00715 0x35,0xf2,0x4a,0x24,0x2e,0xeb,0x3d,0x3f, 00716 0x3d,0x6d,0x5b,0xe3,0x25,0x5a,0xf8,0xc3}; 00717 00718 OFB_Mode_ExternalCipher::Encryption modeE(desE, iv); 00719 fail = !TestFilter(StreamTransformationFilter(modeE).Ref(), 00720 plain, sizeof(plain), encrypted, sizeof(encrypted)); 00721 pass = pass && !fail; 00722 cout << (fail ? "FAILED " : "passed ") << "OFB encryption" << endl; 00723 00724 OFB_Mode_ExternalCipher::Decryption modeD(desE, iv); 00725 fail = !TestFilter(StreamTransformationFilter(modeD).Ref(), 00726 encrypted, sizeof(encrypted), plain, sizeof(plain)); 00727 pass = pass && !fail; 00728 cout << (fail ? "FAILED " : "passed ") << "OFB decryption" << endl; 00729 00730 fail = !TestModeIV(modeE, modeD); 00731 pass = pass && !fail; 00732 cout << (fail ? "FAILED " : "passed ") << "OFB IV generation" << endl; 00733 } 00734 { 00735 const byte encrypted[] = { // generated with Crypto++ 00736 0xF3, 0x09, 0x62, 0x49, 0xC7, 0xF4, 0x6E, 0x51, 00737 0x16, 0x3A, 0x8C, 0xA0, 0xFF, 0xC9, 0x4C, 0x27, 00738 0xFA, 0x2F, 0x80, 0xF4, 0x80, 0xB8, 0x6F, 0x75}; 00739 00740 CTR_Mode_ExternalCipher::Encryption modeE(desE, iv); 00741 fail = !TestFilter(StreamTransformationFilter(modeE).Ref(), 00742 plain, sizeof(plain), encrypted, sizeof(encrypted)); 00743 pass = pass && !fail; 00744 cout << (fail ? "FAILED " : "passed ") << "Counter Mode encryption" << endl; 00745 00746 CTR_Mode_ExternalCipher::Decryption modeD(desE, iv); 00747 fail = !TestFilter(StreamTransformationFilter(modeD).Ref(), 00748 encrypted, sizeof(encrypted), plain, sizeof(plain)); 00749 pass = pass && !fail; 00750 cout << (fail ? "FAILED " : "passed ") << "Counter Mode decryption" << endl; 00751 00752 fail = !TestModeIV(modeE, modeD); 00753 pass = pass && !fail; 00754 cout << (fail ? "FAILED " : "passed ") << "Counter Mode IV generation" << endl; 00755 } 00756 { 00757 const byte plain[] = { // "7654321 Now is the time for " 00758 0x37, 0x36, 0x35, 0x34, 0x33, 0x32, 0x31, 0x20, 00759 0x4e, 0x6f, 0x77, 0x20, 0x69, 0x73, 0x20, 0x74, 00760 0x68, 0x65, 0x20, 0x74, 0x69, 0x6d, 0x65, 0x20, 00761 0x66, 0x6f, 0x72, 0x20}; 00762 const byte mac1[] = { // from FIPS 113 00763 0xf1, 0xd3, 0x0f, 0x68, 0x49, 0x31, 0x2c, 0xa4}; 00764 const byte mac2[] = { // generated with Crypto++ 00765 0x35, 0x80, 0xC5, 0xC4, 0x6B, 0x81, 0x24, 0xE2}; 00766 00767 CBC_MAC<DES> cbcmac(key); 00768 HashFilter cbcmacFilter(cbcmac); 00769 fail = !TestFilter(cbcmacFilter, plain, sizeof(plain), mac1, sizeof(mac1)); 00770 pass = pass && !fail; 00771 cout << (fail ? "FAILED " : "passed ") << "CBC MAC" << endl; 00772 00773 DMAC<DES> dmac(key); 00774 HashFilter dmacFilter(dmac); 00775 fail = !TestFilter(dmacFilter, plain, sizeof(plain), mac2, sizeof(mac2)); 00776 pass = pass && !fail; 00777 cout << (fail ? "FAILED " : "passed ") << "DMAC" << endl; 00778 } 00779 00780 return pass; 00781 } 00782 00783 bool ValidateIDEA() 00784 { 00785 cout << "\nIDEA validation suite running...\n\n"; 00786 00787 FileSource valdata(PKGDATA("ideaval.dat"), true, new HexDecoder); 00788 return BlockTransformationTest(FixedRoundsCipherFactory<IDEAEncryption, IDEADecryption>(), valdata); 00789 } 00790 00791 bool ValidateSAFER() 00792 { 00793 cout << "\nSAFER validation suite running...\n\n"; 00794 00795 FileSource valdata(PKGDATA("saferval.dat"), true, new HexDecoder); 00796 bool pass = true; 00797 pass = BlockTransformationTest(VariableRoundsCipherFactory<SAFER_K_Encryption, SAFER_K_Decryption>(8,6), valdata, 4) && pass; 00798 pass = BlockTransformationTest(VariableRoundsCipherFactory<SAFER_K_Encryption, SAFER_K_Decryption>(16,12), valdata, 4) && pass; 00799 pass = BlockTransformationTest(VariableRoundsCipherFactory<SAFER_SK_Encryption, SAFER_SK_Decryption>(8,6), valdata, 4) && pass; 00800 pass = BlockTransformationTest(VariableRoundsCipherFactory<SAFER_SK_Encryption, SAFER_SK_Decryption>(16,10), valdata, 4) && pass; 00801 return pass; 00802 } 00803 00804 bool ValidateRC2() 00805 { 00806 cout << "\nRC2 validation suite running...\n\n"; 00807 00808 FileSource valdata(PKGDATA("rc2val.dat"), true, new HexDecoder); 00809 HexEncoder output(new FileSink(cout)); 00810 SecByteBlock plain(RC2Encryption::BLOCKSIZE), cipher(RC2Encryption::BLOCKSIZE), out(RC2Encryption::BLOCKSIZE), outplain(RC2Encryption::BLOCKSIZE); 00811 SecByteBlock key(128); 00812 bool pass=true, fail; 00813 00814 while (valdata.MaxRetrievable()) 00815 { 00816 byte keyLen, effectiveLen; 00817 00818 valdata.Get(keyLen); 00819 valdata.Get(effectiveLen); 00820 valdata.Get(key, keyLen); 00821 valdata.Get(plain, RC2Encryption::BLOCKSIZE); 00822 valdata.Get(cipher, RC2Encryption::BLOCKSIZE); 00823 00824 apbt transE(new RC2Encryption(key, keyLen, effectiveLen)); 00825 transE->ProcessBlock(plain, out); 00826 fail = memcmp(out, cipher, RC2Encryption::BLOCKSIZE) != 0; 00827 00828 apbt transD(new RC2Decryption(key, keyLen, effectiveLen)); 00829 transD->ProcessBlock(out, outplain); 00830 fail=fail || memcmp(outplain, plain, RC2Encryption::BLOCKSIZE); 00831 00832 pass = pass && !fail; 00833 00834 cout << (fail ? "FAILED " : "passed "); 00835 output.Put(key, keyLen); 00836 cout << " "; 00837 output.Put(outplain, RC2Encryption::BLOCKSIZE); 00838 cout << " "; 00839 output.Put(out, RC2Encryption::BLOCKSIZE); 00840 cout << endl; 00841 } 00842 return pass; 00843 } 00844 00845 bool ValidateARC4() 00846 { 00847 unsigned char Key0[] = {0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef }; 00848 unsigned char Input0[]={0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef}; 00849 unsigned char Output0[] = {0x75,0xb7,0x87,0x80,0x99,0xe0,0xc5,0x96}; 00850 00851 unsigned char Key1[]={0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef}; 00852 unsigned char Input1[]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; 00853 unsigned char Output1[]={0x74,0x94,0xc2,0xe7,0x10,0x4b,0x08,0x79}; 00854 00855 unsigned char Key2[]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; 00856 unsigned char Input2[]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; 00857 unsigned char Output2[]={0xde,0x18,0x89,0x41,0xa3,0x37,0x5d,0x3a}; 00858 00859 unsigned char Key3[]={0xef,0x01,0x23,0x45}; 00860 unsigned char Input3[]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; 00861 unsigned char Output3[]={0xd6,0xa1,0x41,0xa7,0xec,0x3c,0x38,0xdf,0xbd,0x61}; 00862 00863 unsigned char Key4[]={ 0x01,0x23,0x45,0x67,0x89,0xab, 0xcd,0xef }; 00864 unsigned char Input4[] = 00865 {0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, 00866 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, 00867 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, 00868 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, 00869 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, 00870 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, 00871 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, 00872 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, 00873 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, 00874 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, 00875 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, 00876 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, 00877 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, 00878 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, 00879 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, 00880 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, 00881 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, 00882 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, 00883 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, 00884 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, 00885 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, 00886 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, 00887 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, 00888 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, 00889 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, 00890 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, 00891 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, 00892 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, 00893 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, 00894 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, 00895 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, 00896 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, 00897 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, 00898 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, 00899 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, 00900 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, 00901 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, 00902 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, 00903 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, 00904 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, 00905 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, 00906 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, 00907 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, 00908 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, 00909 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, 00910 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, 00911 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, 00912 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, 00913 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, 00914 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, 00915 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, 00916 0x01}; 00917 unsigned char Output4[]= { 00918 0x75,0x95,0xc3,0xe6,0x11,0x4a,0x09,0x78,0x0c,0x4a,0xd4, 00919 0x52,0x33,0x8e,0x1f,0xfd,0x9a,0x1b,0xe9,0x49,0x8f, 00920 0x81,0x3d,0x76,0x53,0x34,0x49,0xb6,0x77,0x8d,0xca, 00921 0xd8,0xc7,0x8a,0x8d,0x2b,0xa9,0xac,0x66,0x08,0x5d, 00922 0x0e,0x53,0xd5,0x9c,0x26,0xc2,0xd1,0xc4,0x90,0xc1, 00923 0xeb,0xbe,0x0c,0xe6,0x6d,0x1b,0x6b,0x1b,0x13,0xb6, 00924 0xb9,0x19,0xb8,0x47,0xc2,0x5a,0x91,0x44,0x7a,0x95, 00925 0xe7,0x5e,0x4e,0xf1,0x67,0x79,0xcd,0xe8,0xbf,0x0a, 00926 0x95,0x85,0x0e,0x32,0xaf,0x96,0x89,0x44,0x4f,0xd3, 00927 0x77,0x10,0x8f,0x98,0xfd,0xcb,0xd4,0xe7,0x26,0x56, 00928 0x75,0x00,0x99,0x0b,0xcc,0x7e,0x0c,0xa3,0xc4,0xaa, 00929 0xa3,0x04,0xa3,0x87,0xd2,0x0f,0x3b,0x8f,0xbb,0xcd, 00930 0x42,0xa1,0xbd,0x31,0x1d,0x7a,0x43,0x03,0xdd,0xa5, 00931 0xab,0x07,0x88,0x96,0xae,0x80,0xc1,0x8b,0x0a,0xf6, 00932 0x6d,0xff,0x31,0x96,0x16,0xeb,0x78,0x4e,0x49,0x5a, 00933 0xd2,0xce,0x90,0xd7,0xf7,0x72,0xa8,0x17,0x47,0xb6, 00934 0x5f,0x62,0x09,0x3b,0x1e,0x0d,0xb9,0xe5,0xba,0x53, 00935 0x2f,0xaf,0xec,0x47,0x50,0x83,0x23,0xe6,0x71,0x32, 00936 0x7d,0xf9,0x44,0x44,0x32,0xcb,0x73,0x67,0xce,0xc8, 00937 0x2f,0x5d,0x44,0xc0,0xd0,0x0b,0x67,0xd6,0x50,0xa0, 00938 0x75,0xcd,0x4b,0x70,0xde,0xdd,0x77,0xeb,0x9b,0x10, 00939 0x23,0x1b,0x6b,0x5b,0x74,0x13,0x47,0x39,0x6d,0x62, 00940 0x89,0x74,0x21,0xd4,0x3d,0xf9,0xb4,0x2e,0x44,0x6e, 00941 0x35,0x8e,0x9c,0x11,0xa9,0xb2,0x18,0x4e,0xcb,0xef, 00942 0x0c,0xd8,0xe7,0xa8,0x77,0xef,0x96,0x8f,0x13,0x90, 00943 0xec,0x9b,0x3d,0x35,0xa5,0x58,0x5c,0xb0,0x09,0x29, 00944 0x0e,0x2f,0xcd,0xe7,0xb5,0xec,0x66,0xd9,0x08,0x4b, 00945 0xe4,0x40,0x55,0xa6,0x19,0xd9,0xdd,0x7f,0xc3,0x16, 00946 0x6f,0x94,0x87,0xf7,0xcb,0x27,0x29,0x12,0x42,0x64, 00947 0x45,0x99,0x85,0x14,0xc1,0x5d,0x53,0xa1,0x8c,0x86, 00948 0x4c,0xe3,0xa2,0xb7,0x55,0x57,0x93,0x98,0x81,0x26, 00949 0x52,0x0e,0xac,0xf2,0xe3,0x06,0x6e,0x23,0x0c,0x91, 00950 0xbe,0xe4,0xdd,0x53,0x04,0xf5,0xfd,0x04,0x05,0xb3, 00951 0x5b,0xd9,0x9c,0x73,0x13,0x5d,0x3d,0x9b,0xc3,0x35, 00952 0xee,0x04,0x9e,0xf6,0x9b,0x38,0x67,0xbf,0x2d,0x7b, 00953 0xd1,0xea,0xa5,0x95,0xd8,0xbf,0xc0,0x06,0x6f,0xf8, 00954 0xd3,0x15,0x09,0xeb,0x0c,0x6c,0xaa,0x00,0x6c,0x80, 00955 0x7a,0x62,0x3e,0xf8,0x4c,0x3d,0x33,0xc1,0x95,0xd2, 00956 0x3e,0xe3,0x20,0xc4,0x0d,0xe0,0x55,0x81,0x57,0xc8, 00957 0x22,0xd4,0xb8,0xc5,0x69,0xd8,0x49,0xae,0xd5,0x9d, 00958 0x4e,0x0f,0xd7,0xf3,0x79,0x58,0x6b,0x4b,0x7f,0xf6, 00959 0x84,0xed,0x6a,0x18,0x9f,0x74,0x86,0xd4,0x9b,0x9c, 00960 0x4b,0xad,0x9b,0xa2,0x4b,0x96,0xab,0xf9,0x24,0x37, 00961 0x2c,0x8a,0x8f,0xff,0xb1,0x0d,0x55,0x35,0x49,0x00, 00962 0xa7,0x7a,0x3d,0xb5,0xf2,0x05,0xe1,0xb9,0x9f,0xcd, 00963 0x86,0x60,0x86,0x3a,0x15,0x9a,0xd4,0xab,0xe4,0x0f, 00964 0xa4,0x89,0x34,0x16,0x3d,0xdd,0xe5,0x42,0xa6,0x58, 00965 0x55,0x40,0xfd,0x68,0x3c,0xbf,0xd8,0xc0,0x0f,0x12, 00966 0x12,0x9a,0x28,0x4d,0xea,0xcc,0x4c,0xde,0xfe,0x58, 00967 0xbe,0x71,0x37,0x54,0x1c,0x04,0x71,0x26,0xc8,0xd4, 00968 0x9e,0x27,0x55,0xab,0x18,0x1a,0xb7,0xe9,0x40,0xb0, 00969 0xc0}; 00970 00971 // VC60 workaround: auto_ptr lacks reset() 00972 member_ptr<ARC4> arc4; 00973 bool pass=true, fail; 00974 int i; 00975 00976 cout << "\nARC4 validation suite running...\n\n"; 00977 00978 arc4.reset(new ARC4(Key0, sizeof(Key0))); 00979 arc4->ProcessString(Input0, sizeof(Input0)); 00980 fail = memcmp(Input0, Output0, sizeof(Input0)) != 0; 00981 cout << (fail ? "FAILED" : "passed") << " Test 0" << endl; 00982 pass = pass && !fail; 00983 00984 arc4.reset(new ARC4(Key1, sizeof(Key1))); 00985 arc4->ProcessString(Key1, Input1, sizeof(Key1)); 00986 fail = memcmp(Output1, Key1, sizeof(Key1)) != 0; 00987 cout << (fail ? "FAILED" : "passed") << " Test 1" << endl; 00988 pass = pass && !fail; 00989 00990 arc4.reset(new ARC4(Key2, sizeof(Key2))); 00991 for (i=0, fail=false; i<sizeof(Input2); i++) 00992 if (arc4->ProcessByte(Input2[i]) != Output2[i]) 00993 fail = true; 00994 cout << (fail ? "FAILED" : "passed") << " Test 2" << endl; 00995 pass = pass && !fail; 00996 00997 arc4.reset(new ARC4(Key3, sizeof(Key3))); 00998 for (i=0, fail=false; i<sizeof(Input3); i++) 00999 if (arc4->ProcessByte(Input3[i]) != Output3[i]) 01000 fail = true; 01001 cout << (fail ? "FAILED" : "passed") << " Test 3" << endl; 01002 pass = pass && !fail; 01003 01004 arc4.reset(new ARC4(Key4, sizeof(Key4))); 01005 for (i=0, fail=false; i<sizeof(Input4); i++) 01006 if (arc4->ProcessByte(Input4[i]) != Output4[i]) 01007 fail = true; 01008 cout << (fail ? "FAILED" : "passed") << " Test 4" << endl; 01009 pass = pass && !fail; 01010 01011 return pass; 01012 } 01013 01014 bool ValidateRC5() 01015 { 01016 cout << "\nRC5 validation suite running...\n\n"; 01017 01018 FileSource valdata(PKGDATA("rc5val.dat"), true, new HexDecoder); 01019 return BlockTransformationTest(VariableRoundsCipherFactory<RC5Encryption, RC5Decryption>(16, 12), valdata); 01020 } 01021 01022 bool ValidateRC6() 01023 { 01024 cout << "\nRC6 validation suite running...\n\n"; 01025 01026 FileSource valdata(PKGDATA("rc6val.dat"), true, new HexDecoder); 01027 bool pass = true; 01028 pass = BlockTransformationTest(FixedRoundsCipherFactory<RC6Encryption, RC6Decryption>(16), valdata, 2) && pass; 01029 pass = BlockTransformationTest(FixedRoundsCipherFactory<RC6Encryption, RC6Decryption>(24), valdata, 2) && pass; 01030 pass = BlockTransformationTest(FixedRoundsCipherFactory<RC6Encryption, RC6Decryption>(32), valdata, 2) && pass; 01031 return pass; 01032 } 01033 01034 bool ValidateMARS() 01035 { 01036 cout << "\nMARS validation suite running...\n\n"; 01037 01038 FileSource valdata(PKGDATA("marsval.dat"), true, new HexDecoder); 01039 bool pass = true; 01040 pass = BlockTransformationTest(FixedRoundsCipherFactory<MARSEncryption, MARSDecryption>(16), valdata, 4) && pass; 01041 pass = BlockTransformationTest(FixedRoundsCipherFactory<MARSEncryption, MARSDecryption>(24), valdata, 3) && pass; 01042 pass = BlockTransformationTest(FixedRoundsCipherFactory<MARSEncryption, MARSDecryption>(32), valdata, 2) && pass; 01043 return pass; 01044 } 01045 01046 bool ValidateRijndael() 01047 { 01048 cout << "\nRijndael validation suite running...\n\n"; 01049 01050 FileSource valdata(PKGDATA("rijndael.dat"), true, new HexDecoder); 01051 bool pass = true; 01052 pass = BlockTransformationTest(FixedRoundsCipherFactory<RijndaelEncryption, RijndaelDecryption>(16), valdata, 4) && pass; 01053 pass = BlockTransformationTest(FixedRoundsCipherFactory<RijndaelEncryption, RijndaelDecryption>(24), valdata, 3) && pass; 01054 pass = BlockTransformationTest(FixedRoundsCipherFactory<RijndaelEncryption, RijndaelDecryption>(32), valdata, 2) && pass; 01055 return pass; 01056 } 01057 01058 bool ValidateTwofish() 01059 { 01060 cout << "\nTwofish validation suite running...\n\n"; 01061 01062 FileSource valdata(PKGDATA("twofishv.dat"), true, new HexDecoder); 01063 bool pass = true; 01064 pass = BlockTransformationTest(FixedRoundsCipherFactory<TwofishEncryption, TwofishDecryption>(16), valdata, 4) && pass; 01065 pass = BlockTransformationTest(FixedRoundsCipherFactory<TwofishEncryption, TwofishDecryption>(24), valdata, 3) && pass; 01066 pass = BlockTransformationTest(FixedRoundsCipherFactory<TwofishEncryption, TwofishDecryption>(32), valdata, 2) && pass; 01067 return pass; 01068 } 01069 01070 bool ValidateSerpent() 01071 { 01072 cout << "\nSerpent validation suite running...\n\n"; 01073 01074 FileSource valdata(PKGDATA("serpentv.dat"), true, new HexDecoder); 01075 bool pass = true; 01076 pass = BlockTransformationTest(FixedRoundsCipherFactory<SerpentEncryption, SerpentDecryption>(16), valdata, 4) && pass; 01077 pass = BlockTransformationTest(FixedRoundsCipherFactory<SerpentEncryption, SerpentDecryption>(24), valdata, 3) && pass; 01078 pass = BlockTransformationTest(FixedRoundsCipherFactory<SerpentEncryption, SerpentDecryption>(32), valdata, 2) && pass; 01079 return pass; 01080 } 01081 01082 bool ValidateBlowfish() 01083 { 01084 cout << "\nBlowfish validation suite running...\n\n"; 01085 01086 HexEncoder output(new FileSink(cout)); 01087 char *key[]={"abcdefghijklmnopqrstuvwxyz", "Who is John Galt?"}; 01088 byte *plain[]={(byte *)"BLOWFISH", (byte *)"\xfe\xdc\xba\x98\x76\x54\x32\x10"}; 01089 byte *cipher[]={(byte *)"\x32\x4e\xd0\xfe\xf4\x13\xa2\x03", (byte *)"\xcc\x91\x73\x2b\x80\x22\xf6\x84"}; 01090 byte out[8], outplain[8]; 01091 bool pass=true, fail; 01092 01093 for (int i=0; i<2; i++) 01094 { 01095 ECB_Mode<Blowfish>::Encryption enc((byte *)key[i], strlen(key[i])); 01096 enc.ProcessData(out, plain[i], 8); 01097 fail = memcmp(out, cipher[i], 8) != 0; 01098 01099 ECB_Mode<Blowfish>::Decryption dec((byte *)key[i], strlen(key[i])); 01100 dec.ProcessData(outplain, cipher[i], 8); 01101 fail = fail || memcmp(outplain, plain[i], 8); 01102 pass = pass && !fail; 01103 01104 cout << (fail ? "FAILED " : "passed "); 01105 cout << '\"' << key[i] << '\"'; 01106 for (int j=0; j<(signed int)(30-strlen(key[i])); j++) 01107 cout << ' '; 01108 output.Put(outplain, 8); 01109 cout << " "; 01110 output.Put(out, 8); 01111 cout << endl; 01112 } 01113 return pass; 01114 } 01115 01116 bool ValidateThreeWay() 01117 { 01118 cout << "\n3-WAY validation suite running...\n\n"; 01119 01120 FileSource valdata(PKGDATA("3wayval.dat"), true, new HexDecoder); 01121 return BlockTransformationTest(FixedRoundsCipherFactory<ThreeWayEncryption, ThreeWayDecryption>(), valdata); 01122 } 01123 01124 bool ValidateGOST() 01125 { 01126 cout << "\nGOST validation suite running...\n\n"; 01127 01128 FileSource valdata(PKGDATA("gostval.dat"), true, new HexDecoder); 01129 return BlockTransformationTest(FixedRoundsCipherFactory<GOSTEncryption, GOSTDecryption>(), valdata); 01130 } 01131 01132 bool ValidateSHARK() 01133 { 01134 cout << "\nSHARK validation suite running...\n\n"; 01135 01136 #ifdef WORD64_AVAILABLE 01137 FileSource valdata(PKGDATA("sharkval.dat"), true, new HexDecoder); 01138 return BlockTransformationTest(FixedRoundsCipherFactory<SHARKEncryption, SHARKDecryption>(), valdata); 01139 #else 01140 cout << "word64 not available, skipping SHARK validation." << endl; 01141 return true; 01142 #endif 01143 } 01144 01145 bool ValidateCAST() 01146 { 01147 bool pass = true; 01148 01149 cout << "\nCAST-128 validation suite running...\n\n"; 01150 01151 FileSource val128(PKGDATA("cast128v.dat"), true, new HexDecoder); 01152 pass = BlockTransformationTest(FixedRoundsCipherFactory<CAST128Encryption, CAST128Decryption>(16), val128, 1) && pass; 01153 pass = BlockTransformationTest(FixedRoundsCipherFactory<CAST128Encryption, CAST128Decryption>(10), val128, 1) && pass; 01154 pass = BlockTransformationTest(FixedRoundsCipherFactory<CAST128Encryption, CAST128Decryption>(5), val128, 1) && pass; 01155 01156 cout << "\nCAST-256 validation suite running...\n\n"; 01157 01158 FileSource val256(PKGDATA("cast256v.dat"), true, new HexDecoder); 01159 pass = BlockTransformationTest(FixedRoundsCipherFactory<CAST256Encryption, CAST256Decryption>(16), val256, 1) && pass; 01160 pass = BlockTransformationTest(FixedRoundsCipherFactory<CAST256Encryption, CAST256Decryption>(24), val256, 1) && pass; 01161 pass = BlockTransformationTest(FixedRoundsCipherFactory<CAST256Encryption, CAST256Decryption>(32), val256, 1) && pass; 01162 01163 return pass; 01164 } 01165 01166 bool ValidateSquare() 01167 { 01168 cout << "\nSquare validation suite running...\n\n"; 01169 01170 FileSource valdata(PKGDATA("squareva.dat"), true, new HexDecoder); 01171 return BlockTransformationTest(FixedRoundsCipherFactory<SquareEncryption, SquareDecryption>(), valdata); 01172 } 01173 01174 bool ValidateSKIPJACK() 01175 { 01176 cout << "\nSKIPJACK validation suite running...\n\n"; 01177 01178 FileSource valdata(PKGDATA("skipjack.dat"), true, new HexDecoder); 01179 return BlockTransformationTest(FixedRoundsCipherFactory<SKIPJACKEncryption, SKIPJACKDecryption>(), valdata); 01180 } 01181 01182 bool ValidateSEAL() 01183 { 01184 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}; 01185 byte output[32]; 01186 byte key[] = {0x67, 0x45, 0x23, 0x01, 0xef, 0xcd, 0xab, 0x89, 0x98, 0xba, 0xdc, 0xfe, 0x10, 0x32, 0x54, 0x76, 0xc3, 0xd2, 0xe1, 0xf0}; 01187 byte iv[] = {0x01, 0x35, 0x77, 0xaf}; 01188 01189 cout << "\nSEAL validation suite running...\n\n"; 01190 01191 SEAL<>::Encryption seal(key, sizeof(key), iv); 01192 unsigned int size = sizeof(input); 01193 bool pass = true; 01194 01195 memset(output, 1, size); 01196 seal.ProcessString(output, input, size); 01197 for (unsigned int i=0; i<size; i++) 01198 if (output[i] != 0) 01199 pass = false; 01200 01201 seal.Seek(1); 01202 output[1] = seal.ProcessByte(output[1]); 01203 seal.ProcessString(output+2, size-2); 01204 pass = pass && memcmp(output+1, input+1, size-1) == 0; 01205 01206 cout << (pass ? "passed" : "FAILED") << endl; 01207 return pass; 01208 } 01209 01210 bool ValidateBaseCode() 01211 { 01212 bool pass = true, fail; 01213 byte data[255]; 01214 for (unsigned int i=0; i<255; i++) 01215 data[i] = i; 01216 const char *hexEncoded = 01217 "000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F2021222324252627" 01218 "28292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D4E4F" 01219 "505152535455565758595A5B5C5D5E5F606162636465666768696A6B6C6D6E6F7071727374757677" 01220 "78797A7B7C7D7E7F808182838485868788898A8B8C8D8E8F909192939495969798999A9B9C9D9E9F" 01221 "A0A1A2A3A4A5A6A7A8A9AAABACADAEAFB0B1B2B3B4B5B6B7B8B9BABBBCBDBEBFC0C1C2C3C4C5C6C7" 01222 "C8C9CACBCCCDCECFD0D1D2D3D4D5D6D7D8D9DADBDCDDDEDFE0E1E2E3E4E5E6E7E8E9EAEBECEDEEEF" 01223 "F0F1F2F3F4F5F6F7F8F9FAFBFCFDFE"; 01224 const char *base32Encoded = 01225 "AAASEA2EAWDAQCAJBIFS2DIQB6IBCESVCSKTNF22DEPBYHA7D2RUAIJCENUCKJTHFAWUWK3NFWZC8NBT" 01226 "GI3VIPJYG66DUQT5HS8V6R4AIFBEGTCFI3DWSUKKJPGE4VURKBIXEW4WKXMFQYC3MJPX2ZK8M7SGC2VD" 01227 "NTUYN35IPFXGY5DPP3ZZA6MUQP4HK7VZRB6ZW856RX9H9AEBSKB2JBNGS8EIVCWMTUG27D6SUGJJHFEX" 01228 "U4M3TGN4VQQJ5HW9WCS4FI7EWYVKRKFJXKX43MPQX82MDNXVYU45PP72ZG7MZRF7Z496BSQC2RCNMTYH" 01229 "3DE6XU8N3ZHN9WGT4MJ7JXQY49NPVYY55VQ77Z9A6HTQH3HF65V8T4RK7RYQ55ZR8D29F69W8Z5RR8H3" 01230 "9M7939R8"; 01231 const char *base64AndHexEncoded = 01232 "41414543417751464267634943516F4C4441304F4478415245684D554652595847426B6147787764" 01233 "486838674953496A4A43556D4A7967704B6973734C5334764D4445794D7A51310A4E6A63344F546F" 01234 "375044302B50304242516B4E4552555A4853456C4B5330784E546B395155564A5456465657563168" 01235 "5A576C746358563566594746695932526C5A6D646F615770720A6247317562334278636E4E306458" 01236 "5A3365486C3665337839666E2B4167594B44684957476834694A696F754D6A5936506B4A47536B35" 01237 "53566C7065596D5A71626E4A32656E3643680A6F714F6B7061616E714B6D717136797472712B7773" 01238 "624B7A744C573274376935757275387662362F774D484377385446787366497963724C7A4D334F7A" 01239 "39445230745055316462580A324E6E6132397A6433742F6734654C6A354F586D352B6A7036757673" 01240 "3765377638504879382F5431397666342B6672372F50332B0A"; 01241 01242 cout << "\nBase64, base32 and hex coding validation suite running...\n\n"; 01243 01244 fail = !TestFilter(HexEncoder().Ref(), data, 255, (const byte *)hexEncoded, strlen(hexEncoded)); 01245 cout << (fail ? "FAILED " : "passed "); 01246 cout << "Hex Encoding\n"; 01247 pass = pass && !fail; 01248 01249 fail = !TestFilter(HexDecoder().Ref(), (const byte *)hexEncoded, strlen(hexEncoded), data, 255); 01250 cout << (fail ? "FAILED " : "passed "); 01251 cout << "Hex Decoding\n"; 01252 pass = pass && !fail; 01253 01254 fail = !TestFilter(Base32Encoder().Ref(), data, 255, (const byte *)base32Encoded, strlen(base32Encoded)); 01255 cout << (fail ? "FAILED " : "passed "); 01256 cout << "Base32 Encoding\n"; 01257 pass = pass && !fail; 01258 01259 fail = !TestFilter(Base32Decoder().Ref(), (const byte *)base32Encoded, strlen(base32Encoded), data, 255); 01260 cout << (fail ? "FAILED " : "passed "); 01261 cout << "Base32 Decoding\n"; 01262 pass = pass && !fail; 01263 01264 fail = !TestFilter(Base64Encoder(new HexEncoder).Ref(), data, 255, (const byte *)base64AndHexEncoded, strlen(base64AndHexEncoded)); 01265 cout << (fail ? "FAILED " : "passed "); 01266 cout << "Base64 Encoding\n"; 01267 pass = pass && !fail; 01268 01269 fail = !TestFilter(HexDecoder(new Base64Decoder).Ref(), (const byte *)base64AndHexEncoded, strlen(base64AndHexEncoded), data, 255); 01270 cout << (fail ? "FAILED " : "passed "); 01271 cout << "Base64 Decoding\n"; 01272 pass = pass && !fail; 01273 01274 return pass; 01275 } 01276 01277 bool ValidateSHACAL2() 01278 { 01279 cout << "\nSHACAL-2 validation suite running...\n\n"; 01280 01281 bool pass = true; 01282 FileSource valdata(PKGDATA("shacal2v.dat"), true, new HexDecoder); 01283 pass = BlockTransformationTest(FixedRoundsCipherFactory<SHACAL2Encryption, SHACAL2Decryption>(16), valdata, 4) && pass; 01284 pass = BlockTransformationTest(FixedRoundsCipherFactory<SHACAL2Encryption, SHACAL2Decryption>(64), valdata, 10) && pass; 01285 return pass; 01286 } 01287 01288 bool ValidateCamellia() 01289 { 01290 cout << "\nCamellia validation suite running...\n\n"; 01291 01292 #ifdef WORD64_AVAILABLE 01293 bool pass = true; 01294 FileSource valdata(PKGDATA("camellia.dat"), true, new HexDecoder); 01295 pass = BlockTransformationTest(FixedRoundsCipherFactory<CamelliaEncryption, CamelliaDecryption>(16), valdata, 15) && pass; 01296 pass = BlockTransformationTest(FixedRoundsCipherFactory<CamelliaEncryption, CamelliaDecryption>(24), valdata, 15) && pass; 01297 pass = BlockTransformationTest(FixedRoundsCipherFactory<CamelliaEncryption, CamelliaDecryption>(32), valdata, 15) && pass; 01298 return pass; 01299 #else 01300 cout << "word64 not available, skipping Camellia validation." << endl; 01301 return true; 01302 #endif 01303 }

Generated on Fri Aug 27 11:32:50 2004 for Crypto++ by doxygen 1.3.8