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

Generated on Sat Dec 23 02:07:07 2006 for Crypto++ by  doxygen 1.5.1-p1