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

fipsalgt.cpp

00001 // fipsalgt.cpp - written and placed in the public domain by Wei Dai
00002 
00003 // This file implements the various algorithm tests needed to pass FIPS 140 validation.
00004 // They're preserved here (commented out) in case Crypto++ needs to be revalidated.
00005 
00006 #if 0
00007 #ifndef CRYPTOPP_IMPORTS
00008 #define CRYPTOPP_DEFAULT_NO_DLL
00009 #endif
00010 #include "dll.h"
00011 #include "oids.h"
00012 
00013 USING_NAMESPACE(CryptoPP)
00014 USING_NAMESPACE(std)
00015 
00016 class LineBreakParser : public AutoSignaling<Bufferless<Filter> >
00017 {
00018 public:
00019         LineBreakParser(BufferedTransformation *attachment=NULL, byte lineEnd='\n')
00020                 : m_lineEnd(lineEnd) {Detach(attachment);}
00021 
00022         unsigned int Put2(const byte *begin, unsigned int length, int messageEnd, bool blocking)
00023         {
00024                 if (!blocking)
00025                         throw BlockingInputOnly("LineBreakParser");
00026                 
00027                 unsigned int i, last = 0;
00028                 for (i=0; i<length; i++)
00029                 {
00030                         if (begin[i] == m_lineEnd)
00031                         {
00032                                 AttachedTransformation()->Put2(begin+last, i-last, GetAutoSignalPropagation(), blocking);
00033                                 last = i+1;
00034                         }
00035                 }
00036                 if (last != i)
00037                         AttachedTransformation()->Put2(begin+last, i-last, 0, blocking);
00038 
00039                 if (messageEnd && GetAutoSignalPropagation())
00040                 {
00041                         AttachedTransformation()->MessageEnd(GetAutoSignalPropagation()-1, blocking);
00042                         AttachedTransformation()->MessageSeriesEnd(GetAutoSignalPropagation()-1, blocking);
00043                 }
00044 
00045                 return 0;
00046         }
00047 
00048 private:
00049         byte m_lineEnd;
00050 };
00051 
00052 class TestDataParser : public Unflushable<FilterWithInputQueue>
00053 {
00054 public:
00055         enum DataType {OTHER, COUNT, KEY_T, IV, INPUT, OUTPUT};
00056 
00057         TestDataParser(std::string algorithm, std::string test, std::string mode, unsigned int feedbackSize, bool encrypt, BufferedTransformation *attachment)
00058                 : m_algorithm(algorithm), m_test(test), m_mode(mode), m_feedbackSize(feedbackSize)
00059                 , m_firstLine(true), m_blankLineTransition(0)
00060         {
00061                 Detach(attachment);
00062 
00063                 m_nameToType["COUNT"] = COUNT;
00064                 m_nameToType["KEY"] = KEY_T;
00065                 m_nameToType["KEYs"] = KEY_T;
00066                 m_nameToType["key"] = KEY_T;
00067                 m_nameToType["Key"] = KEY_T;
00068                 m_nameToType["IV"] = IV;
00069                 m_nameToType["IV1"] = IV;
00070                 m_nameToType["CV"] = IV;
00071                 m_nameToType["CV1"] = IV;
00072                 m_nameToType["IB"] = IV;
00073                 m_nameToType["TEXT"] = INPUT;
00074                 m_nameToType["RESULT"] = OUTPUT;
00075                 m_nameToType["Msg"] = INPUT;
00076                 m_nameToType["Seed"] = INPUT;
00077                 m_nameToType["V"] = INPUT;
00078                 m_nameToType["DT"] = IV;
00079                 SetEncrypt(encrypt);
00080 
00081                 if (m_algorithm == "DSS")
00082                 {
00083                         if (m_test == "prime")
00084                                 m_trigger = "Prime";
00085                         else if (m_test == "pqg")
00086                                 m_trigger = "N";
00087                         else if (m_test == "xy")
00088                                 m_trigger = "G";
00089                         else if (m_test == "gensig")
00090                                 m_trigger = "Msg";
00091                         else if (m_test == "versig")
00092                                 m_trigger = "Sig";
00093                         else if (m_test == "verpqg")
00094                                 m_trigger = "c";
00095                 }
00096                 else if (m_algorithm == "HMAC")
00097                         m_trigger = "Msg";
00098                 else if (m_algorithm == "SHA2")
00099                         m_trigger = (m_test == "MONTE") ? "Seed" : "Msg";
00100                 else if (m_algorithm == "ECDSA")
00101                 {
00102                         if (m_test == "PKV")
00103                                 m_trigger = "Qy";
00104                         else if (m_test == "KeyPair")
00105                                 m_trigger = "N";
00106                         else if (m_test == "SigGen")
00107                                 m_trigger = "Msg";
00108                         else if (m_test == "SigVer")
00109                                 m_trigger = "S";
00110                 }
00111                 else if (m_algorithm == "RNG")
00112                         m_trigger = "V";
00113                 else if (m_algorithm == "RSA")
00114                         m_trigger = (m_test == "Ver") ? "S" : "Msg";
00115         }
00116 
00117         void SetEncrypt(bool encrypt)
00118         {
00119                 m_encrypt = encrypt;
00120                 if (encrypt)
00121                 {
00122                         m_nameToType["PLAINTEXT"] = INPUT;
00123                         m_nameToType["CIPHERTEXT"] = OUTPUT;
00124                         m_nameToType["PT"] = INPUT;
00125                         m_nameToType["CT"] = OUTPUT;
00126                 }
00127                 else
00128                 {
00129                         m_nameToType["PLAINTEXT"] = OUTPUT;
00130                         m_nameToType["CIPHERTEXT"] = INPUT;
00131                         m_nameToType["PT"] = OUTPUT;
00132                         m_nameToType["CT"] = INPUT;
00133                 }
00134 
00135                 if (m_algorithm == "AES" || m_algorithm == "TDES")
00136                 {
00137                         if (encrypt)
00138                         {
00139                                 m_trigger = "PLAINTEXT";
00140                                 m_typeToName[OUTPUT] = "CIPHERTEXT";
00141                         }
00142                         else
00143                         {
00144                                 m_trigger = "CIPHERTEXT";
00145                                 m_typeToName[OUTPUT] = "PLAINTEXT";
00146                         }
00147                         m_count = 0;
00148                 }
00149         }
00150 
00151 protected:
00152         void OutputData(std::string &output, const std::string &key, const std::string &data)
00153         {
00154                 output += key;
00155                 output += "= ";
00156                 output += data;
00157                 output += "\n";
00158         }
00159 
00160         void OutputData(std::string &output, const std::string &key, int data)
00161         {
00162                 OutputData(output, key, IntToString(data));
00163         }
00164 
00165         void OutputData(std::string &output, const std::string &key, const SecByteBlock &data)
00166         {
00167                 output += key;
00168                 output += "= ";
00169                 HexEncoder(new StringSink(output), false).Put(data, data.size());
00170                 output += "\n";
00171         }
00172 
00173         void OutputData(std::string &output, const std::string &key, const Integer &data, int size=-1)
00174         {
00175                 SecByteBlock s(size < 0 ? data.MinEncodedSize() : size);
00176                 data.Encode(s, s.size());
00177                 OutputData(output, key, s);
00178         }
00179 
00180         void OutputData(std::string &output, const std::string &key, const PolynomialMod2 &data, int size=-1)
00181         {
00182                 SecByteBlock s(size < 0 ? data.MinEncodedSize() : size);
00183                 data.Encode(s, s.size());
00184                 OutputData(output, key, s);
00185         }
00186 
00187         void OutputData(std::string &output, DataType t, const std::string &data)
00188         {
00189                 if (m_algorithm == "SKIPJACK")
00190                 {
00191                         if (m_test == "KAT")
00192                         {
00193                                 if (t == OUTPUT)
00194                                         output = m_line + data + "\n";
00195                         }
00196                         else
00197                         {
00198                                 if (t != COUNT)
00199                                 {
00200                                         output += m_typeToName[t];
00201                                         output += "=";
00202                                 }
00203                                 output += data;
00204                                 output += t == OUTPUT ? "\n" : "  ";
00205                         }
00206                 }
00207                 else if (m_algorithm == "TDES" && t == KEY_T && m_typeToName[KEY_T].empty())
00208                 {
00209                         output += "KEY1 = ";
00210                         output += data.substr(0, 16);
00211                         output += "\nKEY2 = ";
00212                         output += data.size() > 16 ? data.substr(16, 16) : data.substr(0, 16);
00213                         output += "\nKEY3 = ";
00214                         output += data.size() > 32 ? data.substr(32, 16) : data.substr(0, 16);
00215                         output += "\n";
00216                 }
00217                 else
00218                 {
00219                         output += m_typeToName[t];
00220                         output += " = ";
00221                         output += data;
00222                         output += "\n";
00223                 }
00224         }
00225 
00226         void OutputData(std::string &output, DataType t, int i)
00227         {
00228                 OutputData(output, t, IntToString(i));
00229         }
00230 
00231         void OutputData(std::string &output, DataType t, const SecByteBlock &data)
00232         {
00233                 std::string hexData;
00234                 StringSource(data.begin(), data.size(), true, new HexEncoder(new StringSink(hexData), false));
00235                 OutputData(output, t, hexData);
00236         }
00237 
00238         void OutputGivenData(std::string &output, DataType t, bool optional = false)
00239         {
00240                 if (m_data.find(m_typeToName[t]) == m_data.end())
00241                 {
00242                         if (optional)
00243                                 return;
00244                         throw Exception(Exception::OTHER_ERROR, "TestDataParser: key not found: " + m_typeToName[t]);
00245                 }
00246 
00247                 OutputData(output, t, m_data[m_typeToName[t]]);
00248         }
00249 
00250         template <class T>
00251                 BlockCipher * NewBT(T *)
00252         {
00253                 if (!m_encrypt && (m_mode == "ECB" || m_mode == "CBC"))
00254                         return new typename T::Decryption;
00255                 else
00256                         return new typename T::Encryption;
00257         }
00258 
00259         template <class T>
00260                 SymmetricCipher * NewMode(T *, BlockCipher &bt, const byte *iv)
00261         {
00262                 if (!m_encrypt)
00263                         return new typename T::Decryption(bt, iv, m_feedbackSize/8);
00264                 else
00265                         return new typename T::Encryption(bt, iv, m_feedbackSize/8);
00266         }
00267 
00268         static inline void Xor(SecByteBlock &z, const SecByteBlock &x, const SecByteBlock &y)
00269         {
00270                 assert(x.size() == y.size());
00271                 z.resize(x.size());
00272                 xorbuf(z, x, y, x.size());
00273         }
00274 
00275         SecByteBlock UpdateKey(SecByteBlock key, const SecByteBlock *text)
00276         {
00277                 unsigned int innerCount = (m_algorithm == "AES") ? 1000 : 10000;
00278                 int keySize = key.size(), blockSize = text[0].size();
00279                 SecByteBlock x(keySize);
00280                 for (int k=0; k<keySize;)
00281                 {
00282                         int pos = innerCount * blockSize - keySize + k;
00283                         memcpy(x + k, text[pos / blockSize] + pos % blockSize, blockSize - pos % blockSize);
00284                         k += blockSize - pos % blockSize;
00285                 }
00286 
00287                 if (m_algorithm == "TDES" || m_algorithm == "DES")
00288                 {
00289                         for (int i=0; i<keySize; i+=8)
00290                         {
00291                                 xorbuf(key+i, x+keySize-8-i, 8);
00292                                 DES::CorrectKeyParityBits(key+i);
00293                         }
00294                 }
00295                 else
00296                         xorbuf(key, x, keySize);
00297 
00298                 return key;
00299         }
00300 
00301         static inline void AssignLeftMostBits(SecByteBlock &z, const SecByteBlock &x, unsigned int K)
00302         {
00303                 z.Assign(x, K/8);
00304         }
00305 
00306         template <class EC>
00307         void EC_KeyPair(string &output, int n, const OID &oid)
00308         {
00309                 DL_GroupParameters_EC<EC> params(oid);
00310                 for (int i=0; i<n; i++)
00311                 {
00312                         DL_PrivateKey_EC<EC> priv;
00313                         DL_PublicKey_EC<EC> pub;
00314                         priv.Initialize(m_rng, params);
00315                         priv.MakePublicKey(pub);
00316 
00317                         OutputData(output, "d ", priv.GetPrivateExponent());
00318                         OutputData(output, "Qx ", pub.GetPublicElement().x, params.GetCurve().GetField().MaxElementByteLength());
00319                         OutputData(output, "Qy ", pub.GetPublicElement().y, params.GetCurve().GetField().MaxElementByteLength());
00320                 }
00321         }
00322 
00323         template <class EC>
00324         void EC_SigGen(string &output, const OID &oid)
00325         {
00326                 DL_GroupParameters_EC<EC> params(oid);
00327                 ECDSA<EC, SHA1>::PrivateKey priv;
00328                 ECDSA<EC, SHA1>::PublicKey pub;
00329                 priv.Initialize(m_rng, params);
00330                 priv.MakePublicKey(pub);
00331 
00332                 ECDSA<EC, SHA1>::Signer signer(priv);
00333                 SecByteBlock sig(signer.SignatureLength());
00334                 StringSource(m_data["Msg"], true, new HexDecoder(new SignerFilter(m_rng, signer, new ArraySink(sig, sig.size()))));
00335                 SecByteBlock R(sig, sig.size()/2), S(sig+sig.size()/2, sig.size()/2);
00336 
00337                 OutputData(output, "Qx ", pub.GetPublicElement().x, params.GetCurve().GetField().MaxElementByteLength());
00338                 OutputData(output, "Qy ", pub.GetPublicElement().y, params.GetCurve().GetField().MaxElementByteLength());
00339                 OutputData(output, "R ", R);
00340                 OutputData(output, "S ", S);
00341         }
00342 
00343         template <class EC>
00344         void EC_SigVer(string &output, const OID &oid)
00345         {
00346                 SecByteBlock x(DecodeHex(m_data["Qx"]));
00347                 SecByteBlock y(DecodeHex(m_data["Qy"]));
00348                 Integer r((m_data["R"]+"h").c_str());
00349                 Integer s((m_data["S"]+"h").c_str());
00350 
00351                 EC::FieldElement Qx(x, x.size());
00352                 EC::FieldElement Qy(y, y.size());
00353                 EC::Element Q(Qx, Qy);
00354 
00355                 DL_GroupParameters_EC<EC> params(oid);
00356                 ECDSA<EC, SHA1>::PublicKey pub;
00357                 pub.Initialize(params, Q);
00358                 ECDSA<EC, SHA1>::Verifier verifier(pub);
00359 
00360                 SecByteBlock sig(verifier.SignatureLength());
00361                 r.Encode(sig, sig.size()/2);
00362                 s.Encode(sig+sig.size()/2, sig.size()/2);
00363 
00364                 SignatureVerificationFilter filter(verifier);
00365                 filter.Put(sig, sig.size());
00366                 StringSource(m_data["Msg"], true, new HexDecoder(new Redirector(filter, Redirector::DATA_ONLY)));
00367                 filter.MessageEnd();
00368                 byte b;
00369                 filter.Get(b);
00370                 OutputData(output, "Result ", b ? "P" : "F");
00371         }
00372 
00373         template <class EC>
00374         static bool EC_PKV(RandomNumberGenerator &rng, const SecByteBlock &x, const SecByteBlock &y, const OID &oid)
00375         {
00376                 EC::FieldElement Qx(x, x.size());
00377                 EC::FieldElement Qy(y, y.size());
00378                 EC::Element Q(Qx, Qy);
00379 
00380                 DL_GroupParameters_EC<EC> params(oid);
00381                 ECDSA<EC, SHA1>::PublicKey pub;
00382                 pub.Initialize(params, Q);
00383                 return pub.Validate(rng, 3);
00384         }
00385 
00386         template <class H, class Result>
00387         Result * CreateRSA2(const std::string &standard)
00388         {
00389                 if (typeid(Result) == typeid(PK_Verifier))
00390                 {
00391                         if (standard == "R")
00392                                 return (Result *) new RSASS_ISO<H>::Verifier;
00393                         else if (standard == "P")
00394                                 return (Result *) new RSASS<PSS, H>::Verifier;
00395                         else if (standard == "1")
00396                                 return (Result *) new RSASS<PKCS1v15, H>::Verifier;
00397                 }
00398                 else if (typeid(Result) == typeid(PK_Signer))
00399                 {
00400                         if (standard == "R")
00401                                 return (Result *) new RSASS_ISO<H>::Signer;
00402                         else if (standard == "P")
00403                                 return (Result *) new RSASS<PSS, H>::Signer;
00404                         else if (standard == "1")
00405                                 return (Result *) new RSASS<PKCS1v15, H>::Signer;
00406                 }
00407 
00408                 return NULL;
00409         }
00410 
00411         template <class Result>
00412         Result * CreateRSA(const std::string &standard, const std::string &hash)
00413         {
00414                 if (hash == "1")
00415                         return CreateRSA2<SHA1, Result>(standard);
00416                 else if (hash == "224")
00417                         return CreateRSA2<SHA224, Result>(standard);
00418                 else if (hash == "256")
00419                         return CreateRSA2<SHA256, Result>(standard);
00420                 else if (hash == "384")
00421                         return CreateRSA2<SHA384, Result>(standard);
00422                 else if (hash == "512")
00423                         return CreateRSA2<SHA512, Result>(standard);
00424                 else
00425                         return NULL;
00426         }
00427 
00428         virtual void DoTest()
00429         {
00430                 std::string output;
00431 
00432                 if (m_algorithm == "DSS")
00433                 {
00434                         if (m_test == "sha")
00435                         {
00436                                 assert(m_compactString.size() >= 2);
00437                                 assert(m_compactString[0] == m_compactString.size()-2);
00438                                 bool b = !!m_compactString[1];
00439                                 Integer m;
00440                                 unsigned int bitLength = 0;
00441 
00442                                 for (unsigned int j = 2; j < m_compactString.size(); j++)
00443                                 {
00444                                         m <<= m_compactString[j];
00445                                         for (unsigned int k = 0; k < m_compactString[j]; k++)
00446                                                 m.SetBit(k, b);
00447                                         bitLength += m_compactString[j];
00448                                         b = !b;
00449                                 }
00450                                 m_compactString.clear();
00451                                 assert(bitLength % 8 == 0);
00452 
00453                                 SecByteBlock message(bitLength / 8);
00454                                 m.Encode(message, message.size());
00455                                 SHA sha;
00456 
00457                                 if (m_bracketString == "SHS Type 3 Strings")
00458                                 {
00459                                         SecByteBlock m1;
00460                                         for (int j = 0; j < 100; j++)
00461                                         {
00462                                                 for (word32 i = 1; i <= 50000; i++)
00463                                                 {
00464                                                         m1.resize(message.size() + j/4 + 3 + 4);
00465                                                         memcpy(m1, message, message.size());
00466                                                         memset(m1 + message.size(), 0, j/4 + 3);
00467                                                         PutWord(false, BIG_ENDIAN_ORDER, m1 + m1.size() - 4, i);
00468                                                         message.resize(sha.DigestSize());
00469                                                         sha.CalculateDigest(message, m1, m1.size());
00470                                                 }
00471                                                 StringSource(message, message.size(), true, new HexEncoder(new StringSink(output)));
00472                                                 output += " ^\n";
00473                                                 AttachedTransformation()->Put((byte *)output.data(), output.size());
00474                                                 output.resize(0);
00475                                         }
00476                                 }
00477                                 else
00478                                 {
00479                                         StringSource(message, message.size(), true, new HashFilter(sha, new HexEncoder(new StringSink(output))));
00480                                         output += " ^\n";
00481                                         AttachedTransformation()->Put((byte *)output.data(), output.size());
00482                                 }
00483                         }
00484                         else if (m_test == "prime")
00485                         {
00486                                 Integer p((m_data["Prime"] + "h").c_str());
00487                                 OutputData(output, "result", VerifyPrime(m_rng, p, 2) ? "P" : "F");
00488                                 AttachedTransformation()->Put((byte *)output.data(), output.size());
00489                                 output.resize(0);
00490                         }
00491                         else if (m_test == "pqg")
00492                         {
00493                                 int n = atol(m_data["N"].c_str());
00494                                 for (int i=0; i<n; i++)
00495                                 {
00496                                         Integer p, q, h, g;
00497                                         int counter;
00498                                         
00499                                         SecByteBlock seed(SHA::DIGESTSIZE);
00500                                         do
00501                                         {
00502                                                 m_rng.GenerateBlock(seed, seed.size());
00503                                         }
00504                                         while (!DSA::GeneratePrimes(seed, seed.size()*8, counter, p, 1024, q));
00505                                         h.Randomize(m_rng, 2, p-2);
00506                                         g = a_exp_b_mod_c(h, (p-1)/q, p);
00507 
00508                                         OutputData(output, "P", p);
00509                                         OutputData(output, "Q", q);
00510                                         OutputData(output, "G", g);
00511                                         OutputData(output, "Seed", seed);
00512                                         OutputData(output, "H", h, p.ByteCount());
00513                                         OutputData(output, "c", counter);
00514                                         AttachedTransformation()->Put((byte *)output.data(), output.size());
00515                                         output.resize(0);
00516                                 }
00517                         }
00518                         else if (m_test == "xy")
00519                         {
00520                                 Integer p((m_data["P"] + "h").c_str());
00521                                 Integer q((m_data["Q"] + "h").c_str());
00522                                 Integer g((m_data["G"] + "h").c_str());
00523 
00524                                 for (int i=0; i<10; i++)
00525                                 {
00526                                         DSA::Signer priv(m_rng, p, q, g);
00527                                         DSA::Verifier pub(priv);
00528 
00529                                         OutputData(output, "X", priv.GetKey().GetPrivateExponent());
00530                                         OutputData(output, "Y", pub.GetKey().GetPublicElement());
00531                                         AttachedTransformation()->Put((byte *)output.data(), output.size());
00532                                         output.resize(0);
00533                                 }
00534                         }
00535                         else if (m_test == "gensig")
00536                         {
00537                                 Integer p((m_data["P"] + "h").c_str());
00538                                 Integer q((m_data["Q"] + "h").c_str());
00539                                 Integer g((m_data["G"] + "h").c_str());
00540                                 Integer x((m_data["X"] + "h").c_str());
00541                                 DSA::Signer signer(p, q, g, x);
00542 
00543                                 SecByteBlock sig(signer.SignatureLength());
00544                                 StringSource(m_data["Msg"], true, new HexDecoder(new SignerFilter(m_rng, signer, new ArraySink(sig, sig.size()))));
00545                                 OutputData(output, "Sig", sig);
00546                                 AttachedTransformation()->Put((byte *)output.data(), output.size());
00547                                 output.resize(0);
00548                         }
00549                         else if (m_test == "versig")
00550                         {
00551                                 Integer p((m_data["P"] + "h").c_str());
00552                                 Integer q((m_data["Q"] + "h").c_str());
00553                                 Integer g((m_data["G"] + "h").c_str());
00554                                 Integer y((m_data["Y"] + "h").c_str());
00555                                 DSA::Verifier verifier(p, q, g, y);
00556 
00557                                 HexDecoder filter(new SignatureVerificationFilter(verifier));
00558                                 StringSource(m_data["Sig"], true, new Redirector(filter, Redirector::DATA_ONLY));
00559                                 StringSource(m_data["Msg"], true, new Redirector(filter, Redirector::DATA_ONLY));
00560                                 filter.MessageEnd();
00561                                 byte b;
00562                                 filter.Get(b);
00563                                 OutputData(output, "result", b ? "P" : "F");
00564                                 AttachedTransformation()->Put((byte *)output.data(), output.size());
00565                                 output.resize(0);
00566                         }
00567                         else if (m_test == "verpqg")
00568                         {
00569                                 Integer p((m_data["P"] + "h").c_str());
00570                                 Integer q((m_data["Q"] + "h").c_str());
00571                                 Integer g((m_data["G"] + "h").c_str());
00572                                 Integer h((m_data["H"] + "h").c_str());
00573                                 int c = atol(m_data["c"].c_str());
00574                                 SecByteBlock seed(m_data["Seed"].size()/2);
00575                                 StringSource(m_data["Seed"], true, new HexDecoder(new ArraySink(seed, seed.size())));
00576 
00577                                 Integer p1, q1;
00578                                 bool result = DSA::GeneratePrimes(seed, seed.size()*8, c, p1, 1024, q1, true);
00579                                 result = result && (p1 == p && q1 == q);
00580                                 result = result && g == a_exp_b_mod_c(h, (p-1)/q, p);
00581 
00582                                 OutputData(output, "result", result ? "P" : "F");
00583                                 AttachedTransformation()->Put((byte *)output.data(), output.size());
00584                                 output.resize(0);
00585                         }
00586 
00587                         return;
00588                 }
00589 
00590                 if (m_algorithm == "ECDSA")
00591                 {
00592                         std::map<std::string, OID> name2oid;
00593                         name2oid["P-192"] = ASN1::secp192r1();
00594                         name2oid["P-224"] = ASN1::secp224r1();
00595                         name2oid["P-256"] = ASN1::secp256r1();
00596                         name2oid["P-384"] = ASN1::secp384r1();
00597                         name2oid["P-521"] = ASN1::secp521r1();
00598                         name2oid["K-163"] = ASN1::sect163k1();
00599                         name2oid["K-233"] = ASN1::sect233k1();
00600                         name2oid["K-283"] = ASN1::sect283k1();
00601                         name2oid["K-409"] = ASN1::sect409k1();
00602                         name2oid["K-571"] = ASN1::sect571k1();
00603                         name2oid["B-163"] = ASN1::sect163r2();
00604                         name2oid["B-233"] = ASN1::sect233r1();
00605                         name2oid["B-283"] = ASN1::sect283r1();
00606                         name2oid["B-409"] = ASN1::sect409r1();
00607                         name2oid["B-571"] = ASN1::sect571r1();
00608 
00609                         if (m_test == "PKV")
00610                         {
00611                                 bool pass;
00612                                 if (m_bracketString[0] == 'P')
00613                                         pass = EC_PKV<ECP>(m_rng, DecodeHex(m_data["Qx"]), DecodeHex(m_data["Qy"]), name2oid[m_bracketString]);
00614                                 else
00615                                         pass = EC_PKV<EC2N>(m_rng, DecodeHex(m_data["Qx"]), DecodeHex(m_data["Qy"]), name2oid[m_bracketString]);
00616 
00617                                 OutputData(output, "Result ", pass ? "P" : "F");
00618                         }
00619                         else if (m_test == "KeyPair")
00620                         {
00621                                 if (m_bracketString[0] == 'P')
00622                                         EC_KeyPair<ECP>(output, atol(m_data["N"].c_str()), name2oid[m_bracketString]);
00623                                 else
00624                                         EC_KeyPair<EC2N>(output, atol(m_data["N"].c_str()), name2oid[m_bracketString]);
00625                         }
00626                         else if (m_test == "SigGen")
00627                         {
00628                                 if (m_bracketString[0] == 'P')
00629                                         EC_SigGen<ECP>(output, name2oid[m_bracketString]);
00630                                 else
00631                                         EC_SigGen<EC2N>(output, name2oid[m_bracketString]);
00632                         }
00633                         else if (m_test == "SigVer")
00634                         {
00635                                 if (m_bracketString[0] == 'P')
00636                                         EC_SigVer<ECP>(output, name2oid[m_bracketString]);
00637                                 else
00638                                         EC_SigVer<EC2N>(output, name2oid[m_bracketString]);
00639                         }
00640 
00641                         AttachedTransformation()->Put((byte *)output.data(), output.size());
00642                         output.resize(0);
00643                         return;
00644                 }
00645 
00646                 if (m_algorithm == "RSA")
00647                 {
00648                         std::string shaAlg = m_data["SHAAlg"].substr(3);
00649 
00650                         if (m_test == "Ver")
00651                         {
00652                                 Integer n((m_data["n"] + "h").c_str());
00653                                 Integer e((m_data["e"] + "h").c_str());
00654                                 RSA::PublicKey pub;
00655                                 pub.Initialize(n, e);
00656 
00657                                 member_ptr<PK_Verifier> pV(CreateRSA<PK_Verifier>(m_mode, shaAlg));
00658                                 pV->AccessMaterial().AssignFrom(pub);
00659 
00660                                 HexDecoder filter(new SignatureVerificationFilter(*pV));
00661                                 for (unsigned int i=m_data["S"].size(); i<pV->SignatureLength()*2; i++)
00662                                         filter.Put('0');
00663                                 StringSource(m_data["S"], true, new Redirector(filter, Redirector::DATA_ONLY));
00664                                 StringSource(m_data["Msg"], true, new Redirector(filter, Redirector::DATA_ONLY));
00665                                 filter.MessageEnd();
00666                                 byte b;
00667                                 filter.Get(b);
00668                                 OutputData(output, "Result ", b ? "P" : "F");
00669                         }
00670                         else
00671                         {
00672                                 assert(m_test == "Gen");
00673                                 int modLen = atol(m_bracketString.substr(6).c_str());
00674                                 std::string &encodedKey = m_data["PrivKey"];
00675                                 RSA::PrivateKey priv;
00676 
00677                                 if (!encodedKey.empty())
00678                                 {
00679                                         StringStore s(encodedKey);
00680                                         priv.BERDecode(s);
00681                                         if (priv.GetModulus().BitCount() != modLen)
00682                                                 encodedKey.clear();
00683                                 }
00684 
00685                                 if (encodedKey.empty())
00686                                 {
00687                                         priv.Initialize(m_rng, modLen);
00688                                         StringSink s(encodedKey);
00689                                         priv.DEREncode(s);
00690                                         OutputData(output, "n ", priv.GetModulus());
00691                                         OutputData(output, "e ", priv.GetPublicExponent(), modLen/8);
00692                                 }
00693 
00694                                 member_ptr<PK_Signer> pS(CreateRSA<PK_Signer>(m_mode, shaAlg));
00695                                 pS->AccessMaterial().AssignFrom(priv);
00696 
00697                                 SecByteBlock sig(pS->SignatureLength());
00698                                 StringSource(m_data["Msg"], true, new HexDecoder(new SignerFilter(m_rng, *pS, new ArraySink(sig, sig.size()))));
00699                                 OutputData(output, "SHAAlg ", m_data["SHAAlg"]);
00700                                 OutputData(output, "Msg ", m_data["Msg"]);
00701                                 OutputData(output, "S ", sig);
00702                         }
00703 
00704                         AttachedTransformation()->Put((byte *)output.data(), output.size());
00705                         output.resize(0);
00706                         return;
00707                 }
00708 
00709                 if (m_algorithm == "SHA2")
00710                 {
00711                         member_ptr<HashFunction> pHF;
00712 
00713                         if (m_mode == "224")
00714                                 pHF.reset(new SHA224);
00715                         else if (m_mode == "256")
00716                                 pHF.reset(new SHA256);
00717                         else if (m_mode == "384")
00718                                 pHF.reset(new SHA384);
00719                         else if (m_mode == "512")
00720                                 pHF.reset(new SHA512);
00721 
00722                         if (m_test == "MONTE")
00723                         {
00724                                 SecByteBlock seed = m_data2[INPUT];
00725                                 SecByteBlock MD[1003];
00726                                 int i,j;
00727 
00728                                 for (j=0; j<100; j++)
00729                                 {
00730                                         MD[0] = MD[1] = MD[2] = seed;
00731                                         for (i=3; i<1003; i++)
00732                                         {
00733                                                 SecByteBlock Mi = MD[i-3] + MD[i-2] + MD[i-1];
00734                                                 MD[i].resize(pHF->DigestSize());
00735                                                 pHF->CalculateDigest(MD[i], Mi, Mi.size());
00736                                         }
00737                                         seed = MD[1002];
00738                                         OutputData(output, "COUNT ", j);
00739                                         OutputData(output, "MD ", seed);
00740                                         AttachedTransformation()->Put((byte *)output.data(), output.size());
00741                                         output.resize(0);
00742                                 }
00743                         }
00744                         else
00745                         {
00746                                 SecByteBlock tag(pHF->DigestSize());
00747                                 SecByteBlock &msg(m_data2[INPUT]);
00748                                 int len = atol(m_data["Len"].c_str());
00749                                 StringSource(msg.begin(), len/8, true, new HashFilter(*pHF, new ArraySink(tag, tag.size())));
00750                                 OutputData(output, "MD ", tag);
00751                                 AttachedTransformation()->Put((byte *)output.data(), output.size());
00752                                 output.resize(0);
00753                         }
00754                         return;
00755                 }
00756 
00757                 SecByteBlock &key = m_data2[KEY_T];
00758 
00759                 if (m_algorithm == "TDES")
00760                 {
00761                         if (!m_data["KEY1"].empty())
00762                         {
00763                                 const std::string keys[3] = {m_data["KEY1"], m_data["KEY2"], m_data["KEY3"]};
00764                                 key.resize(24);
00765                                 HexDecoder hexDec(new ArraySink(key, key.size()));
00766                                 for (int i=0; i<3; i++)
00767                                         hexDec.Put((byte *)keys[i].data(), keys[i].size());
00768 
00769                                 if (keys[0] == keys[2])
00770                                 {
00771                                         if (keys[0] == keys[1])
00772                                                 key.resize(8);
00773                                         else
00774                                                 key.resize(16);
00775                                 }
00776                                 else
00777                                         key.resize(24);
00778                         }
00779                 }
00780 
00781                 if (m_algorithm == "RNG")
00782                 {
00783                         key.resize(16);
00784                         HexDecoder hexDec(new ArraySink(key, key.size()));
00785                         StringSource(m_data["Key1"], true, new Redirector(hexDec));
00786                         StringSource(m_data["Key2"], true, new Redirector(hexDec));
00787 
00788                         SecByteBlock seed(m_data2[INPUT]), dt(m_data2[IV]), r(8);
00789                         X917RNG rng(new DES_EDE2::Encryption(key), seed, dt);
00790 
00791                         if (m_test == "MCT")
00792                         {
00793                                 for (int i=0; i<10000; i++)
00794                                         rng.GenerateBlock(r, r.size());
00795                         }
00796                         else
00797                         {
00798                                 rng.GenerateBlock(r, r.size());
00799                         }
00800 
00801                         OutputData(output, "R ", r);
00802                         AttachedTransformation()->Put((byte *)output.data(), output.size());
00803                         output.resize(0);
00804                         return;
00805                 }
00806 
00807                 if (m_algorithm == "HMAC")
00808                 {
00809                         member_ptr<MessageAuthenticationCode> pMAC;
00810 
00811                         if (m_bracketString == "L=20")
00812                                 pMAC.reset(new HMAC<SHA1>);
00813                         else if (m_bracketString == "L=28")
00814                                 pMAC.reset(new HMAC<SHA224>);
00815                         else if (m_bracketString == "L=32")
00816                                 pMAC.reset(new HMAC<SHA256>);
00817                         else if (m_bracketString == "L=48")
00818                                 pMAC.reset(new HMAC<SHA384>);
00819                         else if (m_bracketString == "L=64")
00820                                 pMAC.reset(new HMAC<SHA512>);
00821                         else
00822                                 throw Exception(Exception::OTHER_ERROR, "TestDataParser: unexpected HMAC bracket string: " + m_bracketString);
00823 
00824                         pMAC->SetKey(key, key.size());
00825                         int Tlen = atol(m_data["Tlen"].c_str());
00826                         SecByteBlock tag(Tlen);
00827                         StringSource(m_data["Msg"], true, new HexDecoder(new HashFilter(*pMAC, new ArraySink(tag, Tlen), false, Tlen)));
00828                         OutputData(output, "Mac ", tag);
00829                         AttachedTransformation()->Put((byte *)output.data(), output.size());
00830                         output.resize(0);
00831                         return;
00832                 }
00833 
00834                 member_ptr<BlockCipher> pBT;
00835                 if (m_algorithm == "DES")
00836                         pBT.reset(NewBT((DES*)0));
00837                 else if (m_algorithm == "TDES")
00838                 {
00839                         if (key.size() == 8)
00840                                 pBT.reset(NewBT((DES*)0));
00841                         else if (key.size() == 16)
00842                                 pBT.reset(NewBT((DES_EDE2*)0));
00843                         else
00844                                 pBT.reset(NewBT((DES_EDE3*)0));
00845                 }
00846                 else if (m_algorithm == "SKIPJACK")
00847                         pBT.reset(NewBT((SKIPJACK*)0));
00848                 else if (m_algorithm == "AES")
00849                         pBT.reset(NewBT((AES*)0));
00850                 else
00851                         throw Exception(Exception::OTHER_ERROR, "TestDataParser: unexpected algorithm: " + m_algorithm);
00852 
00853                 if (!pBT->IsValidKeyLength(key.size()))
00854                         key.CleanNew(pBT->DefaultKeyLength());  // for Scbcvrct
00855                 pBT->SetKey(key.data(), key.size());
00856 
00857                 SecByteBlock &iv = m_data2[IV];
00858                 if (iv.empty())
00859                         iv.CleanNew(pBT->BlockSize());
00860 
00861                 member_ptr<SymmetricCipher> pCipher;
00862                 unsigned int K = m_feedbackSize;
00863 
00864                 if (m_mode == "ECB")
00865                         pCipher.reset(NewMode((ECB_Mode_ExternalCipher*)0, *pBT, iv));
00866                 else if (m_mode == "CBC")
00867                         pCipher.reset(NewMode((CBC_Mode_ExternalCipher*)0, *pBT, iv));
00868                 else if (m_mode == "CFB")
00869                         pCipher.reset(NewMode((CFB_Mode_ExternalCipher*)0, *pBT, iv));
00870                 else if (m_mode == "OFB")
00871                         pCipher.reset(NewMode((OFB_Mode_ExternalCipher*)0, *pBT, iv));
00872                 else
00873                         throw Exception(Exception::OTHER_ERROR, "TestDataParser: unexpected mode: " + m_mode);
00874 
00875                 bool encrypt = m_encrypt;
00876 
00877                 if (m_test == "MONTE")
00878                 {
00879                         SecByteBlock KEY[401];
00880                         KEY[0] = key;
00881                         int keySize = key.size();
00882                         int blockSize = pBT->BlockSize();
00883 
00884                         SecByteBlock IB[10001], OB[10001], PT[10001], CT[10001], RESULT[10001], TXT[10001], CV[10001];
00885                         PT[0] = GetData("PLAINTEXT");
00886                         CT[0] = GetData("CIPHERTEXT");
00887                         CV[0] = IB[0] = iv;
00888                         TXT[0] = GetData("TEXT");
00889 
00890                         int outerCount = (m_algorithm == "AES") ? 100 : 400;
00891                         int innerCount = (m_algorithm == "AES") ? 1000 : 10000;
00892 
00893                         for (int i=0; i<outerCount; i++)
00894                         {
00895                                 pBT->SetKey(KEY[i], keySize);
00896 
00897                                 for (int j=0; j<innerCount; j++)
00898                                 {
00899                                         if (m_mode == "ECB")
00900                                         {
00901                                                 if (encrypt)
00902                                                 {
00903                                                         IB[j] = PT[j];
00904                                                         CT[j].resize(blockSize);
00905                                                         pBT->ProcessBlock(IB[j], CT[j]);
00906                                                         PT[j+1] = CT[j];
00907                                                 }
00908                                                 else
00909                                                 {
00910                                                         IB[j] = CT[j];
00911                                                         PT[j].resize(blockSize);
00912                                                         pBT->ProcessBlock(IB[j], PT[j]);
00913                                                         CT[j+1] = PT[j];
00914                                                 }
00915                                         }
00916                                         else if (m_mode == "OFB")
00917                                         {
00918                                                 OB[j].resize(blockSize);
00919                                                 pBT->ProcessBlock(IB[j], OB[j]);
00920                                                 Xor(RESULT[j], OB[j], TXT[j]);
00921                                                 TXT[j+1] = IB[j];
00922                                                 IB[j+1] = OB[j];
00923                                         }
00924                                         else if (m_mode == "CBC")
00925                                         {
00926                                                 if (encrypt)
00927                                                 {
00928                                                         Xor(IB[j], PT[j], CV[j]);
00929                                                         CT[j].resize(blockSize);
00930                                                         pBT->ProcessBlock(IB[j], CT[j]);
00931                                                         PT[j+1] = CV[j];
00932                                                         CV[j+1] = CT[j];
00933                                                 }
00934                                                 else
00935                                                 {
00936                                                         IB[j] = CT[j];
00937                                                         OB[j].resize(blockSize);
00938                                                         pBT->ProcessBlock(IB[j], OB[j]);
00939                                                         Xor(PT[j], OB[j], CV[j]);
00940                                                         CV[j+1] = CT[j];
00941                                                         CT[j+1] = PT[j];
00942                                                 }
00943                                         }
00944                                         else if (m_mode == "CFB")
00945                                         {
00946                                                 if (encrypt)
00947                                                 {
00948                                                         OB[j].resize(blockSize);
00949                                                         pBT->ProcessBlock(IB[j], OB[j]);
00950                                                         AssignLeftMostBits(CT[j], OB[j], K);
00951                                                         Xor(CT[j], CT[j], PT[j]);
00952                                                         AssignLeftMostBits(PT[j+1], IB[j], K);
00953                                                         IB[j+1].resize(blockSize);
00954                                                         memcpy(IB[j+1], IB[j]+K/8, blockSize-K/8);
00955                                                         memcpy(IB[j+1]+blockSize-K/8, CT[j], K/8);
00956                                                 }
00957                                                 else
00958                                                 {
00959                                                         OB[j].resize(blockSize);
00960                                                         pBT->ProcessBlock(IB[j], OB[j]);
00961                                                         AssignLeftMostBits(PT[j], OB[j], K);
00962                                                         Xor(PT[j], PT[j], CT[j]);
00963                                                         IB[j+1].resize(blockSize);
00964                                                         memcpy(IB[j+1], IB[j]+K/8, blockSize-K/8);
00965                                                         memcpy(IB[j+1]+blockSize-K/8, CT[j], K/8);
00966                                                         AssignLeftMostBits(CT[j+1], OB[j], K);
00967                                                 }
00968                                         }
00969                                         else
00970                                                 throw Exception(Exception::OTHER_ERROR, "TestDataParser: unexpected mode: " + m_mode);
00971                                 }
00972 
00973                                 OutputData(output, "COUNT ", i);
00974                                 OutputData(output, KEY_T, KEY[i]);
00975                                 if (m_mode == "CBC")
00976                                         OutputData(output, IV, CV[0]);
00977                                 if (m_mode == "OFB" || m_mode == "CFB")
00978                                         OutputData(output, IV, IB[0]);
00979                                 if (m_mode == "ECB" || m_mode == "CBC" || m_mode == "CFB")
00980                                 {
00981                                         if (encrypt)
00982                                         {
00983                                                 OutputData(output, INPUT, PT[0]);
00984                                                 OutputData(output, OUTPUT, CT[innerCount-1]);
00985                                                 KEY[i+1] = UpdateKey(KEY[i], CT);
00986                                         }
00987                                         else
00988                                         {
00989                                                 OutputData(output, INPUT, CT[0]);
00990                                                 OutputData(output, OUTPUT, PT[innerCount-1]);
00991                                                 KEY[i+1] = UpdateKey(KEY[i], PT);
00992                                         }
00993                                         PT[0] = PT[innerCount];
00994                                         IB[0] = IB[innerCount];
00995                                         CV[0] = CV[innerCount];
00996                                         CT[0] = CT[innerCount];
00997                                 }
00998                                 else if (m_mode == "OFB")
00999                                 {
01000                                         OutputData(output, INPUT, TXT[0]);
01001                                         OutputData(output, OUTPUT, RESULT[innerCount-1]);
01002                                         KEY[i+1] = UpdateKey(KEY[i], RESULT);
01003                                         Xor(TXT[0], TXT[0], IB[innerCount-1]);
01004                                         IB[0] = OB[innerCount-1];
01005                                 }
01006                                 output += "\n";
01007                                 AttachedTransformation()->Put((byte *)output.data(), output.size());
01008                                 output.resize(0);
01009                         }
01010                 }
01011                 else if (m_test == "MCT")
01012                 {
01013                         SecByteBlock KEY[101];
01014                         KEY[0] = key;
01015                         int keySize = key.size();
01016                         int blockSize = pBT->BlockSize();
01017 
01018                         SecByteBlock ivs[101], inputs[1001], outputs[1001];
01019                         ivs[0] = iv;
01020                         inputs[0] = m_data2[INPUT];
01021 
01022                         for (int i=0; i<100; i++)
01023                         {
01024                                 pCipher->SetKey(KEY[i], keySize, MakeParameters(Name::IV(), (const byte *)ivs[i])(Name::FeedbackSize(), (int)K/8, false));
01025 
01026                                 for (int j=0; j<1000; j++)
01027                                 {
01028                                         outputs[j] = inputs[j];
01029                                         pCipher->ProcessString(outputs[j], outputs[j].size());
01030                                         if (K==8 && m_mode == "CFB")
01031                                         {
01032                                                 if (j<16)
01033                                                         inputs[j+1].Assign(ivs[i]+j, 1);
01034                                                 else
01035                                                         inputs[j+1] = outputs[j-16];
01036                                         }
01037                                         else if (m_mode == "ECB")
01038                                                 inputs[j+1] = outputs[j];
01039                                         else if (j == 0)
01040                                                 inputs[j+1] = ivs[i];
01041                                         else
01042                                                 inputs[j+1] = outputs[j-1];
01043                                 }
01044 
01045                                 if (m_algorithm == "AES")
01046                                         OutputData(output, COUNT, m_count++);
01047                                 OutputData(output, KEY_T, KEY[i]);
01048                                 if (m_mode != "ECB")
01049                                         OutputData(output, IV, ivs[i]);
01050                                 OutputData(output, INPUT, inputs[0]);
01051                                 OutputData(output, OUTPUT, outputs[999]);
01052                                 output += "\n";
01053                                 AttachedTransformation()->Put((byte *)output.data(), output.size());
01054                                 output.resize(0);
01055 
01056                                 KEY[i+1] = UpdateKey(KEY[i], outputs);
01057                                 ivs[i+1].CleanNew(pCipher->IVSize());
01058                                 ivs[i+1] = UpdateKey(ivs[i+1], outputs);
01059                                 if (K==8 && m_mode == "CFB")
01060                                         inputs[0] = outputs[999-16];
01061                                 else if (m_mode == "ECB")
01062                                         inputs[0] = outputs[999];
01063                                 else
01064                                         inputs[0] = outputs[998];
01065                         }
01066                 }
01067                 else
01068                 {
01069                         assert(m_test == "KAT");
01070 
01071                         SecByteBlock &input = m_data2[INPUT];
01072                         SecByteBlock result(input.size());
01073                         member_ptr<Filter> pFilter(new StreamTransformationFilter(*pCipher, new ArraySink(result, result.size()), StreamTransformationFilter::NO_PADDING));
01074                         StringSource(input.data(), input.size(), true, pFilter.release());
01075 
01076                         OutputGivenData(output, COUNT, true);
01077                         OutputData(output, KEY_T, key);
01078                         OutputGivenData(output, IV, true);
01079                         OutputGivenData(output, INPUT);
01080                         OutputData(output, OUTPUT, result);
01081                         output += "\n";
01082                         AttachedTransformation()->Put((byte *)output.data(), output.size());
01083                 }
01084         }
01085 
01086         std::vector<std::string> Tokenize(const std::string &line)
01087         {
01088                 std::vector<std::string> result;
01089                 std::string s;
01090                 for (unsigned int i=0; i<line.size(); i++)
01091                 {
01092                         if (isalnum(line[i]) || line[i] == '^')
01093                                 s += line[i];
01094                         else if (!s.empty())
01095                         {
01096                                 result.push_back(s);
01097                                 s = "";
01098                         }
01099                         if (line[i] == '=')
01100                                 result.push_back("=");
01101                 }
01102                 result.push_back(s);
01103                 return result;
01104         }
01105 
01106         bool IsolatedMessageEnd(bool blocking)
01107         {
01108                 if (!blocking)
01109                         throw BlockingInputOnly("TestDataParser");
01110 
01111                 m_line.resize(0);
01112                 m_inQueue.TransferTo(StringSink(m_line).Ref());
01113 
01114                 if (m_line[0] == '#')
01115                         return false;
01116 
01117                 bool copyLine = false;
01118 
01119                 if (m_line[0] == '[')
01120                 {
01121                         m_bracketString = m_line.substr(1, m_line.size()-2);
01122                         if (m_bracketString == "ENCRYPT")
01123                                 SetEncrypt(true);
01124                         if (m_bracketString == "DECRYPT")
01125                                 SetEncrypt(false);
01126                         copyLine = true;
01127                 }
01128 
01129                 if (m_line.substr(0, 2) == "H>")
01130                 {
01131                         assert(m_test == "sha");
01132                         m_bracketString = m_line.substr(2, m_line.size()-4);
01133                         m_line = m_line.substr(0, 13) + "Hashes<H";
01134                         copyLine = true;
01135                 }
01136 
01137                 if (m_line == "D>")
01138                         copyLine = true;
01139 
01140                 if (m_line == "<D")
01141                 {
01142                         m_line += "\n";
01143                         copyLine = true;
01144                 }
01145 
01146                 if (copyLine)
01147                 {
01148                         m_line += '\n';
01149                         AttachedTransformation()->Put((byte *)m_line.data(), m_line.size(), blocking);
01150                         return false;
01151                 }
01152 
01153                 std::vector<std::string> tokens = Tokenize(m_line);
01154 
01155                 if (m_algorithm == "DSS" && m_test == "sha")
01156                 {
01157                         for (unsigned int i = 0; i < tokens.size(); i++)
01158                         {
01159                                 if (tokens[i] == "^")
01160                                         DoTest();
01161                                 else if (tokens[i] != "")
01162                                         m_compactString.push_back(atol(tokens[i].c_str()));
01163                         }
01164                 }
01165                 else
01166                 {
01167                         if (!m_line.empty() && ((m_algorithm == "RSA" && m_test != "Gen") || m_algorithm == "RNG" || m_algorithm == "HMAC" || m_algorithm == "SHA2" || (m_algorithm == "ECDSA" && m_test != "KeyPair") || (m_algorithm == "DSS" && m_test != "pqg")))
01168                         {
01169                                 // copy input to output
01170                                 std::string output = m_line + '\n';
01171                                 AttachedTransformation()->Put((byte *)output.data(), output.size());
01172                         }
01173 
01174                         for (unsigned int i = 0; i < tokens.size(); i++)
01175                         {
01176                                 if (m_firstLine && m_algorithm != "DSS")
01177                                 {
01178                                         if (tokens[i] == "Encrypt" || tokens[i] == "OFB")
01179                                                 SetEncrypt(true);
01180                                         else if (tokens[i] == "Decrypt")
01181                                                 SetEncrypt(false);
01182                                         else if (tokens[i] == "Modes")
01183                                                 m_test = "MONTE";
01184                                 }
01185                                 else
01186                                 {
01187                                         if (tokens[i] != "=")
01188                                                 continue;
01189 
01190                                         if (i == 0)
01191                                                 throw Exception(Exception::OTHER_ERROR, "TestDataParser: unexpected data: " + m_line);
01192 
01193                                         const std::string &key = tokens[i-1];
01194                                         std::string &data = m_data[key];
01195                                         data = tokens[i+1];
01196                                         DataType t = m_nameToType[key];
01197                                         m_typeToName[t] = key;
01198                                         m_data2[t] = DecodeHex(data);
01199 
01200                                         if (key == m_trigger || (t == OUTPUT && !m_data2[INPUT].empty()))
01201                                                 DoTest();
01202                                 }
01203                         }
01204                 }
01205 
01206                 m_firstLine = false;
01207 
01208                 return false;
01209         }
01210 
01211         inline const SecByteBlock & GetData(const std::string &key)
01212         {
01213                 return m_data2[m_nameToType[key]];
01214         }
01215 
01216         static SecByteBlock DecodeHex(const std::string &data)
01217         {
01218                 SecByteBlock data2(data.size() / 2);
01219                 StringSource(data, true, new HexDecoder(new ArraySink(data2, data2.size())));
01220                 return data2;
01221         }
01222 
01223         std::string m_algorithm, m_test, m_mode, m_line, m_bracketString, m_trigger;
01224         unsigned int m_feedbackSize, m_blankLineTransition;
01225         bool m_encrypt, m_firstLine;
01226 
01227         typedef std::map<std::string, DataType> NameToTypeMap;
01228         NameToTypeMap m_nameToType;
01229         typedef std::map<DataType, std::string> TypeToNameMap;
01230         TypeToNameMap m_typeToName;
01231 
01232         typedef std::map<std::string, std::string> Map;
01233         Map m_data;             // raw data
01234         typedef std::map<DataType, SecByteBlock> Map2;
01235         Map2 m_data2;
01236         int m_count;
01237 
01238         AutoSeededX917RNG<DES_EDE3> m_rng;
01239         std::vector<unsigned int> m_compactString;
01240 };
01241 
01242 int FIPS_140_AlgorithmTest(int argc, char **argv)
01243 {
01244         argc--;
01245         argv++;
01246 
01247         std::string algorithm = argv[1];
01248         std::string pathname = argv[2];
01249         unsigned int i = pathname.find_last_of("\\/");
01250         std::string filename = pathname.substr(i == std::string::npos ? 0 : i+1);
01251         try
01252         {
01253                 std::string mode;
01254                 if (algorithm == "SHA2")
01255                         mode = filename.substr(3, 3);
01256                 else if (algorithm == "RSA")
01257                         mode = filename.substr(6, 1);
01258                 else if (filename[0] == 'S' || filename[0] == 'T')
01259                         mode = filename.substr(1, 3);
01260                 else
01261                         mode = filename.substr(0, 3);
01262                 for (i = 0; i<mode.size(); i++)
01263                         mode[i] = toupper(mode[i]);
01264                 unsigned int feedbackSize = mode == "CFB" ? atoi(filename.substr(filename.find_first_of("0123456789")).c_str()) : 0;
01265                 std::string test;
01266                 if (algorithm == "DSS" || algorithm == "ECDSA")
01267                         test = filename.substr(0, filename.size() - 4);
01268                 else if (algorithm == "RSA")
01269                         test = filename.substr(3, 3);
01270                 else if (filename.find("Monte") != std::string::npos)
01271                         test = "MONTE";
01272                 else if (filename.find("MCT") != std::string::npos)
01273                         test = "MCT";
01274                 else
01275                         test = "KAT";
01276                 bool encrypt = (filename.find("vrct") == std::string::npos);
01277 
01278                 BufferedTransformation *pSink = NULL;
01279 
01280                 if (argc > 3)
01281                 {
01282                         std::string outDir = argv[3];
01283                         if (*outDir.rbegin() != '\\' && *outDir.rbegin() != '/')
01284                                 outDir += '/';
01285                         std::string outPathname = outDir + filename.substr(0, filename.size() - 3) + "rsp";
01286                         pSink = new FileSink(outPathname.c_str(), false);
01287                 }
01288                 else
01289                         pSink = new FileSink(cout);
01290 
01291                 FileSource(pathname.c_str(), true, new LineBreakParser(new TestDataParser(algorithm, test, mode, feedbackSize, encrypt, pSink)), false);
01292         }
01293         catch (...)
01294         {
01295                 cout << "file: " << filename << endl;
01296                 throw;
01297         }
01298         return 0;
01299 }
01300 
01301 extern int (*AdhocTest)(int argc, char *argv[]);
01302 static int s_i = (AdhocTest = &FIPS_140_AlgorithmTest, 0);
01303 #endif

Generated on Tue Aug 16 08:38:41 2005 for Crypto++ by  doxygen 1.3.9.1