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