Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Class Members | File Members

fipsalgt.cpp

00001 // fipsalgt.cpp - written and placed in the public domain by Wei Dai 00002 00003 // This file implements the various algorithm tests needed to pass FIPS 140 validation. 00004 // They're preserved here (commented out) in case Crypto++ needs to be revalidated. 00005 00006 #if 0 00007 #include "dll.h" 00008 00009 USING_NAMESPACE(CryptoPP) 00010 USING_NAMESPACE(std) 00011 00012 class LineBreakParser : public AutoSignaling<Bufferless<Filter> > 00013 { 00014 public: 00015 LineBreakParser(BufferedTransformation *attachment=NULL, byte lineEnd='\n') 00016 : AutoSignaling<Bufferless<Filter> >(attachment), m_lineEnd(lineEnd) {} 00017 00018 unsigned int Put2(const byte *begin, unsigned int length, int messageEnd, bool blocking) 00019 { 00020 if (!blocking) 00021 throw BlockingInputOnly("LineBreakParser"); 00022 00023 unsigned int i, last = 0; 00024 for (i=0; i<length; i++) 00025 { 00026 if (begin[i] == m_lineEnd) 00027 { 00028 AttachedTransformation()->Put2(begin+last, i-last, GetAutoSignalPropagation(), blocking); 00029 last = i+1; 00030 } 00031 } 00032 if (last != i) 00033 AttachedTransformation()->Put2(begin+last, i-last, 0, blocking); 00034 00035 if (messageEnd && GetAutoSignalPropagation()) 00036 { 00037 AttachedTransformation()->MessageEnd(GetAutoSignalPropagation()-1, blocking); 00038 AttachedTransformation()->MessageSeriesEnd(GetAutoSignalPropagation()-1, blocking); 00039 } 00040 00041 return 0; 00042 } 00043 00044 private: 00045 byte m_lineEnd; 00046 }; 00047 00048 class TestDataParser : public Unflushable<FilterWithInputQueue> 00049 { 00050 public: 00051 enum DataType {OTHER, COUNT, KEY_T, IV, INPUT, OUTPUT}; 00052 00053 TestDataParser(std::string algorithm, std::string test, std::string mode, unsigned int feedbackSize, bool encrypt, BufferedTransformation *attachment) 00054 : Unflushable<FilterWithInputQueue>(attachment) 00055 , m_algorithm(algorithm), m_test(test), m_mode(mode), m_feedbackSize(feedbackSize) 00056 , m_firstLine(true), m_blankLineTransition(0) 00057 { 00058 m_nameToType["COUNT"] = COUNT; 00059 m_nameToType["KEY"] = KEY_T; 00060 m_nameToType["KEYs"] = KEY_T; 00061 m_nameToType["key"] = KEY_T; 00062 m_nameToType["IV"] = IV; 00063 m_nameToType["IV1"] = IV; 00064 m_nameToType["CV"] = IV; 00065 m_nameToType["CV1"] = IV; 00066 m_nameToType["IB"] = IV; 00067 m_nameToType["TEXT"] = INPUT; 00068 m_nameToType["RESULT"] = OUTPUT; 00069 SetEncrypt(encrypt); 00070 00071 if (m_algorithm == "DSS") 00072 { 00073 if (m_test == "prime") 00074 m_trigger = "Prime"; 00075 else if (m_test == "pqg") 00076 m_trigger = "N"; 00077 else if (m_test == "xy") 00078 m_trigger = "G"; 00079 else if (m_test == "gensig") 00080 m_trigger = "Msg"; 00081 else if (m_test == "versig") 00082 m_trigger = "Sig"; 00083 else if (m_test == "verpqg") 00084 m_trigger = "c"; 00085 } 00086 } 00087 00088 void SetEncrypt(bool encrypt) 00089 { 00090 m_encrypt = encrypt; 00091 if (encrypt) 00092 { 00093 m_nameToType["PLAINTEXT"] = INPUT; 00094 m_nameToType["CIPHERTEXT"] = OUTPUT; 00095 m_nameToType["PT"] = INPUT; 00096 m_nameToType["CT"] = OUTPUT; 00097 } 00098 else 00099 { 00100 m_nameToType["PLAINTEXT"] = OUTPUT; 00101 m_nameToType["CIPHERTEXT"] = INPUT; 00102 m_nameToType["PT"] = OUTPUT; 00103 m_nameToType["CT"] = INPUT; 00104 } 00105 00106 if (m_algorithm == "AES") 00107 { 00108 if (encrypt) 00109 { 00110 m_trigger = "PLAINTEXT"; 00111 m_typeToName[OUTPUT] = "CIPHERTEXT"; 00112 } 00113 else 00114 { 00115 m_trigger = "CIPHERTEXT"; 00116 m_typeToName[OUTPUT] = "PLAINTEXT"; 00117 } 00118 m_count = 0; 00119 } 00120 } 00121 00122 protected: 00123 void OutputData(std::string &output, const std::string &key, const std::string &data) 00124 { 00125 output += key; 00126 output += "= "; 00127 output += data; 00128 output += "\n"; 00129 } 00130 00131 void OutputData(std::string &output, const std::string &key, int data) 00132 { 00133 OutputData(output, key, IntToString(data)); 00134 } 00135 00136 void OutputData(std::string &output, const std::string &key, const SecByteBlock &data) 00137 { 00138 output += key; 00139 output += "= "; 00140 HexEncoder(new StringSink(output), false).Put(data, data.size()); 00141 output += "\n"; 00142 } 00143 00144 void OutputData(std::string &output, const std::string &key, const Integer &data) 00145 { 00146 SecByteBlock s(data.MinEncodedSize()); 00147 data.Encode(s, s.size()); 00148 OutputData(output, key, s); 00149 } 00150 00151 void OutputData(std::string &output, DataType t, const std::string &data) 00152 { 00153 if (m_algorithm == "SKIPJACK") 00154 { 00155 if (m_test == "KAT") 00156 { 00157 if (t == OUTPUT) 00158 output = m_line + data + "\n"; 00159 } 00160 else 00161 { 00162 if (t != COUNT) 00163 { 00164 output += m_typeToName[t]; 00165 output += "="; 00166 } 00167 output += data; 00168 output += t == OUTPUT ? "\n" : " "; 00169 } 00170 } 00171 else if (m_algorithm == "TDES" && t == KEY_T && m_typeToName[KEY_T].empty()) 00172 { 00173 output += "KEY1 = "; 00174 output += data.substr(0, 16); 00175 output += "\nKEY2 = "; 00176 output += data.size() > 16 ? data.substr(16, 16) : data.substr(0, 16); 00177 output += "\nKEY3 = "; 00178 output += data.size() > 32 ? data.substr(32, 16) : data.substr(0, 16); 00179 output += "\n"; 00180 } 00181 else 00182 { 00183 output += m_typeToName[t]; 00184 output += " = "; 00185 output += data; 00186 output += "\n"; 00187 } 00188 } 00189 00190 void OutputData(std::string &output, DataType t, int i) 00191 { 00192 OutputData(output, t, IntToString(i)); 00193 } 00194 00195 void OutputData(std::string &output, DataType t, const SecByteBlock &data) 00196 { 00197 std::string hexData; 00198 StringSource(data.begin(), data.size(), true, new HexEncoder(new StringSink(hexData), false)); 00199 OutputData(output, t, hexData); 00200 } 00201 00202 void OutputGivenData(std::string &output, DataType t, bool optional = false) 00203 { 00204 if (m_data.find(m_typeToName[t]) == m_data.end()) 00205 { 00206 if (optional) 00207 return; 00208 throw Exception(Exception::OTHER_ERROR, "TestDataParser: key not found: " + m_typeToName[t]); 00209 } 00210 00211 OutputData(output, t, m_data[m_typeToName[t]]); 00212 } 00213 00214 template <class T> 00215 BlockCipher * NewBT(T *) 00216 { 00217 if (!m_encrypt && (m_mode == "ECB" || m_mode == "CBC")) 00218 return new typename T::Decryption; 00219 else 00220 return new typename T::Encryption; 00221 } 00222 00223 template <class T> 00224 SymmetricCipher * NewMode(T *, BlockCipher &bt, const byte *iv) 00225 { 00226 if (!m_encrypt) 00227 return new typename T::Decryption(bt, iv, m_feedbackSize/8); 00228 else 00229 return new typename T::Encryption(bt, iv, m_feedbackSize/8); 00230 } 00231 00232 static inline void Xor(SecByteBlock &z, const SecByteBlock &x, const SecByteBlock &y) 00233 { 00234 assert(x.size() == y.size()); 00235 z.resize(x.size()); 00236 xorbuf(z, x, y, x.size()); 00237 } 00238 00239 SecByteBlock UpdateKey(SecByteBlock key, const SecByteBlock *text) 00240 { 00241 unsigned int innerCount = (m_algorithm == "AES") ? 1000 : 10000; 00242 int keySize = key.size(), blockSize = text[0].size(); 00243 SecByteBlock x(keySize); 00244 for (int k=0; k<keySize;) 00245 { 00246 int pos = innerCount * blockSize - keySize + k; 00247 memcpy(x + k, text[pos / blockSize] + pos % blockSize, blockSize - pos % blockSize); 00248 k += blockSize - pos % blockSize; 00249 } 00250 00251 if (m_algorithm == "TDES" || m_algorithm == "DES") 00252 { 00253 for (int i=0; i<keySize; i+=8) 00254 { 00255 xorbuf(key+i, x+keySize-8-i, 8); 00256 DES::CorrectKeyParityBits(key+i); 00257 } 00258 } 00259 else 00260 xorbuf(key, x, keySize); 00261 00262 return key; 00263 } 00264 00265 static inline void AssignLeftMostBits(SecByteBlock &z, const SecByteBlock &x, unsigned int K) 00266 { 00267 z.Assign(x, K/8); 00268 } 00269 00270 virtual void DoTest() 00271 { 00272 std::string output; 00273 00274 if (m_algorithm == "DSS") 00275 { 00276 if (m_test == "sha") 00277 { 00278 assert(m_compactString.size() >= 2); 00279 assert(m_compactString[0] == m_compactString.size()-2); 00280 bool b = !!m_compactString[1]; 00281 Integer m; 00282 unsigned int bitLength = 0; 00283 00284 for (unsigned int j = 2; j < m_compactString.size(); j++) 00285 { 00286 m <<= m_compactString[j]; 00287 for (unsigned int k = 0; k < m_compactString[j]; k++) 00288 m.SetBit(k, b); 00289 bitLength += m_compactString[j]; 00290 b = !b; 00291 } 00292 m_compactString.clear(); 00293 assert(bitLength % 8 == 0); 00294 00295 SecByteBlock message(bitLength / 8); 00296 m.Encode(message, message.size()); 00297 SHA sha; 00298 00299 if (m_bracketString == "SHS Type 3 Strings") 00300 { 00301 SecByteBlock m1; 00302 for (int j = 0; j < 100; j++) 00303 { 00304 for (word32 i = 1; i <= 50000; i++) 00305 { 00306 m1.resize(message.size() + j/4 + 3 + 4); 00307 memcpy(m1, message, message.size()); 00308 memset(m1 + message.size(), 0, j/4 + 3); 00309 PutWord(false, BIG_ENDIAN_ORDER, m1 + m1.size() - 4, i); 00310 message.resize(sha.DigestSize()); 00311 sha.CalculateDigest(message, m1, m1.size()); 00312 } 00313 StringSource(message, message.size(), true, new HexEncoder(new StringSink(output))); 00314 output += " ^\n"; 00315 AttachedTransformation()->Put((byte *)output.data(), output.size()); 00316 output.resize(0); 00317 } 00318 } 00319 else 00320 { 00321 StringSource(message, message.size(), true, new HashFilter(sha, new HexEncoder(new StringSink(output)))); 00322 output += " ^\n"; 00323 AttachedTransformation()->Put((byte *)output.data(), output.size()); 00324 } 00325 } 00326 else if (m_test == "prime") 00327 { 00328 Integer p((m_data["Prime"] + "h").c_str()); 00329 OutputData(output, "result", VerifyPrime(m_rng, p, 2) ? "P" : "F"); 00330 AttachedTransformation()->Put((byte *)output.data(), output.size()); 00331 output.resize(0); 00332 } 00333 else if (m_test == "pqg") 00334 { 00335 int n = atol(m_data["N"].c_str()); 00336 for (int i=0; i<n; i++) 00337 { 00338 Integer p, q, h, g; 00339 int counter; 00340 00341 SecByteBlock seed(SHA::DIGESTSIZE); 00342 do 00343 { 00344 m_rng.GenerateBlock(seed, seed.size()); 00345 } 00346 while (!DSA::GeneratePrimes(seed, seed.size()*8, counter, p, 1024, q)); 00347 h.Randomize(m_rng, 2, p-2); 00348 g = a_exp_b_mod_c(h, (p-1)/q, p); 00349 00350 OutputData(output, "P", p); 00351 OutputData(output, "Q", q); 00352 OutputData(output, "G", g); 00353 OutputData(output, "Seed", seed); 00354 OutputData(output, "H", h); 00355 OutputData(output, "c", counter); 00356 AttachedTransformation()->Put((byte *)output.data(), output.size()); 00357 output.resize(0); 00358 } 00359 } 00360 else if (m_test == "xy") 00361 { 00362 Integer p((m_data["P"] + "h").c_str()); 00363 Integer q((m_data["Q"] + "h").c_str()); 00364 Integer g((m_data["G"] + "h").c_str()); 00365 00366 for (int i=0; i<10; i++) 00367 { 00368 DSA::Signer priv(m_rng, p, q, g); 00369 DSA::Verifier pub(priv); 00370 00371 OutputData(output, "X", priv.GetKey().GetPrivateExponent()); 00372 OutputData(output, "Y", pub.GetKey().GetPublicElement()); 00373 AttachedTransformation()->Put((byte *)output.data(), output.size()); 00374 output.resize(0); 00375 } 00376 } 00377 else if (m_test == "gensig") 00378 { 00379 Integer p((m_data["P"] + "h").c_str()); 00380 Integer q((m_data["Q"] + "h").c_str()); 00381 Integer g((m_data["G"] + "h").c_str()); 00382 Integer x((m_data["X"] + "h").c_str()); 00383 DSA::Signer signer(p, q, g, x); 00384 00385 SecByteBlock sig(signer.SignatureLength()); 00386 StringSource(m_data["Msg"], true, new HexDecoder(new SignerFilter(m_rng, signer, new ArraySink(sig, sig.size())))); 00387 OutputData(output, "Sig", sig); 00388 AttachedTransformation()->Put((byte *)output.data(), output.size()); 00389 output.resize(0); 00390 } 00391 else if (m_test == "versig") 00392 { 00393 Integer p((m_data["P"] + "h").c_str()); 00394 Integer q((m_data["Q"] + "h").c_str()); 00395 Integer g((m_data["G"] + "h").c_str()); 00396 Integer y((m_data["Y"] + "h").c_str()); 00397 DSA::Verifier verifier(p, q, g, y); 00398 00399 HexDecoder filter(new SignatureVerificationFilter(verifier)); 00400 StringSource(m_data["Sig"], true, new Redirector(filter, false)); 00401 StringSource(m_data["Msg"], true, new Redirector(filter, false)); 00402 filter.MessageEnd(); 00403 byte b; 00404 filter.Get(b); 00405 OutputData(output, "result", b ? "P" : "F"); 00406 AttachedTransformation()->Put((byte *)output.data(), output.size()); 00407 output.resize(0); 00408 } 00409 else if (m_test == "verpqg") 00410 { 00411 Integer p((m_data["P"] + "h").c_str()); 00412 Integer q((m_data["Q"] + "h").c_str()); 00413 Integer g((m_data["G"] + "h").c_str()); 00414 Integer h((m_data["H"] + "h").c_str()); 00415 int c = atol(m_data["c"].c_str()); 00416 SecByteBlock seed(m_data["Seed"].size()/2); 00417 StringSource(m_data["Seed"], true, new HexDecoder(new ArraySink(seed, seed.size()))); 00418 00419 Integer p1, q1; 00420 bool result = DSA::GeneratePrimes(seed, seed.size()*8, c, p1, 1024, q1, true); 00421 result = result && (p1 == p && q1 == q); 00422 result = result && g == a_exp_b_mod_c(h, (p-1)/q, p); 00423 00424 OutputData(output, "result", result ? "P" : "F"); 00425 AttachedTransformation()->Put((byte *)output.data(), output.size()); 00426 output.resize(0); 00427 } 00428 00429 return; 00430 } 00431 00432 SecByteBlock &key = m_data2[KEY_T]; 00433 00434 if (m_algorithm == "TDES") 00435 { 00436 if (!m_data["KEY1"].empty()) 00437 { 00438 const std::string keys[3] = {m_data["KEY1"], m_data["KEY2"], m_data["KEY3"]}; 00439 key.resize(24); 00440 HexDecoder hexDec(new ArraySink(key, key.size())); 00441 for (int i=0; i<3; i++) 00442 hexDec.Put((byte *)keys[i].data(), keys[i].size()); 00443 00444 if (keys[0] == keys[2]) 00445 { 00446 if (keys[0] == keys[1]) 00447 key.resize(8); 00448 else 00449 key.resize(16); 00450 } 00451 else 00452 key.resize(24); 00453 } 00454 } 00455 00456 member_ptr<BlockCipher> pBT; 00457 if (m_algorithm == "DES") 00458 pBT.reset(NewBT((DES*)0)); 00459 else if (m_algorithm == "TDES") 00460 { 00461 if (key.size() == 8) 00462 pBT.reset(NewBT((DES*)0)); 00463 else if (key.size() == 16) 00464 pBT.reset(NewBT((DES_EDE2*)0)); 00465 else 00466 pBT.reset(NewBT((DES_EDE3*)0)); 00467 } 00468 else if (m_algorithm == "SKIPJACK") 00469 pBT.reset(NewBT((SKIPJACK*)0)); 00470 else if (m_algorithm == "AES") 00471 pBT.reset(NewBT((AES*)0)); 00472 else 00473 throw Exception(Exception::OTHER_ERROR, "TestDataParser: unexpected algorithm: " + m_algorithm); 00474 00475 if (!pBT->IsValidKeyLength(key.size())) 00476 key.CleanNew(pBT->DefaultKeyLength()); // for Scbcvrct 00477 pBT->SetKey(key.data(), key.size()); 00478 00479 SecByteBlock &iv = m_data2[IV]; 00480 if (iv.empty()) 00481 iv.CleanNew(pBT->BlockSize()); 00482 00483 member_ptr<SymmetricCipher> pCipher; 00484 unsigned int K = m_feedbackSize; 00485 00486 if (m_mode == "ECB") 00487 pCipher.reset(NewMode((ECB_Mode_ExternalCipher*)0, *pBT, iv)); 00488 else if (m_mode == "CBC") 00489 pCipher.reset(NewMode((CBC_Mode_ExternalCipher*)0, *pBT, iv)); 00490 else if (m_mode == "CFB") 00491 pCipher.reset(NewMode((CFB_Mode_ExternalCipher*)0, *pBT, iv)); 00492 else if (m_mode == "OFB") 00493 pCipher.reset(NewMode((OFB_Mode_ExternalCipher*)0, *pBT, iv)); 00494 else 00495 throw Exception(Exception::OTHER_ERROR, "TestDataParser: unexpected mode: " + m_mode); 00496 00497 bool encrypt = m_encrypt; 00498 00499 if (m_test == "MONTE") 00500 { 00501 SecByteBlock KEY[401]; 00502 KEY[0] = key; 00503 int keySize = key.size(); 00504 int blockSize = pBT->BlockSize(); 00505 00506 SecByteBlock IB[10001], OB[10001], PT[10001], CT[10001], RESULT[10001], TXT[10001], CV[10001]; 00507 PT[0] = GetData("PLAINTEXT"); 00508 CT[0] = GetData("CIPHERTEXT"); 00509 CV[0] = IB[0] = iv; 00510 TXT[0] = GetData("TEXT"); 00511 00512 unsigned int outerCount = (m_algorithm == "AES") ? 100 : 400; 00513 unsigned int innerCount = (m_algorithm == "AES") ? 1000 : 10000; 00514 00515 for (int i=0; i<outerCount; i++) 00516 { 00517 pBT->SetKey(KEY[i], keySize); 00518 00519 for (int j=0; j<innerCount; j++) 00520 { 00521 if (m_mode == "ECB") 00522 { 00523 if (encrypt) 00524 { 00525 IB[j] = PT[j]; 00526 CT[j].resize(blockSize); 00527 pBT->ProcessBlock(IB[j], CT[j]); 00528 PT[j+1] = CT[j]; 00529 } 00530 else 00531 { 00532 IB[j] = CT[j]; 00533 PT[j].resize(blockSize); 00534 pBT->ProcessBlock(IB[j], PT[j]); 00535 CT[j+1] = PT[j]; 00536 } 00537 } 00538 else if (m_mode == "OFB") 00539 { 00540 OB[j].resize(blockSize); 00541 pBT->ProcessBlock(IB[j], OB[j]); 00542 Xor(RESULT[j], OB[j], TXT[j]); 00543 TXT[j+1] = IB[j]; 00544 IB[j+1] = OB[j]; 00545 } 00546 else if (m_mode == "CBC") 00547 { 00548 if (encrypt) 00549 { 00550 Xor(IB[j], PT[j], CV[j]); 00551 CT[j].resize(blockSize); 00552 pBT->ProcessBlock(IB[j], CT[j]); 00553 PT[j+1] = CV[j]; 00554 CV[j+1] = CT[j]; 00555 } 00556 else 00557 { 00558 IB[j] = CT[j]; 00559 OB[j].resize(blockSize); 00560 pBT->ProcessBlock(IB[j], OB[j]); 00561 Xor(PT[j], OB[j], CV[j]); 00562 CV[j+1] = CT[j]; 00563 CT[j+1] = PT[j]; 00564 } 00565 } 00566 else if (m_mode == "CFB") 00567 { 00568 if (encrypt) 00569 { 00570 OB[j].resize(blockSize); 00571 pBT->ProcessBlock(IB[j], OB[j]); 00572 AssignLeftMostBits(CT[j], OB[j], K); 00573 Xor(CT[j], CT[j], PT[j]); 00574 AssignLeftMostBits(PT[j+1], IB[j], K); 00575 IB[j+1].resize(blockSize); 00576 memcpy(IB[j+1], IB[j]+K/8, blockSize-K/8); 00577 memcpy(IB[j+1]+blockSize-K/8, CT[j], K/8); 00578 } 00579 else 00580 { 00581 OB[j].resize(blockSize); 00582 pBT->ProcessBlock(IB[j], OB[j]); 00583 AssignLeftMostBits(PT[j], OB[j], K); 00584 Xor(PT[j], PT[j], CT[j]); 00585 IB[j+1].resize(blockSize); 00586 memcpy(IB[j+1], IB[j]+K/8, blockSize-K/8); 00587 memcpy(IB[j+1]+blockSize-K/8, CT[j], K/8); 00588 AssignLeftMostBits(CT[j+1], OB[j], K); 00589 } 00590 } 00591 else 00592 throw Exception(Exception::OTHER_ERROR, "TestDataParser: unexpected mode: " + m_mode); 00593 } 00594 00595 OutputData(output, COUNT, i); 00596 OutputData(output, KEY_T, KEY[i]); 00597 if (m_mode == "CBC") 00598 OutputData(output, IV, CV[0]); 00599 if (m_mode == "OFB" || m_mode == "CFB") 00600 OutputData(output, IV, IB[0]); 00601 if (m_mode == "ECB" || m_mode == "CBC" || m_mode == "CFB") 00602 { 00603 if (encrypt) 00604 { 00605 OutputData(output, INPUT, PT[0]); 00606 OutputData(output, OUTPUT, CT[innerCount-1]); 00607 KEY[i+1] = UpdateKey(KEY[i], CT); 00608 } 00609 else 00610 { 00611 OutputData(output, INPUT, CT[0]); 00612 OutputData(output, OUTPUT, PT[innerCount-1]); 00613 KEY[i+1] = UpdateKey(KEY[i], PT); 00614 } 00615 PT[0] = PT[innerCount]; 00616 IB[0] = IB[innerCount]; 00617 CV[0] = CV[innerCount]; 00618 CT[0] = CT[innerCount]; 00619 } 00620 else if (m_mode == "OFB") 00621 { 00622 OutputData(output, INPUT, TXT[0]); 00623 OutputData(output, OUTPUT, RESULT[innerCount-1]); 00624 KEY[i+1] = UpdateKey(KEY[i], RESULT); 00625 Xor(TXT[0], TXT[0], IB[innerCount-1]); 00626 IB[0] = OB[innerCount-1]; 00627 } 00628 output += "\n"; 00629 AttachedTransformation()->Put((byte *)output.data(), output.size()); 00630 output.resize(0); 00631 } 00632 } 00633 else if (m_test == "MCT") 00634 { 00635 SecByteBlock KEY[101]; 00636 KEY[0] = key; 00637 int keySize = key.size(); 00638 int blockSize = pBT->BlockSize(); 00639 00640 SecByteBlock ivs[101], inputs[1001], outputs[1001]; 00641 ivs[0] = iv; 00642 inputs[0] = m_data2[INPUT]; 00643 00644 for (int i=0; i<100; i++) 00645 { 00646 pCipher->SetKey(KEY[i], keySize, MakeParameters(Name::IV(), (const byte *)ivs[i])(Name::FeedbackSize(), (int)K/8)); 00647 00648 for (int j=0; j<1000; j++) 00649 { 00650 outputs[j] = inputs[j]; 00651 pCipher->ProcessString(outputs[j], outputs[j].size()); 00652 if (K==8 && m_mode == "CFB") 00653 { 00654 if (j<16) 00655 inputs[j+1].Assign(ivs[i]+j, 1); 00656 else 00657 inputs[j+1] = outputs[j-16]; 00658 } 00659 else if (m_mode == "ECB") 00660 inputs[j+1] = outputs[j]; 00661 else if (j == 0) 00662 inputs[j+1] = ivs[i]; 00663 else 00664 inputs[j+1] = outputs[j-1]; 00665 } 00666 00667 if (m_algorithm == "AES") 00668 OutputData(output, COUNT, m_count++); 00669 OutputData(output, KEY_T, KEY[i]); 00670 if (m_mode != "ECB") 00671 OutputData(output, IV, ivs[i]); 00672 OutputData(output, INPUT, inputs[0]); 00673 OutputData(output, OUTPUT, outputs[999]); 00674 output += "\n"; 00675 AttachedTransformation()->Put((byte *)output.data(), output.size()); 00676 output.resize(0); 00677 00678 KEY[i+1] = UpdateKey(KEY[i], outputs); 00679 ivs[i+1].CleanNew(pCipher->IVSize()); 00680 ivs[i+1] = UpdateKey(ivs[i+1], outputs); 00681 if (K==8 && m_mode == "CFB") 00682 inputs[0] = outputs[999-16]; 00683 else if (m_mode == "ECB") 00684 inputs[0] = outputs[999]; 00685 else 00686 inputs[0] = outputs[998]; 00687 } 00688 } 00689 else 00690 { 00691 assert(m_test == "KAT"); 00692 00693 SecByteBlock &input = m_data2[INPUT]; 00694 SecByteBlock result(input.size()); 00695 member_ptr<Filter> pFilter(new StreamTransformationFilter(*pCipher, new ArraySink(result, result.size()), StreamTransformationFilter::NO_PADDING)); 00696 StringSource(input.data(), input.size(), true, pFilter.release()); 00697 00698 OutputGivenData(output, COUNT, true); 00699 OutputData(output, KEY_T, key); 00700 OutputGivenData(output, IV, true); 00701 OutputGivenData(output, INPUT); 00702 OutputData(output, OUTPUT, result); 00703 output += "\n"; 00704 AttachedTransformation()->Put((byte *)output.data(), output.size()); 00705 } 00706 } 00707 00708 std::vector<std::string> Tokenize(const std::string &line) 00709 { 00710 std::vector<std::string> result; 00711 std::string s; 00712 for (int i=0; i<line.size(); i++) 00713 { 00714 if (isalnum(line[i]) || line[i] == '^') 00715 s += line[i]; 00716 else if (!s.empty()) 00717 { 00718 result.push_back(s); 00719 s = ""; 00720 } 00721 if (line[i] == '=') 00722 result.push_back("="); 00723 } 00724 result.push_back(s); 00725 return result; 00726 } 00727 00728 bool IsolatedMessageEnd(bool blocking) 00729 { 00730 if (!blocking) 00731 throw BlockingInputOnly("TestDataParser"); 00732 00733 m_line.resize(0); 00734 m_inQueue.TransferTo(StringSink(m_line).Ref()); 00735 00736 if (m_line[0] == '#') 00737 return false; 00738 00739 bool copyLine = false; 00740 00741 if (m_line[0] == '[') 00742 { 00743 m_bracketString = m_line.substr(1, m_line.size()-2); 00744 if (m_bracketString == "ENCRYPT") 00745 SetEncrypt(true); 00746 if (m_bracketString == "DECRYPT") 00747 SetEncrypt(false); 00748 copyLine = true; 00749 } 00750 00751 if (m_line.substr(0, 2) == "H>") 00752 { 00753 assert(m_test == "sha"); 00754 m_bracketString = m_line.substr(2, m_line.size()-4); 00755 m_line = m_line.substr(0, 13) + "Hashes<H"; 00756 copyLine = true; 00757 } 00758 00759 if (m_line == "D>") 00760 copyLine = true; 00761 00762 if (m_line == "<D") 00763 { 00764 m_line += "\n"; 00765 copyLine = true; 00766 } 00767 00768 if (copyLine) 00769 { 00770 m_line += '\n'; 00771 AttachedTransformation()->Put((byte *)m_line.data(), m_line.size(), blocking); 00772 return false; 00773 } 00774 00775 std::vector<std::string> tokens = Tokenize(m_line); 00776 00777 if (m_algorithm == "DSS" && m_test == "sha") 00778 { 00779 for (int i = 0; i < tokens.size(); i++) 00780 { 00781 if (tokens[i] == "^") 00782 DoTest(); 00783 else if (tokens[i] != "") 00784 m_compactString.push_back(atol(tokens[i].c_str())); 00785 } 00786 } 00787 else 00788 { 00789 if (!m_line.empty() && m_algorithm == "DSS" && m_test != "pqg") 00790 { 00791 std::string output = m_line + '\n'; 00792 AttachedTransformation()->Put((byte *)output.data(), output.size()); 00793 } 00794 00795 for (int i = 0; i < tokens.size(); i++) 00796 { 00797 if (m_firstLine && m_algorithm != "DSS") 00798 { 00799 if (tokens[i] == "Encrypt" || tokens[i] == "OFB") 00800 SetEncrypt(true); 00801 else if (tokens[i] == "Decrypt") 00802 SetEncrypt(false); 00803 else if (tokens[i] == "Modes") 00804 m_test = "MONTE"; 00805 } 00806 else 00807 { 00808 if (tokens[i] != "=") 00809 continue; 00810 00811 if (i == 0) 00812 throw Exception(Exception::OTHER_ERROR, "TestDataParser: unexpected data: " + m_line); 00813 00814 const std::string &key = tokens[i-1]; 00815 std::string &data = m_data[key]; 00816 data = tokens[i+1]; 00817 DataType t = m_nameToType[key]; 00818 m_typeToName[t] = key; 00819 SecByteBlock data2(data.size() / 2); 00820 StringSource(data, true, new HexDecoder(new ArraySink(data2, data2.size()))); 00821 m_data2[t] = data2; 00822 00823 if (key == m_trigger || (t == OUTPUT && !m_data2[INPUT].empty())) 00824 DoTest(); 00825 } 00826 } 00827 } 00828 00829 m_firstLine = false; 00830 00831 return false; 00832 } 00833 00834 inline const SecByteBlock & GetData(const std::string &key) 00835 { 00836 return m_data2[m_nameToType[key]]; 00837 } 00838 00839 std::string m_algorithm, m_test, m_mode, m_line, m_bracketString, m_trigger; 00840 unsigned int m_feedbackSize, m_blankLineTransition; 00841 bool m_encrypt, m_firstLine; 00842 00843 typedef std::map<std::string, DataType> NameToTypeMap; 00844 NameToTypeMap m_nameToType; 00845 typedef std::map<DataType, std::string> TypeToNameMap; 00846 TypeToNameMap m_typeToName; 00847 00848 typedef std::map<std::string, std::string> Map; 00849 Map m_data; // raw data 00850 typedef std::map<DataType, SecByteBlock> Map2; 00851 Map2 m_data2; 00852 int m_count; 00853 00854 AutoSeededX917RNG<DES_EDE3> m_rng; 00855 std::vector<unsigned int> m_compactString; 00856 }; 00857 00858 int main (int argc, char **argv) 00859 { 00860 std::string algorithm = argv[1]; 00861 std::string pathname = argv[2]; 00862 int i = pathname.find_last_of("\\/"); 00863 std::string filename = pathname.substr(i == std::string::npos ? 0 : i+1); 00864 std::string mode; 00865 if (filename[0] == 'S' || filename[0] == 'T') 00866 mode = filename.substr(1, 3); 00867 else 00868 mode = filename.substr(0, 3); 00869 for (i = 0; i<mode.size(); i++) 00870 mode[i] = toupper(mode[i]); 00871 unsigned int feedbackSize = mode == "CFB" ? atoi(filename.substr(filename.find_first_of("0123456789")).c_str()) : 0; 00872 std::string test; 00873 if (algorithm == "DSS") 00874 test = filename.substr(0, filename.size() - 4); 00875 else if (filename.find("Monte") != std::string::npos) 00876 test = "MONTE"; 00877 else if (filename.find("MCT") != std::string::npos) 00878 test = "MCT"; 00879 else 00880 test = "KAT"; 00881 bool encrypt = (filename.find("vrct") == std::string::npos); 00882 00883 BufferedTransformation *pSink = NULL; 00884 00885 if (argc > 3) 00886 { 00887 std::string outDir = argv[3]; 00888 if (*outDir.rbegin() != '\\' && *outDir.rbegin() != '/') 00889 outDir += '/'; 00890 std::string outPathname = outDir + filename.substr(0, filename.size() - 3) + "rsp"; 00891 pSink = new FileSink(outPathname.c_str(), false); 00892 } 00893 else 00894 pSink = new FileSink(cout); 00895 00896 FileSource(pathname.c_str(), true, new LineBreakParser(new TestDataParser(algorithm, test, mode, feedbackSize, encrypt, pSink)), false); 00897 return 0; 00898 } 00899 #endif

Generated on Wed Jul 21 19:15:25 2004 for Crypto++ by doxygen 1.3.7-20040704