validat1.cpp

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

Generated on Fri Feb 6 00:56:26 2009 for Crypto++ by  doxygen 1.4.7