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