- Main Page
- Namespaces
- Classes
- Files

# 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(24);
    00750                         StringSource(m_data["Key1"] + m_data["Key2"] + m_data["Key3"], true, new HexDecoder(new ArraySink(key, key.size())));
    00751
    00752                         SecByteBlock seed(m_data2[INPUT]), dt(m_data2[IV]), r(8);
    00753                         X917RNG rng(new DES_EDE3::Encryption(key, key.size()), seed, dt);
    00754
    00755                         if (m_test == "MCT")
    00756                         {
    00757                                 for (int i=0; i<10000; i++)
    00758                                         rng.GenerateBlock(r, r.size());
    00759                         }
    00760                         else
    00761                         {
    00762                                 rng.GenerateBlock(r, r.size());
    00763                         }
    00764
    00765                         OutputData(output, "R ", r);
    00766                         AttachedTransformation()->Put((byte *)output.data(), output.size());
    00767                         output.resize(0);
    00768                         return;
    00769                 }
    00770
    00771                 if (m_algorithm == "HMAC")
    00772                 {
    00773                         member_ptr<MessageAuthenticationCode> pMAC;
    00774
    00775                         if (m_bracketString == "L=20")
    00776                                 pMAC.reset(new HMAC<SHA1>);
    00777                         else if (m_bracketString == "L=28")
    00778                                 pMAC.reset(new HMAC<SHA224>);
    00779                         else if (m_bracketString == "L=32")
    00780                                 pMAC.reset(new HMAC<SHA256>);
    00781                         else if (m_bracketString == "L=48")
    00782                                 pMAC.reset(new HMAC<SHA384>);
    00783                         else if (m_bracketString == "L=64")
    00784                                 pMAC.reset(new HMAC<SHA512>);
    00785                         else
    00786                                 throw Exception(Exception::OTHER_ERROR, "TestDataParser: unexpected HMAC bracket string: " + m_bracketString);
    00787
    00788                         pMAC->SetKey(key, key.size());
    00789                         int Tlen = atol(m_data["Tlen"].c_str());
    00790                         SecByteBlock tag(Tlen);
    00791                         StringSource(m_data["Msg"], true, new HexDecoder(new HashFilter(*pMAC, new ArraySink(tag, Tlen), false, Tlen)));
    00792                         OutputData(output, "Mac ", tag);
    00793                         AttachedTransformation()->Put((byte *)output.data(), output.size());
    00794                         output.resize(0);
    00795                         return;
    00796                 }
    00797
    00798                 member_ptr<BlockCipher> pBT;
    00799                 if (m_algorithm == "DES")
    00800                         pBT.reset(NewBT((DES*)0));
    00801                 else if (m_algorithm == "TDES")
    00802                 {
    00803                         if (key.size() == 8)
    00804                                 pBT.reset(NewBT((DES*)0));
    00805                         else if (key.size() == 16)
    00806                                 pBT.reset(NewBT((DES_EDE2*)0));
    00807                         else
    00808                                 pBT.reset(NewBT((DES_EDE3*)0));
    00809                 }
    00810                 else if (m_algorithm == "SKIPJACK")
    00811                         pBT.reset(NewBT((SKIPJACK*)0));
    00812                 else if (m_algorithm == "AES")
    00813                         pBT.reset(NewBT((AES*)0));
    00814                 else
    00815                         throw Exception(Exception::OTHER_ERROR, "TestDataParser: unexpected algorithm: " + m_algorithm);
    00816
    00817                 if (!pBT->IsValidKeyLength(key.size()))
    00818                         key.CleanNew(pBT->DefaultKeyLength());  // for Scbcvrct
    00819                 pBT->SetKey(key.data(), key.size());
    00820
    00821                 SecByteBlock &iv = m_data2[IV];
    00822                 if (iv.empty())
    00823                         iv.CleanNew(pBT->BlockSize());
    00824
    00825                 member_ptr<SymmetricCipher> pCipher;
    00826                 unsigned int K = m_feedbackSize;
    00827
    00828                 if (m_mode == "ECB")
    00829                         pCipher.reset(NewMode((ECB_Mode_ExternalCipher*)0, *pBT, iv));
    00830                 else if (m_mode == "CBC")
    00831                         pCipher.reset(NewMode((CBC_Mode_ExternalCipher*)0, *pBT, iv));
    00832                 else if (m_mode == "CFB")
    00833                         pCipher.reset(NewMode((CFB_Mode_ExternalCipher*)0, *pBT, iv));
    00834                 else if (m_mode == "OFB")
    00835                         pCipher.reset(NewMode((OFB_Mode_ExternalCipher*)0, *pBT, iv));
    00836                 else
    00837                         throw Exception(Exception::OTHER_ERROR, "TestDataParser: unexpected mode: " + m_mode);
    00838
    00839                 bool encrypt = m_encrypt;
    00840
    00841                 if (m_test == "MONTE")
    00842                 {
    00843                         SecByteBlock KEY[401];
    00844                         KEY[0] = key;
    00845                         int keySize = key.size();
    00846                         int blockSize = pBT->BlockSize();
    00847
    00848                         std::vector<SecByteBlock> IB(10001), OB(10001), PT(10001), CT(10001), RESULT(10001), TXT(10001), CV(10001);
    00849                         PT[0] = GetData("PLAINTEXT");
    00850                         CT[0] = GetData("CIPHERTEXT");
    00851                         CV[0] = IB[0] = iv;
    00852                         TXT[0] = GetData("TEXT");
    00853
    00854                         int outerCount = (m_algorithm == "AES") ? 100 : 400;
    00855                         int innerCount = (m_algorithm == "AES") ? 1000 : 10000;
    00856
    00857                         for (int i=0; i<outerCount; i++)
    00858                         {
    00859                                 pBT->SetKey(KEY[i], keySize);
    00860
    00861                                 for (int j=0; j<innerCount; j++)
    00862                                 {
    00863                                         if (m_mode == "ECB")
    00864                                         {
    00865                                                 if (encrypt)
    00866                                                 {
    00867                                                         IB[j] = PT[j];
    00868                                                         CT[j].resize(blockSize);
    00869                                                         pBT->ProcessBlock(IB[j], CT[j]);
    00870                                                         PT[j+1] = CT[j];
    00871                                                 }
    00872                                                 else
    00873                                                 {
    00874                                                         IB[j] = CT[j];
    00875                                                         PT[j].resize(blockSize);
    00876                                                         pBT->ProcessBlock(IB[j], PT[j]);
    00877                                                         CT[j+1] = PT[j];
    00878                                                 }
    00879                                         }
    00880                                         else if (m_mode == "OFB")
    00881                                         {
    00882                                                 OB[j].resize(blockSize);
    00883                                                 pBT->ProcessBlock(IB[j], OB[j]);
    00884                                                 Xor(RESULT[j], OB[j], TXT[j]);
    00885                                                 TXT[j+1] = IB[j];
    00886                                                 IB[j+1] = OB[j];
    00887                                         }
    00888                                         else if (m_mode == "CBC")
    00889                                         {
    00890                                                 if (encrypt)
    00891                                                 {
    00892                                                         Xor(IB[j], PT[j], CV[j]);
    00893                                                         CT[j].resize(blockSize);
    00894                                                         pBT->ProcessBlock(IB[j], CT[j]);
    00895                                                         PT[j+1] = CV[j];
    00896                                                         CV[j+1] = CT[j];
    00897                                                 }
    00898                                                 else
    00899                                                 {
    00900                                                         IB[j] = CT[j];
    00901                                                         OB[j].resize(blockSize);
    00902                                                         pBT->ProcessBlock(IB[j], OB[j]);
    00903                                                         Xor(PT[j], OB[j], CV[j]);
    00904                                                         CV[j+1] = CT[j];
    00905                                                         CT[j+1] = PT[j];
    00906                                                 }
    00907                                         }
    00908                                         else if (m_mode == "CFB")
    00909                                         {
    00910                                                 if (encrypt)
    00911                                                 {
    00912                                                         OB[j].resize(blockSize);
    00913                                                         pBT->ProcessBlock(IB[j], OB[j]);
    00914                                                         AssignLeftMostBits(CT[j], OB[j], K);
    00915                                                         Xor(CT[j], CT[j], PT[j]);
    00916                                                         AssignLeftMostBits(PT[j+1], IB[j], K);
    00917                                                         IB[j+1].resize(blockSize);
    00918                                                         memcpy(IB[j+1], IB[j]+K/8, blockSize-K/8);
    00919                                                         memcpy(IB[j+1]+blockSize-K/8, CT[j], K/8);
    00920                                                 }
    00921                                                 else
    00922                                                 {
    00923                                                         OB[j].resize(blockSize);
    00924                                                         pBT->ProcessBlock(IB[j], OB[j]);
    00925                                                         AssignLeftMostBits(PT[j], OB[j], K);
    00926                                                         Xor(PT[j], PT[j], CT[j]);
    00927                                                         IB[j+1].resize(blockSize);
    00928                                                         memcpy(IB[j+1], IB[j]+K/8, blockSize-K/8);
    00929                                                         memcpy(IB[j+1]+blockSize-K/8, CT[j], K/8);
    00930                                                         AssignLeftMostBits(CT[j+1], OB[j], K);
    00931                                                 }
    00932                                         }
    00933                                         else
    00934                                                 throw Exception(Exception::OTHER_ERROR, "TestDataParser: unexpected mode: " + m_mode);
    00935                                 }
    00936
    00937                                 OutputData(output, COUNT, IntToString(i));
    00938                                 OutputData(output, KEY_T, KEY[i]);
    00939                                 if (m_mode == "CBC")
    00940                                         OutputData(output, IV, CV[0]);
    00941                                 if (m_mode == "OFB" || m_mode == "CFB")
    00942                                         OutputData(output, IV, IB[0]);
    00943                                 if (m_mode == "ECB" || m_mode == "CBC" || m_mode == "CFB")
    00944                                 {
    00945                                         if (encrypt)
    00946                                         {
    00947                                                 OutputData(output, INPUT, PT[0]);
    00948                                                 OutputData(output, OUTPUT, CT[innerCount-1]);
    00949                                                 KEY[i+1] = UpdateKey(KEY[i], &CT[0]);
    00950                                         }
    00951                                         else
    00952                                         {
    00953                                                 OutputData(output, INPUT, CT[0]);
    00954                                                 OutputData(output, OUTPUT, PT[innerCount-1]);
    00955                                                 KEY[i+1] = UpdateKey(KEY[i], &PT[0]);
    00956                                         }
    00957                                         PT[0] = PT[innerCount];
    00958                                         IB[0] = IB[innerCount];
    00959                                         CV[0] = CV[innerCount];
    00960                                         CT[0] = CT[innerCount];
    00961                                 }
    00962                                 else if (m_mode == "OFB")
    00963                                 {
    00964                                         OutputData(output, INPUT, TXT[0]);
    00965                                         OutputData(output, OUTPUT, RESULT[innerCount-1]);
    00966                                         KEY[i+1] = UpdateKey(KEY[i], &RESULT[0]);
    00967                                         Xor(TXT[0], TXT[0], IB[innerCount-1]);
    00968                                         IB[0] = OB[innerCount-1];
    00969                                 }
    00970                                 output += "\n";
    00971                                 AttachedTransformation()->Put((byte *)output.data(), output.size());
    00972                                 output.resize(0);
    00973                         }
    00974                 }
    00975                 else if (m_test == "MCT")
    00976                 {
    00977                         SecByteBlock KEY[101];
    00978                         KEY[0] = key;
    00979                         int keySize = key.size();
    00980                         int blockSize = pBT->BlockSize();
    00981
    00982                         SecByteBlock ivs[101], inputs[1001], outputs[1001];
    00983                         ivs[0] = iv;
    00984                         inputs[0] = m_data2[INPUT];
    00985
    00986                         for (int i=0; i<100; i++)
    00987                         {
    00988                                 pCipher->SetKey(KEY[i], keySize, MakeParameters(Name::IV(), (const byte *)ivs[i])(Name::FeedbackSize(), (int)K/8, false));
    00989
    00990                                 for (int j=0; j<1000; j++)
    00991                                 {
    00992                                         outputs[j] = inputs[j];
    00993                                         pCipher->ProcessString(outputs[j], outputs[j].size());
    00994                                         if (K==8 && m_mode == "CFB")
    00995                                         {
    00996                                                 if (j<16)
    00997                                                         inputs[j+1].Assign(ivs[i]+j, 1);
    00998                                                 else
    00999                                                         inputs[j+1] = outputs[j-16];
    01000                                         }
    01001                                         else if (m_mode == "ECB")
    01002                                                 inputs[j+1] = outputs[j];
    01003                                         else if (j == 0)
    01004                                                 inputs[j+1] = ivs[i];
    01005                                         else
    01006                                                 inputs[j+1] = outputs[j-1];
    01007                                 }
    01008
    01009                                 if (m_algorithm == "AES")
    01010                                         OutputData(output, COUNT, m_count++);
    01011                                 OutputData(output, KEY_T, KEY[i]);
    01012                                 if (m_mode != "ECB")
    01013                                         OutputData(output, IV, ivs[i]);
    01014                                 OutputData(output, INPUT, inputs[0]);
    01015                                 OutputData(output, OUTPUT, outputs[999]);
    01016                                 output += "\n";
    01017                                 AttachedTransformation()->Put((byte *)output.data(), output.size());
    01018                                 output.resize(0);
    01019
    01020                                 KEY[i+1] = UpdateKey(KEY[i], outputs);
    01021                                 ivs[i+1].CleanNew(pCipher->IVSize());
    01022                                 ivs[i+1] = UpdateKey(ivs[i+1], outputs);
    01023                                 if (K==8 && m_mode == "CFB")
    01024                                         inputs[0] = outputs[999-16];
    01025                                 else if (m_mode == "ECB")
    01026                                         inputs[0] = outputs[999];
    01027                                 else
    01028                                         inputs[0] = outputs[998];
    01029                         }
    01030                 }
    01031                 else
    01032                 {
    01033                         assert(m_test == "KAT");
    01034
    01035                         SecByteBlock &input = m_data2[INPUT];
    01036                         SecByteBlock result(input.size());
    01037                         member_ptr<Filter> pFilter(new StreamTransformationFilter(*pCipher, new ArraySink(result, result.size()), StreamTransformationFilter::NO_PADDING));
    01038                         StringSource(input.data(), input.size(), true, pFilter.release());
    01039
    01040                         OutputGivenData(output, COUNT, true);
    01041                         OutputData(output, KEY_T, key);
    01042                         OutputGivenData(output, IV, true);
    01043                         OutputGivenData(output, INPUT);
    01044                         OutputData(output, OUTPUT, result);
    01045                         output += "\n";
    01046                         AttachedTransformation()->Put((byte *)output.data(), output.size());
    01047                 }
    01048         }
    01049
    01050         std::vector<std::string> Tokenize(const std::string &line)
    01051         {
    01052                 std::vector<std::string> result;
    01053                 std::string s;
    01054                 for (unsigned int i=0; i<line.size(); i++)
    01055                 {
    01056                         if (isalnum(line[i]) || line[i] == '^')
    01057                                 s += line[i];
    01058                         else if (!s.empty())
    01059                         {
    01060                                 result.push_back(s);
    01061                                 s = "";
    01062                         }
    01063                         if (line[i] == '=')
    01064                                 result.push_back("=");
    01065                 }
    01066                 if (!s.empty())
    01067                         result.push_back(s);
    01068                 return result;
    01069         }
    01070
    01071         bool IsolatedMessageEnd(bool blocking)
    01072         {
    01073                 if (!blocking)
    01074                         throw BlockingInputOnly("TestDataParser");
    01075
    01076                 m_line.resize(0);
    01077                 m_inQueue.TransferTo(StringSink(m_line).Ref());
    01078
    01079                 if (m_line[0] == '#')
    01080                         return false;
    01081
    01082                 bool copyLine = false;
    01083
    01084                 if (m_line[0] == '[')
    01085                 {
    01086                         m_bracketString = m_line.substr(1, m_line.size()-2);
    01087                         if (m_bracketString == "ENCRYPT")
    01088                                 SetEncrypt(true);
    01089                         if (m_bracketString == "DECRYPT")
    01090                                 SetEncrypt(false);
    01091                         copyLine = true;
    01092                 }
    01093
    01094                 if (m_line.substr(0, 2) == "H>")
    01095                 {
    01096                         assert(m_test == "sha");
    01097                         m_bracketString = m_line.substr(2, m_line.size()-4);
    01098                         m_line = m_line.substr(0, 13) + "Hashes<H";
    01099                         copyLine = true;
    01100                 }
    01101
    01102                 if (m_line == "D>")
    01103                         copyLine = true;
    01104
    01105                 if (m_line == "<D")
    01106                 {
    01107                         m_line += "\n";
    01108                         copyLine = true;
    01109                 }
    01110
    01111                 if (copyLine)
    01112                 {
    01113                         m_line += '\n';
    01114                         AttachedTransformation()->Put((byte *)m_line.data(), m_line.size(), blocking);
    01115                         return false;
    01116                 }
    01117
    01118                 std::vector<std::string> tokens = Tokenize(m_line);
    01119
    01120                 if (m_algorithm == "DSA" && m_test == "sha")
    01121                 {
    01122                         for (unsigned int i = 0; i < tokens.size(); i++)
    01123                         {
    01124                                 if (tokens[i] == "^")
    01125                                         DoTest();
    01126                                 else if (tokens[i] != "")
    01127                                         m_compactString.push_back(atol(tokens[i].c_str()));
    01128                         }
    01129                 }
    01130                 else
    01131                 {
    01132                         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"))))
    01133                         {
    01134                                 // copy input to output
    01135                                 std::string output = m_line + '\n';
    01136                                 AttachedTransformation()->Put((byte *)output.data(), output.size());
    01137                         }
    01138
    01139                         for (unsigned int i = 0; i < tokens.size(); i++)
    01140                         {
    01141                                 if (m_firstLine && m_algorithm != "DSA")
    01142                                 {
    01143                                         if (tokens[i] == "Encrypt" || tokens[i] == "OFB")
    01144                                                 SetEncrypt(true);
    01145                                         else if (tokens[i] == "Decrypt")
    01146                                                 SetEncrypt(false);
    01147                                         else if (tokens[i] == "Modes")
    01148                                                 m_test = "MONTE";
    01149                                 }
    01150                                 else
    01151                                 {
    01152                                         if (tokens[i] != "=")
    01153                                                 continue;
    01154
    01155                                         if (i == 0)
    01156                                                 throw Exception(Exception::OTHER_ERROR, "TestDataParser: unexpected data: " + m_line);
    01157
    01158                                         const std::string &key = tokens[i-1];
    01159                                         std::string &data = m_data[key];
    01160                                         data = (tokens.size() > i+1) ? tokens[i+1] : "";
    01161                                         DataType t = m_nameToType[key];
    01162                                         m_typeToName[t] = key;
    01163                                         m_data2[t] = DecodeHex(data);
    01164
    01165                                         if (key == m_trigger || (t == OUTPUT && !m_data2[INPUT].empty() && !isspace(m_line[0])))
    01166                                                 DoTest();
    01167                                 }
    01168                         }
    01169                 }
    01170
    01171                 m_firstLine = false;
    01172
    01173                 return false;
    01174         }
    01175
    01176         inline const SecByteBlock & GetData(const std::string &key)
    01177         {
    01178                 return m_data2[m_nameToType[key]];
    01179         }
    01180
    01181         static SecByteBlock DecodeHex(const std::string &data)
    01182         {
    01183                 SecByteBlock data2(data.size() / 2);
    01184                 StringSource(data, true, new HexDecoder(new ArraySink(data2, data2.size())));
    01185                 return data2;
    01186         }
    01187
    01188         std::string m_algorithm, m_test, m_mode, m_line, m_bracketString, m_trigger;
    01189         unsigned int m_feedbackSize, m_blankLineTransition;
    01190         bool m_encrypt, m_firstLine;
    01191
    01192         typedef std::map<std::string, DataType> NameToTypeMap;
    01193         NameToTypeMap m_nameToType;
    01194         typedef std::map<DataType, std::string> TypeToNameMap;
    01195         TypeToNameMap m_typeToName;
    01196
    01197         typedef std::map<std::string, std::string> Map;
    01198         Map m_data;             // raw data
    01199         typedef std::map<DataType, SecByteBlock> Map2;
    01200         Map2 m_data2;
    01201         int m_count;
    01202
    01203         AutoSeededX917RNG<AES> m_rng;
    01204         std::vector<unsigned int> m_compactString;
    01205 };
    01206
    01207 int FIPS_140_AlgorithmTest(int argc, char **argv)
    01208 {
    01209         argc--;
    01210         argv++;
    01211
    01212         std::string algorithm = argv[1];
    01213         std::string pathname = argv[2];
    01214         unsigned int i = pathname.find_last_of("\\/");
    01215         std::string filename = pathname.substr(i == std::string::npos ? 0 : i+1);
    01216         std::string dirname = pathname.substr(0, i);
    01217
    01218         if (algorithm == "auto")
    01219         {
    01220                 string algTable[] = {"AES", "ECDSA", "DSA", "HMAC", "RNG", "RSA", "TDES", "SKIPJACK", "SHA"};   // order is important here
    01221                 for (i=0; i<sizeof(algTable)/sizeof(algTable[0]); i++)
    01222                 {
    01223                         if (dirname.find(algTable[i]) != std::string::npos)
    01224                         {
    01225                                 algorithm = algTable[i];
    01226                                 break;
    01227                         }
    01228                 }
    01229         }
    01230
    01231         try
    01232         {
    01233                 std::string mode;
    01234                 if (algorithm == "SHA")
    01235                         mode = IntToString(atol(filename.substr(3, 3).c_str()));
    01236                 else if (algorithm == "RSA")
    01237                         mode = filename.substr(6, 1);
    01238                 else if (filename[0] == 'S' || filename[0] == 'T')
    01239                         mode = filename.substr(1, 3);
    01240                 else
    01241                         mode = filename.substr(0, 3);
    01242                 for (i = 0; i<mode.size(); i++)
    01243                         mode[i] = toupper(mode[i]);
    01244                 unsigned int feedbackSize = mode == "CFB" ? atoi(filename.substr(filename.find_first_of("0123456789")).c_str()) : 0;
    01245                 std::string test;
    01246                 if (algorithm == "DSA" || algorithm == "ECDSA")
    01247                         test = filename.substr(0, filename.size() - 4);
    01248                 else if (algorithm == "RSA")
    01249                         test = filename.substr(3, 3);
    01250                 else if (filename.find("Monte") != std::string::npos)
    01251                         test = "MONTE";
    01252                 else if (filename.find("MCT") != std::string::npos)
    01253                         test = "MCT";
    01254                 else
    01255                         test = "KAT";
    01256                 bool encrypt = (filename.find("vrct") == std::string::npos);
    01257
    01258                 BufferedTransformation *pSink = NULL;
    01259
    01260                 if (argc > 3)
    01261                 {
    01262                         std::string outDir = argv[3];
    01263
    01264                         if (outDir == "auto")
    01265                         {
    01266                                 if (dirname.substr(dirname.size()-3) == "req")
    01267                                         outDir = dirname.substr(0, dirname.size()-3) + "resp";
    01268                         }
    01269
    01270                         if (*outDir.rbegin() != '\\' && *outDir.rbegin() != '/')
    01271                                 outDir += '/';
    01272                         std::string outPathname = outDir + filename.substr(0, filename.size() - 3) + "rsp";
    01273                         pSink = new FileSink(outPathname.c_str(), false);
    01274                 }
    01275                 else
    01276                         pSink = new FileSink(cout);
    01277
    01278                 FileSource(pathname.c_str(), true, new LineBreakParser(new TestDataParser(algorithm, test, mode, feedbackSize, encrypt, pSink)), false);
    01279         }
    01280         catch (...)
    01281         {
    01282                 cout << "file: " << filename << endl;
    01283                 throw;
    01284         }
    01285         return 0;
    01286 }
    01287
    01288 extern int (*AdhocTest)(int argc, char *argv[]);
    01289 static int s_i = (AdhocTest = &FIPS_140_AlgorithmTest, 0);
    01290 #endif