Team Fortress 2 Source Code as on 22/4/2020
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1294 lines
36 KiB

  1. // fipsalgt.cpp - written and placed in the public domain by Wei Dai
  2. // This file implements the various algorithm tests needed to pass FIPS 140 validation.
  3. // They're preserved here (commented out) in case Crypto++ needs to be revalidated.
  4. #if 0
  5. #ifndef CRYPTOPP_IMPORTS
  6. #define CRYPTOPP_DEFAULT_NO_DLL
  7. #endif
  8. #include "dll.h"
  9. #include "cryptlib.h"
  10. #include "smartptr.h"
  11. #include "filters.h"
  12. #include "oids.h"
  13. USING_NAMESPACE(CryptoPP)
  14. USING_NAMESPACE(std)
  15. class LineBreakParser : public AutoSignaling<Bufferless<Filter> >
  16. {
  17. public:
  18. LineBreakParser(BufferedTransformation *attachment=NULL, byte lineEnd='\n')
  19. : m_lineEnd(lineEnd) {Detach(attachment);}
  20. size_t Put2(const byte *begin, size_t length, int messageEnd, bool blocking)
  21. {
  22. if (!blocking)
  23. throw BlockingInputOnly("LineBreakParser");
  24. unsigned int i, last = 0;
  25. for (i=0; i<length; i++)
  26. {
  27. if (begin[i] == m_lineEnd)
  28. {
  29. AttachedTransformation()->Put2(begin+last, i-last, GetAutoSignalPropagation(), blocking);
  30. last = i+1;
  31. }
  32. }
  33. if (last != i)
  34. AttachedTransformation()->Put2(begin+last, i-last, 0, blocking);
  35. if (messageEnd && GetAutoSignalPropagation())
  36. {
  37. AttachedTransformation()->MessageEnd(GetAutoSignalPropagation()-1, blocking);
  38. AttachedTransformation()->MessageSeriesEnd(GetAutoSignalPropagation()-1, blocking);
  39. }
  40. return 0;
  41. }
  42. private:
  43. byte m_lineEnd;
  44. };
  45. class TestDataParser : public Unflushable<FilterWithInputQueue>
  46. {
  47. public:
  48. enum DataType {OTHER, COUNT, KEY_T, IV, INPUT, OUTPUT};
  49. TestDataParser(std::string algorithm, std::string test, std::string mode, unsigned int feedbackSize, bool encrypt, BufferedTransformation *attachment)
  50. : m_algorithm(algorithm), m_test(test), m_mode(mode), m_feedbackSize(feedbackSize)
  51. , m_firstLine(true), m_blankLineTransition(0)
  52. {
  53. Detach(attachment);
  54. m_typeToName[COUNT] = "COUNT";
  55. m_nameToType["COUNT"] = COUNT;
  56. m_nameToType["KEY"] = KEY_T;
  57. m_nameToType["KEYs"] = KEY_T;
  58. m_nameToType["key"] = KEY_T;
  59. m_nameToType["Key"] = KEY_T;
  60. m_nameToType["IV"] = IV;
  61. m_nameToType["IV1"] = IV;
  62. m_nameToType["CV"] = IV;
  63. m_nameToType["CV1"] = IV;
  64. m_nameToType["IB"] = IV;
  65. m_nameToType["TEXT"] = INPUT;
  66. m_nameToType["RESULT"] = OUTPUT;
  67. m_nameToType["Msg"] = INPUT;
  68. m_nameToType["Seed"] = INPUT;
  69. m_nameToType["V"] = INPUT;
  70. m_nameToType["DT"] = IV;
  71. SetEncrypt(encrypt);
  72. if (m_algorithm == "DSA" || m_algorithm == "ECDSA")
  73. {
  74. if (m_test == "PKV")
  75. m_trigger = "Qy";
  76. else if (m_test == "KeyPair")
  77. m_trigger = "N";
  78. else if (m_test == "SigGen")
  79. m_trigger = "Msg";
  80. else if (m_test == "SigVer")
  81. m_trigger = "S";
  82. else if (m_test == "PQGGen")
  83. m_trigger = "N";
  84. else if (m_test == "PQGVer")
  85. m_trigger = "H";
  86. }
  87. else if (m_algorithm == "HMAC")
  88. m_trigger = "Msg";
  89. else if (m_algorithm == "SHA")
  90. m_trigger = (m_test == "MONTE") ? "Seed" : "Msg";
  91. else if (m_algorithm == "RNG")
  92. m_trigger = "V";
  93. else if (m_algorithm == "RSA")
  94. m_trigger = (m_test == "Ver") ? "S" : "Msg";
  95. }
  96. void SetEncrypt(bool encrypt)
  97. {
  98. m_encrypt = encrypt;
  99. if (encrypt)
  100. {
  101. m_nameToType["PLAINTEXT"] = INPUT;
  102. m_nameToType["CIPHERTEXT"] = OUTPUT;
  103. m_nameToType["PT"] = INPUT;
  104. m_nameToType["CT"] = OUTPUT;
  105. }
  106. else
  107. {
  108. m_nameToType["PLAINTEXT"] = OUTPUT;
  109. m_nameToType["CIPHERTEXT"] = INPUT;
  110. m_nameToType["PT"] = OUTPUT;
  111. m_nameToType["CT"] = INPUT;
  112. }
  113. if (m_algorithm == "AES" || m_algorithm == "TDES")
  114. {
  115. if (encrypt)
  116. {
  117. m_trigger = "PLAINTEXT";
  118. m_typeToName[OUTPUT] = "CIPHERTEXT";
  119. }
  120. else
  121. {
  122. m_trigger = "CIPHERTEXT";
  123. m_typeToName[OUTPUT] = "PLAINTEXT";
  124. }
  125. m_count = 0;
  126. }
  127. }
  128. protected:
  129. void OutputData(std::string &output, const std::string &key, const std::string &data)
  130. {
  131. output += key;
  132. output += "= ";
  133. output += data;
  134. output += "\n";
  135. }
  136. void OutputData(std::string &output, const std::string &key, int data)
  137. {
  138. OutputData(output, key, IntToString(data));
  139. }
  140. void OutputData(std::string &output, const std::string &key, const SecByteBlock &data)
  141. {
  142. output += key;
  143. output += "= ";
  144. HexEncoder(new StringSink(output), false).Put(data, data.size());
  145. output += "\n";
  146. }
  147. void OutputData(std::string &output, const std::string &key, const Integer &data, int size=-1)
  148. {
  149. SecByteBlock s(size < 0 ? data.MinEncodedSize() : size);
  150. data.Encode(s, s.size());
  151. OutputData(output, key, s);
  152. }
  153. void OutputData(std::string &output, const std::string &key, const PolynomialMod2 &data, int size=-1)
  154. {
  155. SecByteBlock s(size < 0 ? data.MinEncodedSize() : size);
  156. data.Encode(s, s.size());
  157. OutputData(output, key, s);
  158. }
  159. void OutputData(std::string &output, DataType t, const std::string &data)
  160. {
  161. if (m_algorithm == "SKIPJACK")
  162. {
  163. if (m_test == "KAT")
  164. {
  165. if (t == OUTPUT)
  166. output = m_line + data + "\n";
  167. }
  168. else
  169. {
  170. if (t != COUNT)
  171. {
  172. output += m_typeToName[t];
  173. output += "=";
  174. }
  175. output += data;
  176. output += t == OUTPUT ? "\n" : " ";
  177. }
  178. }
  179. else if (m_algorithm == "TDES" && t == KEY_T && m_typeToName[KEY_T].empty())
  180. {
  181. output += "KEY1 = ";
  182. output += data.substr(0, 16);
  183. output += "\nKEY2 = ";
  184. output += data.size() > 16 ? data.substr(16, 16) : data.substr(0, 16);
  185. output += "\nKEY3 = ";
  186. output += data.size() > 32 ? data.substr(32, 16) : data.substr(0, 16);
  187. output += "\n";
  188. }
  189. else
  190. {
  191. output += m_typeToName[t];
  192. output += " = ";
  193. output += data;
  194. output += "\n";
  195. }
  196. }
  197. void OutputData(std::string &output, DataType t, int i)
  198. {
  199. OutputData(output, t, IntToString(i));
  200. }
  201. void OutputData(std::string &output, DataType t, const SecByteBlock &data)
  202. {
  203. std::string hexData;
  204. StringSource(data.begin(), data.size(), true, new HexEncoder(new StringSink(hexData), false));
  205. OutputData(output, t, hexData);
  206. }
  207. void OutputGivenData(std::string &output, DataType t, bool optional = false)
  208. {
  209. if (m_data.find(m_typeToName[t]) == m_data.end())
  210. {
  211. if (optional)
  212. return;
  213. throw Exception(Exception::OTHER_ERROR, "TestDataParser: key not found: " + m_typeToName[t]);
  214. }
  215. OutputData(output, t, m_data[m_typeToName[t]]);
  216. }
  217. template <class T>
  218. BlockCipher * NewBT(T *)
  219. {
  220. if (!m_encrypt && (m_mode == "ECB" || m_mode == "CBC"))
  221. return new typename T::Decryption;
  222. else
  223. return new typename T::Encryption;
  224. }
  225. template <class T>
  226. SymmetricCipher * NewMode(T *, BlockCipher &bt, const byte *iv)
  227. {
  228. if (!m_encrypt)
  229. return new typename T::Decryption(bt, iv, m_feedbackSize/8);
  230. else
  231. return new typename T::Encryption(bt, iv, m_feedbackSize/8);
  232. }
  233. static inline void Xor(SecByteBlock &z, const SecByteBlock &x, const SecByteBlock &y)
  234. {
  235. assert(x.size() == y.size());
  236. z.resize(x.size());
  237. xorbuf(z, x, y, x.size());
  238. }
  239. SecByteBlock UpdateKey(SecByteBlock key, const SecByteBlock *text)
  240. {
  241. unsigned int innerCount = (m_algorithm == "AES") ? 1000 : 10000;
  242. int keySize = key.size(), blockSize = text[0].size();
  243. SecByteBlock x(keySize);
  244. for (int k=0; k<keySize;)
  245. {
  246. int pos = innerCount * blockSize - keySize + k;
  247. memcpy(x + k, text[pos / blockSize] + pos % blockSize, blockSize - pos % blockSize);
  248. k += blockSize - pos % blockSize;
  249. }
  250. if (m_algorithm == "TDES" || m_algorithm == "DES")
  251. {
  252. for (int i=0; i<keySize; i+=8)
  253. {
  254. xorbuf(key+i, x+keySize-8-i, 8);
  255. DES::CorrectKeyParityBits(key+i);
  256. }
  257. }
  258. else
  259. xorbuf(key, x, keySize);
  260. return key;
  261. }
  262. static inline void AssignLeftMostBits(SecByteBlock &z, const SecByteBlock &x, unsigned int K)
  263. {
  264. z.Assign(x, K/8);
  265. }
  266. template <class EC>
  267. void EC_KeyPair(string &output, int n, const OID &oid)
  268. {
  269. DL_GroupParameters_EC<EC> params(oid);
  270. for (int i=0; i<n; i++)
  271. {
  272. DL_PrivateKey_EC<EC> priv;
  273. DL_PublicKey_EC<EC> pub;
  274. priv.Initialize(m_rng, params);
  275. priv.MakePublicKey(pub);
  276. OutputData(output, "d ", priv.GetPrivateExponent());
  277. OutputData(output, "Qx ", pub.GetPublicElement().x, params.GetCurve().GetField().MaxElementByteLength());
  278. OutputData(output, "Qy ", pub.GetPublicElement().y, params.GetCurve().GetField().MaxElementByteLength());
  279. }
  280. }
  281. template <class EC>
  282. void EC_SigGen(string &output, const OID &oid)
  283. {
  284. DL_GroupParameters_EC<EC> params(oid);
  285. typename ECDSA<EC, SHA1>::PrivateKey priv;
  286. typename ECDSA<EC, SHA1>::PublicKey pub;
  287. priv.Initialize(m_rng, params);
  288. priv.MakePublicKey(pub);
  289. typename ECDSA<EC, SHA1>::Signer signer(priv);
  290. SecByteBlock sig(signer.SignatureLength());
  291. StringSource(m_data["Msg"], true, new HexDecoder(new SignerFilter(m_rng, signer, new ArraySink(sig, sig.size()))));
  292. SecByteBlock R(sig, sig.size()/2), S(sig+sig.size()/2, sig.size()/2);
  293. OutputData(output, "Qx ", pub.GetPublicElement().x, params.GetCurve().GetField().MaxElementByteLength());
  294. OutputData(output, "Qy ", pub.GetPublicElement().y, params.GetCurve().GetField().MaxElementByteLength());
  295. OutputData(output, "R ", R);
  296. OutputData(output, "S ", S);
  297. }
  298. template <class EC>
  299. void EC_SigVer(string &output, const OID &oid)
  300. {
  301. SecByteBlock x(DecodeHex(m_data["Qx"]));
  302. SecByteBlock y(DecodeHex(m_data["Qy"]));
  303. Integer r((m_data["R"]+"h").c_str());
  304. Integer s((m_data["S"]+"h").c_str());
  305. typename EC::FieldElement Qx(x, x.size());
  306. typename EC::FieldElement Qy(y, y.size());
  307. typename EC::Element Q(Qx, Qy);
  308. DL_GroupParameters_EC<EC> params(oid);
  309. typename ECDSA<EC, SHA1>::PublicKey pub;
  310. pub.Initialize(params, Q);
  311. typename ECDSA<EC, SHA1>::Verifier verifier(pub);
  312. SecByteBlock sig(verifier.SignatureLength());
  313. r.Encode(sig, sig.size()/2);
  314. s.Encode(sig+sig.size()/2, sig.size()/2);
  315. SignatureVerificationFilter filter(verifier);
  316. filter.Put(sig, sig.size());
  317. StringSource(m_data["Msg"], true, new HexDecoder(new Redirector(filter, Redirector::DATA_ONLY)));
  318. filter.MessageEnd();
  319. byte b;
  320. filter.Get(b);
  321. OutputData(output, "Result ", b ? "P" : "F");
  322. }
  323. template <class EC>
  324. static bool EC_PKV(RandomNumberGenerator &rng, const SecByteBlock &x, const SecByteBlock &y, const OID &oid)
  325. {
  326. typename EC::FieldElement Qx(x, x.size());
  327. typename EC::FieldElement Qy(y, y.size());
  328. typename EC::Element Q(Qx, Qy);
  329. DL_GroupParameters_EC<EC> params(oid);
  330. typename ECDSA<EC, SHA1>::PublicKey pub;
  331. pub.Initialize(params, Q);
  332. return pub.Validate(rng, 3);
  333. }
  334. template <class H, class Result>
  335. Result * CreateRSA2(const std::string &standard)
  336. {
  337. if (typeid(Result) == typeid(PK_Verifier))
  338. {
  339. if (standard == "R")
  340. return (Result *) new typename RSASS_ISO<H>::Verifier;
  341. else if (standard == "P")
  342. return (Result *) new typename RSASS<PSS, H>::Verifier;
  343. else if (standard == "1")
  344. return (Result *) new typename RSASS<PKCS1v15, H>::Verifier;
  345. }
  346. else if (typeid(Result) == typeid(PK_Signer))
  347. {
  348. if (standard == "R")
  349. return (Result *) new typename RSASS_ISO<H>::Signer;
  350. else if (standard == "P")
  351. return (Result *) new typename RSASS<PSS, H>::Signer;
  352. else if (standard == "1")
  353. return (Result *) new typename RSASS<PKCS1v15, H>::Signer;
  354. }
  355. return NULL;
  356. }
  357. template <class Result>
  358. Result * CreateRSA(const std::string &standard, const std::string &hash)
  359. {
  360. if (hash == "1")
  361. return CreateRSA2<SHA1, Result>(standard);
  362. else if (hash == "224")
  363. return CreateRSA2<SHA224, Result>(standard);
  364. else if (hash == "256")
  365. return CreateRSA2<SHA256, Result>(standard);
  366. else if (hash == "384")
  367. return CreateRSA2<SHA384, Result>(standard);
  368. else if (hash == "512")
  369. return CreateRSA2<SHA512, Result>(standard);
  370. else
  371. return NULL;
  372. }
  373. virtual void DoTest()
  374. {
  375. std::string output;
  376. if (m_algorithm == "DSA")
  377. {
  378. if (m_test == "KeyPair")
  379. {
  380. DL_GroupParameters_DSA pqg;
  381. int modLen = atol(m_bracketString.substr(6).c_str());
  382. pqg.GenerateRandomWithKeySize(m_rng, modLen);
  383. OutputData(output, "P ", pqg.GetModulus());
  384. OutputData(output, "Q ", pqg.GetSubgroupOrder());
  385. OutputData(output, "G ", pqg.GetSubgroupGenerator());
  386. int n = atol(m_data["N"].c_str());
  387. for (int i=0; i<n; i++)
  388. {
  389. DSA::Signer priv;
  390. priv.AccessKey().GenerateRandom(m_rng, pqg);
  391. DSA::Verifier pub(priv);
  392. OutputData(output, "X ", priv.GetKey().GetPrivateExponent());
  393. OutputData(output, "Y ", pub.GetKey().GetPublicElement());
  394. AttachedTransformation()->Put((byte *)output.data(), output.size());
  395. output.resize(0);
  396. }
  397. }
  398. else if (m_test == "PQGGen")
  399. {
  400. int n = atol(m_data["N"].c_str());
  401. for (int i=0; i<n; i++)
  402. {
  403. Integer p, q, h, g;
  404. int counter;
  405. SecByteBlock seed(SHA::DIGESTSIZE);
  406. do
  407. {
  408. m_rng.GenerateBlock(seed, seed.size());
  409. }
  410. while (!DSA::GeneratePrimes(seed, seed.size()*8, counter, p, 1024, q));
  411. h.Randomize(m_rng, 2, p-2);
  412. g = a_exp_b_mod_c(h, (p-1)/q, p);
  413. OutputData(output, "P ", p);
  414. OutputData(output, "Q ", q);
  415. OutputData(output, "G ", g);
  416. OutputData(output, "Seed ", seed);
  417. OutputData(output, "c ", counter);
  418. OutputData(output, "H ", h, p.ByteCount());
  419. AttachedTransformation()->Put((byte *)output.data(), output.size());
  420. output.resize(0);
  421. }
  422. }
  423. else if (m_test == "SigGen")
  424. {
  425. std::string &encodedKey = m_data["PrivKey"];
  426. int modLen = atol(m_bracketString.substr(6).c_str());
  427. DSA::PrivateKey priv;
  428. if (!encodedKey.empty())
  429. {
  430. StringStore s(encodedKey);
  431. priv.BERDecode(s);
  432. if (priv.GetGroupParameters().GetModulus().BitCount() != modLen)
  433. encodedKey.clear();
  434. }
  435. if (encodedKey.empty())
  436. {
  437. priv.Initialize(m_rng, modLen);
  438. StringSink s(encodedKey);
  439. priv.DEREncode(s);
  440. OutputData(output, "P ", priv.GetGroupParameters().GetModulus());
  441. OutputData(output, "Q ", priv.GetGroupParameters().GetSubgroupOrder());
  442. OutputData(output, "G ", priv.GetGroupParameters().GetSubgroupGenerator());
  443. }
  444. DSA::Signer signer(priv);
  445. DSA::Verifier pub(signer);
  446. OutputData(output, "Msg ", m_data["Msg"]);
  447. OutputData(output, "Y ", pub.GetKey().GetPublicElement());
  448. SecByteBlock sig(signer.SignatureLength());
  449. StringSource(m_data["Msg"], true, new HexDecoder(new SignerFilter(m_rng, signer, new ArraySink(sig, sig.size()))));
  450. SecByteBlock R(sig, sig.size()/2), S(sig+sig.size()/2, sig.size()/2);
  451. OutputData(output, "R ", R);
  452. OutputData(output, "S ", S);
  453. AttachedTransformation()->Put((byte *)output.data(), output.size());
  454. output.resize(0);
  455. }
  456. else if (m_test == "SigVer")
  457. {
  458. Integer p((m_data["P"] + "h").c_str());
  459. Integer q((m_data["Q"] + "h").c_str());
  460. Integer g((m_data["G"] + "h").c_str());
  461. Integer y((m_data["Y"] + "h").c_str());
  462. DSA::Verifier verifier(p, q, g, y);
  463. HexDecoder filter(new SignatureVerificationFilter(verifier));
  464. StringSource(m_data["R"], true, new Redirector(filter, Redirector::DATA_ONLY));
  465. StringSource(m_data["S"], true, new Redirector(filter, Redirector::DATA_ONLY));
  466. StringSource(m_data["Msg"], true, new Redirector(filter, Redirector::DATA_ONLY));
  467. filter.MessageEnd();
  468. byte b;
  469. filter.Get(b);
  470. OutputData(output, "Result ", b ? "P" : "F");
  471. AttachedTransformation()->Put((byte *)output.data(), output.size());
  472. output.resize(0);
  473. }
  474. else if (m_test == "PQGVer")
  475. {
  476. Integer p((m_data["P"] + "h").c_str());
  477. Integer q((m_data["Q"] + "h").c_str());
  478. Integer g((m_data["G"] + "h").c_str());
  479. Integer h((m_data["H"] + "h").c_str());
  480. int c = atol(m_data["c"].c_str());
  481. SecByteBlock seed(m_data["Seed"].size()/2);
  482. StringSource(m_data["Seed"], true, new HexDecoder(new ArraySink(seed, seed.size())));
  483. Integer p1, q1;
  484. bool result = DSA::GeneratePrimes(seed, seed.size()*8, c, p1, 1024, q1, true);
  485. result = result && (p1 == p && q1 == q);
  486. result = result && g == a_exp_b_mod_c(h, (p-1)/q, p);
  487. OutputData(output, "Result ", result ? "P" : "F");
  488. AttachedTransformation()->Put((byte *)output.data(), output.size());
  489. output.resize(0);
  490. }
  491. return;
  492. }
  493. if (m_algorithm == "ECDSA")
  494. {
  495. std::map<std::string, OID> name2oid;
  496. name2oid["P-192"] = ASN1::secp192r1();
  497. name2oid["P-224"] = ASN1::secp224r1();
  498. name2oid["P-256"] = ASN1::secp256r1();
  499. name2oid["P-384"] = ASN1::secp384r1();
  500. name2oid["P-521"] = ASN1::secp521r1();
  501. name2oid["K-163"] = ASN1::sect163k1();
  502. name2oid["K-233"] = ASN1::sect233k1();
  503. name2oid["K-283"] = ASN1::sect283k1();
  504. name2oid["K-409"] = ASN1::sect409k1();
  505. name2oid["K-571"] = ASN1::sect571k1();
  506. name2oid["B-163"] = ASN1::sect163r2();
  507. name2oid["B-233"] = ASN1::sect233r1();
  508. name2oid["B-283"] = ASN1::sect283r1();
  509. name2oid["B-409"] = ASN1::sect409r1();
  510. name2oid["B-571"] = ASN1::sect571r1();
  511. if (m_test == "PKV")
  512. {
  513. bool pass;
  514. if (m_bracketString[0] == 'P')
  515. pass = EC_PKV<ECP>(m_rng, DecodeHex(m_data["Qx"]), DecodeHex(m_data["Qy"]), name2oid[m_bracketString]);
  516. else
  517. pass = EC_PKV<EC2N>(m_rng, DecodeHex(m_data["Qx"]), DecodeHex(m_data["Qy"]), name2oid[m_bracketString]);
  518. OutputData(output, "Result ", pass ? "P" : "F");
  519. }
  520. else if (m_test == "KeyPair")
  521. {
  522. if (m_bracketString[0] == 'P')
  523. EC_KeyPair<ECP>(output, atol(m_data["N"].c_str()), name2oid[m_bracketString]);
  524. else
  525. EC_KeyPair<EC2N>(output, atol(m_data["N"].c_str()), name2oid[m_bracketString]);
  526. }
  527. else if (m_test == "SigGen")
  528. {
  529. if (m_bracketString[0] == 'P')
  530. EC_SigGen<ECP>(output, name2oid[m_bracketString]);
  531. else
  532. EC_SigGen<EC2N>(output, name2oid[m_bracketString]);
  533. }
  534. else if (m_test == "SigVer")
  535. {
  536. if (m_bracketString[0] == 'P')
  537. EC_SigVer<ECP>(output, name2oid[m_bracketString]);
  538. else
  539. EC_SigVer<EC2N>(output, name2oid[m_bracketString]);
  540. }
  541. AttachedTransformation()->Put((byte *)output.data(), output.size());
  542. output.resize(0);
  543. return;
  544. }
  545. if (m_algorithm == "RSA")
  546. {
  547. std::string shaAlg = m_data["SHAAlg"].substr(3);
  548. if (m_test == "Ver")
  549. {
  550. Integer n((m_data["n"] + "h").c_str());
  551. Integer e((m_data["e"] + "h").c_str());
  552. RSA::PublicKey pub;
  553. pub.Initialize(n, e);
  554. member_ptr<PK_Verifier> pV(CreateRSA<PK_Verifier>(m_mode, shaAlg));
  555. pV->AccessMaterial().AssignFrom(pub);
  556. HexDecoder filter(new SignatureVerificationFilter(*pV));
  557. for (unsigned int i=m_data["S"].size(); i<pV->SignatureLength()*2; i++)
  558. filter.Put('0');
  559. StringSource(m_data["S"], true, new Redirector(filter, Redirector::DATA_ONLY));
  560. StringSource(m_data["Msg"], true, new Redirector(filter, Redirector::DATA_ONLY));
  561. filter.MessageEnd();
  562. byte b;
  563. filter.Get(b);
  564. OutputData(output, "Result ", b ? "P" : "F");
  565. }
  566. else
  567. {
  568. assert(m_test == "Gen");
  569. int modLen = atol(m_bracketString.substr(6).c_str());
  570. std::string &encodedKey = m_data["PrivKey"];
  571. RSA::PrivateKey priv;
  572. if (!encodedKey.empty())
  573. {
  574. StringStore s(encodedKey);
  575. priv.BERDecode(s);
  576. if (priv.GetModulus().BitCount() != modLen)
  577. encodedKey.clear();
  578. }
  579. if (encodedKey.empty())
  580. {
  581. priv.Initialize(m_rng, modLen);
  582. StringSink s(encodedKey);
  583. priv.DEREncode(s);
  584. OutputData(output, "n ", priv.GetModulus());
  585. OutputData(output, "e ", priv.GetPublicExponent(), modLen/8);
  586. }
  587. member_ptr<PK_Signer> pS(CreateRSA<PK_Signer>(m_mode, shaAlg));
  588. pS->AccessMaterial().AssignFrom(priv);
  589. SecByteBlock sig(pS->SignatureLength());
  590. StringSource(m_data["Msg"], true, new HexDecoder(new SignerFilter(m_rng, *pS, new ArraySink(sig, sig.size()))));
  591. OutputData(output, "SHAAlg ", m_data["SHAAlg"]);
  592. OutputData(output, "Msg ", m_data["Msg"]);
  593. OutputData(output, "S ", sig);
  594. }
  595. AttachedTransformation()->Put((byte *)output.data(), output.size());
  596. output.resize(0);
  597. return;
  598. }
  599. if (m_algorithm == "SHA")
  600. {
  601. member_ptr<HashFunction> pHF;
  602. if (m_mode == "1")
  603. pHF.reset(new SHA1);
  604. else if (m_mode == "224")
  605. pHF.reset(new SHA224);
  606. else if (m_mode == "256")
  607. pHF.reset(new SHA256);
  608. else if (m_mode == "384")
  609. pHF.reset(new SHA384);
  610. else if (m_mode == "512")
  611. pHF.reset(new SHA512);
  612. if (m_test == "MONTE")
  613. {
  614. SecByteBlock seed = m_data2[INPUT];
  615. SecByteBlock MD[1003];
  616. int i,j;
  617. for (j=0; j<100; j++)
  618. {
  619. MD[0] = MD[1] = MD[2] = seed;
  620. for (i=3; i<1003; i++)
  621. {
  622. SecByteBlock Mi = MD[i-3] + MD[i-2] + MD[i-1];
  623. MD[i].resize(pHF->DigestSize());
  624. pHF->CalculateDigest(MD[i], Mi, Mi.size());
  625. }
  626. seed = MD[1002];
  627. OutputData(output, "COUNT ", j);
  628. OutputData(output, "MD ", seed);
  629. AttachedTransformation()->Put((byte *)output.data(), output.size());
  630. output.resize(0);
  631. }
  632. }
  633. else
  634. {
  635. SecByteBlock tag(pHF->DigestSize());
  636. SecByteBlock &msg(m_data2[INPUT]);
  637. int len = atol(m_data["Len"].c_str());
  638. StringSource(msg.begin(), len/8, true, new HashFilter(*pHF, new ArraySink(tag, tag.size())));
  639. OutputData(output, "MD ", tag);
  640. AttachedTransformation()->Put((byte *)output.data(), output.size());
  641. output.resize(0);
  642. }
  643. return;
  644. }
  645. SecByteBlock &key = m_data2[KEY_T];
  646. if (m_algorithm == "TDES")
  647. {
  648. if (!m_data["KEY1"].empty())
  649. {
  650. const std::string keys[3] = {m_data["KEY1"], m_data["KEY2"], m_data["KEY3"]};
  651. key.resize(24);
  652. HexDecoder hexDec(new ArraySink(key, key.size()));
  653. for (int i=0; i<3; i++)
  654. hexDec.Put((byte *)keys[i].data(), keys[i].size());
  655. if (keys[0] == keys[2])
  656. {
  657. if (keys[0] == keys[1])
  658. key.resize(8);
  659. else
  660. key.resize(16);
  661. }
  662. else
  663. key.resize(24);
  664. }
  665. }
  666. if (m_algorithm == "RNG")
  667. {
  668. key.resize(24);
  669. StringSource(m_data["Key1"] + m_data["Key2"] + m_data["Key3"], true, new HexDecoder(new ArraySink(key, key.size())));
  670. SecByteBlock seed(m_data2[INPUT]), dt(m_data2[IV]), r(8);
  671. X917RNG rng(new DES_EDE3::Encryption(key, key.size()), seed, dt);
  672. if (m_test == "MCT")
  673. {
  674. for (int i=0; i<10000; i++)
  675. rng.GenerateBlock(r, r.size());
  676. }
  677. else
  678. {
  679. rng.GenerateBlock(r, r.size());
  680. }
  681. OutputData(output, "R ", r);
  682. AttachedTransformation()->Put((byte *)output.data(), output.size());
  683. output.resize(0);
  684. return;
  685. }
  686. if (m_algorithm == "HMAC")
  687. {
  688. member_ptr<MessageAuthenticationCode> pMAC;
  689. if (m_bracketString == "L=20")
  690. pMAC.reset(new HMAC<SHA1>);
  691. else if (m_bracketString == "L=28")
  692. pMAC.reset(new HMAC<SHA224>);
  693. else if (m_bracketString == "L=32")
  694. pMAC.reset(new HMAC<SHA256>);
  695. else if (m_bracketString == "L=48")
  696. pMAC.reset(new HMAC<SHA384>);
  697. else if (m_bracketString == "L=64")
  698. pMAC.reset(new HMAC<SHA512>);
  699. else
  700. throw Exception(Exception::OTHER_ERROR, "TestDataParser: unexpected HMAC bracket string: " + m_bracketString);
  701. pMAC->SetKey(key, key.size());
  702. int Tlen = atol(m_data["Tlen"].c_str());
  703. SecByteBlock tag(Tlen);
  704. StringSource(m_data["Msg"], true, new HexDecoder(new HashFilter(*pMAC, new ArraySink(tag, Tlen), false, Tlen)));
  705. OutputData(output, "Mac ", tag);
  706. AttachedTransformation()->Put((byte *)output.data(), output.size());
  707. output.resize(0);
  708. return;
  709. }
  710. member_ptr<BlockCipher> pBT;
  711. if (m_algorithm == "DES")
  712. pBT.reset(NewBT((DES*)0));
  713. else if (m_algorithm == "TDES")
  714. {
  715. if (key.size() == 8)
  716. pBT.reset(NewBT((DES*)0));
  717. else if (key.size() == 16)
  718. pBT.reset(NewBT((DES_EDE2*)0));
  719. else
  720. pBT.reset(NewBT((DES_EDE3*)0));
  721. }
  722. else if (m_algorithm == "SKIPJACK")
  723. pBT.reset(NewBT((SKIPJACK*)0));
  724. else if (m_algorithm == "AES")
  725. pBT.reset(NewBT((AES*)0));
  726. else
  727. throw Exception(Exception::OTHER_ERROR, "TestDataParser: unexpected algorithm: " + m_algorithm);
  728. if (!pBT->IsValidKeyLength(key.size()))
  729. key.CleanNew(pBT->DefaultKeyLength()); // for Scbcvrct
  730. pBT->SetKey(key.data(), key.size());
  731. SecByteBlock &iv = m_data2[IV];
  732. if (iv.empty())
  733. iv.CleanNew(pBT->BlockSize());
  734. member_ptr<SymmetricCipher> pCipher;
  735. unsigned int K = m_feedbackSize;
  736. if (m_mode == "ECB")
  737. pCipher.reset(NewMode((ECB_Mode_ExternalCipher*)0, *pBT, iv));
  738. else if (m_mode == "CBC")
  739. pCipher.reset(NewMode((CBC_Mode_ExternalCipher*)0, *pBT, iv));
  740. else if (m_mode == "CFB")
  741. pCipher.reset(NewMode((CFB_Mode_ExternalCipher*)0, *pBT, iv));
  742. else if (m_mode == "OFB")
  743. pCipher.reset(NewMode((OFB_Mode_ExternalCipher*)0, *pBT, iv));
  744. else
  745. throw Exception(Exception::OTHER_ERROR, "TestDataParser: unexpected mode: " + m_mode);
  746. bool encrypt = m_encrypt;
  747. if (m_test == "MONTE")
  748. {
  749. SecByteBlock KEY[401];
  750. KEY[0] = key;
  751. int keySize = key.size();
  752. int blockSize = pBT->BlockSize();
  753. std::vector<SecByteBlock> IB(10001), OB(10001), PT(10001), CT(10001), RESULT(10001), TXT(10001), CV(10001);
  754. PT[0] = GetData("PLAINTEXT");
  755. CT[0] = GetData("CIPHERTEXT");
  756. CV[0] = IB[0] = iv;
  757. TXT[0] = GetData("TEXT");
  758. int outerCount = (m_algorithm == "AES") ? 100 : 400;
  759. int innerCount = (m_algorithm == "AES") ? 1000 : 10000;
  760. for (int i=0; i<outerCount; i++)
  761. {
  762. pBT->SetKey(KEY[i], keySize);
  763. for (int j=0; j<innerCount; j++)
  764. {
  765. if (m_mode == "ECB")
  766. {
  767. if (encrypt)
  768. {
  769. IB[j] = PT[j];
  770. CT[j].resize(blockSize);
  771. pBT->ProcessBlock(IB[j], CT[j]);
  772. PT[j+1] = CT[j];
  773. }
  774. else
  775. {
  776. IB[j] = CT[j];
  777. PT[j].resize(blockSize);
  778. pBT->ProcessBlock(IB[j], PT[j]);
  779. CT[j+1] = PT[j];
  780. }
  781. }
  782. else if (m_mode == "OFB")
  783. {
  784. OB[j].resize(blockSize);
  785. pBT->ProcessBlock(IB[j], OB[j]);
  786. Xor(RESULT[j], OB[j], TXT[j]);
  787. TXT[j+1] = IB[j];
  788. IB[j+1] = OB[j];
  789. }
  790. else if (m_mode == "CBC")
  791. {
  792. if (encrypt)
  793. {
  794. Xor(IB[j], PT[j], CV[j]);
  795. CT[j].resize(blockSize);
  796. pBT->ProcessBlock(IB[j], CT[j]);
  797. PT[j+1] = CV[j];
  798. CV[j+1] = CT[j];
  799. }
  800. else
  801. {
  802. IB[j] = CT[j];
  803. OB[j].resize(blockSize);
  804. pBT->ProcessBlock(IB[j], OB[j]);
  805. Xor(PT[j], OB[j], CV[j]);
  806. CV[j+1] = CT[j];
  807. CT[j+1] = PT[j];
  808. }
  809. }
  810. else if (m_mode == "CFB")
  811. {
  812. if (encrypt)
  813. {
  814. OB[j].resize(blockSize);
  815. pBT->ProcessBlock(IB[j], OB[j]);
  816. AssignLeftMostBits(CT[j], OB[j], K);
  817. Xor(CT[j], CT[j], PT[j]);
  818. AssignLeftMostBits(PT[j+1], IB[j], K);
  819. IB[j+1].resize(blockSize);
  820. memcpy(IB[j+1], IB[j]+K/8, blockSize-K/8);
  821. memcpy(IB[j+1]+blockSize-K/8, CT[j], K/8);
  822. }
  823. else
  824. {
  825. OB[j].resize(blockSize);
  826. pBT->ProcessBlock(IB[j], OB[j]);
  827. AssignLeftMostBits(PT[j], OB[j], K);
  828. Xor(PT[j], PT[j], CT[j]);
  829. IB[j+1].resize(blockSize);
  830. memcpy(IB[j+1], IB[j]+K/8, blockSize-K/8);
  831. memcpy(IB[j+1]+blockSize-K/8, CT[j], K/8);
  832. AssignLeftMostBits(CT[j+1], OB[j], K);
  833. }
  834. }
  835. else
  836. throw Exception(Exception::OTHER_ERROR, "TestDataParser: unexpected mode: " + m_mode);
  837. }
  838. OutputData(output, COUNT, IntToString(i));
  839. OutputData(output, KEY_T, KEY[i]);
  840. if (m_mode == "CBC")
  841. OutputData(output, IV, CV[0]);
  842. if (m_mode == "OFB" || m_mode == "CFB")
  843. OutputData(output, IV, IB[0]);
  844. if (m_mode == "ECB" || m_mode == "CBC" || m_mode == "CFB")
  845. {
  846. if (encrypt)
  847. {
  848. OutputData(output, INPUT, PT[0]);
  849. OutputData(output, OUTPUT, CT[innerCount-1]);
  850. KEY[i+1] = UpdateKey(KEY[i], &CT[0]);
  851. }
  852. else
  853. {
  854. OutputData(output, INPUT, CT[0]);
  855. OutputData(output, OUTPUT, PT[innerCount-1]);
  856. KEY[i+1] = UpdateKey(KEY[i], &PT[0]);
  857. }
  858. PT[0] = PT[innerCount];
  859. IB[0] = IB[innerCount];
  860. CV[0] = CV[innerCount];
  861. CT[0] = CT[innerCount];
  862. }
  863. else if (m_mode == "OFB")
  864. {
  865. OutputData(output, INPUT, TXT[0]);
  866. OutputData(output, OUTPUT, RESULT[innerCount-1]);
  867. KEY[i+1] = UpdateKey(KEY[i], &RESULT[0]);
  868. Xor(TXT[0], TXT[0], IB[innerCount-1]);
  869. IB[0] = OB[innerCount-1];
  870. }
  871. output += "\n";
  872. AttachedTransformation()->Put((byte *)output.data(), output.size());
  873. output.resize(0);
  874. }
  875. }
  876. else if (m_test == "MCT")
  877. {
  878. SecByteBlock KEY[101];
  879. KEY[0] = key;
  880. int keySize = key.size();
  881. int blockSize = pBT->BlockSize();
  882. SecByteBlock ivs[101], inputs[1001], outputs[1001];
  883. ivs[0] = iv;
  884. inputs[0] = m_data2[INPUT];
  885. for (int i=0; i<100; i++)
  886. {
  887. pCipher->SetKey(KEY[i], keySize, MakeParameters(Name::IV(), (const byte *)ivs[i])(Name::FeedbackSize(), (int)K/8, false));
  888. for (int j=0; j<1000; j++)
  889. {
  890. outputs[j] = inputs[j];
  891. pCipher->ProcessString(outputs[j], outputs[j].size());
  892. if (K==8 && m_mode == "CFB")
  893. {
  894. if (j<16)
  895. inputs[j+1].Assign(ivs[i]+j, 1);
  896. else
  897. inputs[j+1] = outputs[j-16];
  898. }
  899. else if (m_mode == "ECB")
  900. inputs[j+1] = outputs[j];
  901. else if (j == 0)
  902. inputs[j+1] = ivs[i];
  903. else
  904. inputs[j+1] = outputs[j-1];
  905. }
  906. if (m_algorithm == "AES")
  907. OutputData(output, COUNT, m_count++);
  908. OutputData(output, KEY_T, KEY[i]);
  909. if (m_mode != "ECB")
  910. OutputData(output, IV, ivs[i]);
  911. OutputData(output, INPUT, inputs[0]);
  912. OutputData(output, OUTPUT, outputs[999]);
  913. output += "\n";
  914. AttachedTransformation()->Put((byte *)output.data(), output.size());
  915. output.resize(0);
  916. KEY[i+1] = UpdateKey(KEY[i], outputs);
  917. ivs[i+1].CleanNew(pCipher->IVSize());
  918. ivs[i+1] = UpdateKey(ivs[i+1], outputs);
  919. if (K==8 && m_mode == "CFB")
  920. inputs[0] = outputs[999-16];
  921. else if (m_mode == "ECB")
  922. inputs[0] = outputs[999];
  923. else
  924. inputs[0] = outputs[998];
  925. }
  926. }
  927. else
  928. {
  929. assert(m_test == "KAT");
  930. SecByteBlock &input = m_data2[INPUT];
  931. SecByteBlock result(input.size());
  932. member_ptr<Filter> pFilter(new StreamTransformationFilter(*pCipher, new ArraySink(result, result.size()), StreamTransformationFilter::NO_PADDING));
  933. StringSource(input.data(), input.size(), true, pFilter.release());
  934. OutputGivenData(output, COUNT, true);
  935. OutputData(output, KEY_T, key);
  936. OutputGivenData(output, IV, true);
  937. OutputGivenData(output, INPUT);
  938. OutputData(output, OUTPUT, result);
  939. output += "\n";
  940. AttachedTransformation()->Put((byte *)output.data(), output.size());
  941. }
  942. }
  943. std::vector<std::string> Tokenize(const std::string &line)
  944. {
  945. std::vector<std::string> result;
  946. std::string s;
  947. for (unsigned int i=0; i<line.size(); i++)
  948. {
  949. if (isalnum(line[i]) || line[i] == '^')
  950. s += line[i];
  951. else if (!s.empty())
  952. {
  953. result.push_back(s);
  954. s = "";
  955. }
  956. if (line[i] == '=')
  957. result.push_back("=");
  958. }
  959. if (!s.empty())
  960. result.push_back(s);
  961. return result;
  962. }
  963. bool IsolatedMessageEnd(bool blocking)
  964. {
  965. if (!blocking)
  966. throw BlockingInputOnly("TestDataParser");
  967. m_line.resize(0);
  968. m_inQueue.TransferTo(StringSink(m_line).Ref());
  969. if (m_line[0] == '#')
  970. return false;
  971. bool copyLine = false;
  972. if (m_line[0] == '[')
  973. {
  974. m_bracketString = m_line.substr(1, m_line.size()-2);
  975. if (m_bracketString == "ENCRYPT")
  976. SetEncrypt(true);
  977. if (m_bracketString == "DECRYPT")
  978. SetEncrypt(false);
  979. copyLine = true;
  980. }
  981. if (m_line.substr(0, 2) == "H>")
  982. {
  983. assert(m_test == "sha");
  984. m_bracketString = m_line.substr(2, m_line.size()-4);
  985. m_line = m_line.substr(0, 13) + "Hashes<H";
  986. copyLine = true;
  987. }
  988. if (m_line == "D>")
  989. copyLine = true;
  990. if (m_line == "<D")
  991. {
  992. m_line += "\n";
  993. copyLine = true;
  994. }
  995. if (copyLine)
  996. {
  997. m_line += '\n';
  998. AttachedTransformation()->Put((byte *)m_line.data(), m_line.size(), blocking);
  999. return false;
  1000. }
  1001. std::vector<std::string> tokens = Tokenize(m_line);
  1002. if (m_algorithm == "DSA" && m_test == "sha")
  1003. {
  1004. for (unsigned int i = 0; i < tokens.size(); i++)
  1005. {
  1006. if (tokens[i] == "^")
  1007. DoTest();
  1008. else if (tokens[i] != "")
  1009. m_compactString.push_back(atol(tokens[i].c_str()));
  1010. }
  1011. }
  1012. else
  1013. {
  1014. 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"))))
  1015. {
  1016. // copy input to output
  1017. std::string output = m_line + '\n';
  1018. AttachedTransformation()->Put((byte *)output.data(), output.size());
  1019. }
  1020. for (unsigned int i = 0; i < tokens.size(); i++)
  1021. {
  1022. if (m_firstLine && m_algorithm != "DSA")
  1023. {
  1024. if (tokens[i] == "Encrypt" || tokens[i] == "OFB")
  1025. SetEncrypt(true);
  1026. else if (tokens[i] == "Decrypt")
  1027. SetEncrypt(false);
  1028. else if (tokens[i] == "Modes")
  1029. m_test = "MONTE";
  1030. }
  1031. else
  1032. {
  1033. if (tokens[i] != "=")
  1034. continue;
  1035. if (i == 0)
  1036. throw Exception(Exception::OTHER_ERROR, "TestDataParser: unexpected data: " + m_line);
  1037. const std::string &key = tokens[i-1];
  1038. std::string &data = m_data[key];
  1039. data = (tokens.size() > i+1) ? tokens[i+1] : "";
  1040. DataType t = m_nameToType[key];
  1041. m_typeToName[t] = key;
  1042. m_data2[t] = DecodeHex(data);
  1043. if (key == m_trigger || (t == OUTPUT && !m_data2[INPUT].empty() && !isspace(m_line[0])))
  1044. DoTest();
  1045. }
  1046. }
  1047. }
  1048. m_firstLine = false;
  1049. return false;
  1050. }
  1051. inline const SecByteBlock & GetData(const std::string &key)
  1052. {
  1053. return m_data2[m_nameToType[key]];
  1054. }
  1055. static SecByteBlock DecodeHex(const std::string &data)
  1056. {
  1057. SecByteBlock data2(data.size() / 2);
  1058. StringSource(data, true, new HexDecoder(new ArraySink(data2, data2.size())));
  1059. return data2;
  1060. }
  1061. std::string m_algorithm, m_test, m_mode, m_line, m_bracketString, m_trigger;
  1062. unsigned int m_feedbackSize, m_blankLineTransition;
  1063. bool m_encrypt, m_firstLine;
  1064. typedef std::map<std::string, DataType> NameToTypeMap;
  1065. NameToTypeMap m_nameToType;
  1066. typedef std::map<DataType, std::string> TypeToNameMap;
  1067. TypeToNameMap m_typeToName;
  1068. typedef std::map<std::string, std::string> Map;
  1069. Map m_data; // raw data
  1070. typedef std::map<DataType, SecByteBlock> Map2;
  1071. Map2 m_data2;
  1072. int m_count;
  1073. AutoSeededX917RNG<AES> m_rng;
  1074. std::vector<unsigned int> m_compactString;
  1075. };
  1076. int FIPS_140_AlgorithmTest(int argc, char **argv)
  1077. {
  1078. argc--;
  1079. argv++;
  1080. std::string algorithm = argv[1];
  1081. std::string pathname = argv[2];
  1082. unsigned int i = pathname.find_last_of("\\/");
  1083. std::string filename = pathname.substr(i == std::string::npos ? 0 : i+1);
  1084. std::string dirname = pathname.substr(0, i);
  1085. if (algorithm == "auto")
  1086. {
  1087. string algTable[] = {"AES", "ECDSA", "DSA", "HMAC", "RNG", "RSA", "TDES", "SKIPJACK", "SHA"}; // order is important here
  1088. for (i=0; i<sizeof(algTable)/sizeof(algTable[0]); i++)
  1089. {
  1090. if (dirname.find(algTable[i]) != std::string::npos)
  1091. {
  1092. algorithm = algTable[i];
  1093. break;
  1094. }
  1095. }
  1096. }
  1097. try
  1098. {
  1099. std::string mode;
  1100. if (algorithm == "SHA")
  1101. mode = IntToString(atol(filename.substr(3, 3).c_str()));
  1102. else if (algorithm == "RSA")
  1103. mode = filename.substr(6, 1);
  1104. else if (filename[0] == 'S' || filename[0] == 'T')
  1105. mode = filename.substr(1, 3);
  1106. else
  1107. mode = filename.substr(0, 3);
  1108. for (i = 0; i<mode.size(); i++)
  1109. mode[i] = toupper(mode[i]);
  1110. unsigned int feedbackSize = mode == "CFB" ? atoi(filename.substr(filename.find_first_of("0123456789")).c_str()) : 0;
  1111. std::string test;
  1112. if (algorithm == "DSA" || algorithm == "ECDSA")
  1113. test = filename.substr(0, filename.size() - 4);
  1114. else if (algorithm == "RSA")
  1115. test = filename.substr(3, 3);
  1116. else if (filename.find("Monte") != std::string::npos)
  1117. test = "MONTE";
  1118. else if (filename.find("MCT") != std::string::npos)
  1119. test = "MCT";
  1120. else
  1121. test = "KAT";
  1122. bool encrypt = (filename.find("vrct") == std::string::npos);
  1123. BufferedTransformation *pSink = NULL;
  1124. if (argc > 3)
  1125. {
  1126. std::string outDir = argv[3];
  1127. if (outDir == "auto")
  1128. {
  1129. if (dirname.substr(dirname.size()-3) == "req")
  1130. outDir = dirname.substr(0, dirname.size()-3) + "resp";
  1131. }
  1132. if (*outDir.rbegin() != '\\' && *outDir.rbegin() != '/')
  1133. outDir += '/';
  1134. std::string outPathname = outDir + filename.substr(0, filename.size() - 3) + "rsp";
  1135. pSink = new FileSink(outPathname.c_str(), false);
  1136. }
  1137. else
  1138. pSink = new FileSink(cout);
  1139. FileSource(pathname.c_str(), true, new LineBreakParser(new TestDataParser(algorithm, test, mode, feedbackSize, encrypt, pSink)), false);
  1140. }
  1141. catch (...)
  1142. {
  1143. cout << "file: " << filename << endl;
  1144. throw;
  1145. }
  1146. return 0;
  1147. }
  1148. extern int (*AdhocTest)(int argc, char *argv[]);
  1149. static int s_i = (AdhocTest = &FIPS_140_AlgorithmTest, 0);
  1150. #endif