Crypto++
|
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