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

Generated on Fri Aug 13 09:56:55 2004 for Crypto++ by doxygen 1.3.7