📄 fipsalgt.cpp
字号:
// fipsalgt.cpp - written and placed in the public domain by Wei Dai// This file implements the various algorithm tests needed to pass FIPS 140 validation.// They're preserved here (commented out) in case Crypto++ needs to be revalidated.#if 0#ifndef CRYPTOPP_IMPORTS#define CRYPTOPP_DEFAULT_NO_DLL#endif#include "dll.h"#include "oids.h"USING_NAMESPACE(CryptoPP)USING_NAMESPACE(std)class LineBreakParser : public AutoSignaling<Bufferless<Filter> >{public: LineBreakParser(BufferedTransformation *attachment=NULL, byte lineEnd='\n') : m_lineEnd(lineEnd) {Detach(attachment);} size_t Put2(const byte *begin, size_t length, int messageEnd, bool blocking) { if (!blocking) throw BlockingInputOnly("LineBreakParser"); unsigned int i, last = 0; for (i=0; i<length; i++) { if (begin[i] == m_lineEnd) { AttachedTransformation()->Put2(begin+last, i-last, GetAutoSignalPropagation(), blocking); last = i+1; } } if (last != i) AttachedTransformation()->Put2(begin+last, i-last, 0, blocking); if (messageEnd && GetAutoSignalPropagation()) { AttachedTransformation()->MessageEnd(GetAutoSignalPropagation()-1, blocking); AttachedTransformation()->MessageSeriesEnd(GetAutoSignalPropagation()-1, blocking); } return 0; }private: byte m_lineEnd;};class TestDataParser : public Unflushable<FilterWithInputQueue>{public: enum DataType {OTHER, COUNT, KEY_T, IV, INPUT, OUTPUT}; TestDataParser(std::string algorithm, std::string test, std::string mode, unsigned int feedbackSize, bool encrypt, BufferedTransformation *attachment) : m_algorithm(algorithm), m_test(test), m_mode(mode), m_feedbackSize(feedbackSize) , m_firstLine(true), m_blankLineTransition(0) { Detach(attachment); m_typeToName[COUNT] = "COUNT"; m_nameToType["COUNT"] = COUNT; m_nameToType["KEY"] = KEY_T; m_nameToType["KEYs"] = KEY_T; m_nameToType["key"] = KEY_T; m_nameToType["Key"] = KEY_T; m_nameToType["IV"] = IV; m_nameToType["IV1"] = IV; m_nameToType["CV"] = IV; m_nameToType["CV1"] = IV; m_nameToType["IB"] = IV; m_nameToType["TEXT"] = INPUT; m_nameToType["RESULT"] = OUTPUT; m_nameToType["Msg"] = INPUT; m_nameToType["Seed"] = INPUT; m_nameToType["V"] = INPUT; m_nameToType["DT"] = IV; SetEncrypt(encrypt); if (m_algorithm == "DSA" || m_algorithm == "ECDSA") { if (m_test == "PKV") m_trigger = "Qy"; else if (m_test == "KeyPair") m_trigger = "N"; else if (m_test == "SigGen") m_trigger = "Msg"; else if (m_test == "SigVer") m_trigger = "S"; else if (m_test == "PQGGen") m_trigger = "N"; else if (m_test == "PQGVer") m_trigger = "H"; } else if (m_algorithm == "HMAC") m_trigger = "Msg"; else if (m_algorithm == "SHA") m_trigger = (m_test == "MONTE") ? "Seed" : "Msg"; else if (m_algorithm == "RNG") m_trigger = "V"; else if (m_algorithm == "RSA") m_trigger = (m_test == "Ver") ? "S" : "Msg"; } void SetEncrypt(bool encrypt) { m_encrypt = encrypt; if (encrypt) { m_nameToType["PLAINTEXT"] = INPUT; m_nameToType["CIPHERTEXT"] = OUTPUT; m_nameToType["PT"] = INPUT; m_nameToType["CT"] = OUTPUT; } else { m_nameToType["PLAINTEXT"] = OUTPUT; m_nameToType["CIPHERTEXT"] = INPUT; m_nameToType["PT"] = OUTPUT; m_nameToType["CT"] = INPUT; } if (m_algorithm == "AES" || m_algorithm == "TDES") { if (encrypt) { m_trigger = "PLAINTEXT"; m_typeToName[OUTPUT] = "CIPHERTEXT"; } else { m_trigger = "CIPHERTEXT"; m_typeToName[OUTPUT] = "PLAINTEXT"; } m_count = 0; } }protected: void OutputData(std::string &output, const std::string &key, const std::string &data) { output += key; output += "= "; output += data; output += "\n"; } void OutputData(std::string &output, const std::string &key, int data) { OutputData(output, key, IntToString(data)); } void OutputData(std::string &output, const std::string &key, const SecByteBlock &data) { output += key; output += "= "; HexEncoder(new StringSink(output), false).Put(data, data.size()); output += "\n"; } void OutputData(std::string &output, const std::string &key, const Integer &data, int size=-1) { SecByteBlock s(size < 0 ? data.MinEncodedSize() : size); data.Encode(s, s.size()); OutputData(output, key, s); } void OutputData(std::string &output, const std::string &key, const PolynomialMod2 &data, int size=-1) { SecByteBlock s(size < 0 ? data.MinEncodedSize() : size); data.Encode(s, s.size()); OutputData(output, key, s); } void OutputData(std::string &output, DataType t, const std::string &data) { if (m_algorithm == "SKIPJACK") { if (m_test == "KAT") { if (t == OUTPUT) output = m_line + data + "\n"; } else { if (t != COUNT) { output += m_typeToName[t]; output += "="; } output += data; output += t == OUTPUT ? "\n" : " "; } } else if (m_algorithm == "TDES" && t == KEY_T && m_typeToName[KEY_T].empty()) { output += "KEY1 = "; output += data.substr(0, 16); output += "\nKEY2 = "; output += data.size() > 16 ? data.substr(16, 16) : data.substr(0, 16); output += "\nKEY3 = "; output += data.size() > 32 ? data.substr(32, 16) : data.substr(0, 16); output += "\n"; } else { output += m_typeToName[t]; output += " = "; output += data; output += "\n"; } } void OutputData(std::string &output, DataType t, int i) { OutputData(output, t, IntToString(i)); } void OutputData(std::string &output, DataType t, const SecByteBlock &data) { std::string hexData; StringSource(data.begin(), data.size(), true, new HexEncoder(new StringSink(hexData), false)); OutputData(output, t, hexData); } void OutputGivenData(std::string &output, DataType t, bool optional = false) { if (m_data.find(m_typeToName[t]) == m_data.end()) { if (optional) return; throw Exception(Exception::OTHER_ERROR, "TestDataParser: key not found: " + m_typeToName[t]); } OutputData(output, t, m_data[m_typeToName[t]]); } template <class T> BlockCipher * NewBT(T *) { if (!m_encrypt && (m_mode == "ECB" || m_mode == "CBC")) return new typename T::Decryption; else return new typename T::Encryption; } template <class T> SymmetricCipher * NewMode(T *, BlockCipher &bt, const byte *iv) { if (!m_encrypt) return new typename T::Decryption(bt, iv, m_feedbackSize/8); else return new typename T::Encryption(bt, iv, m_feedbackSize/8); } static inline void Xor(SecByteBlock &z, const SecByteBlock &x, const SecByteBlock &y) { assert(x.size() == y.size()); z.resize(x.size()); xorbuf(z, x, y, x.size()); } SecByteBlock UpdateKey(SecByteBlock key, const SecByteBlock *text) { unsigned int innerCount = (m_algorithm == "AES") ? 1000 : 10000; int keySize = key.size(), blockSize = text[0].size(); SecByteBlock x(keySize); for (int k=0; k<keySize;) { int pos = innerCount * blockSize - keySize + k; memcpy(x + k, text[pos / blockSize] + pos % blockSize, blockSize - pos % blockSize); k += blockSize - pos % blockSize; } if (m_algorithm == "TDES" || m_algorithm == "DES") { for (int i=0; i<keySize; i+=8) { xorbuf(key+i, x+keySize-8-i, 8); DES::CorrectKeyParityBits(key+i); } } else xorbuf(key, x, keySize); return key; } static inline void AssignLeftMostBits(SecByteBlock &z, const SecByteBlock &x, unsigned int K) { z.Assign(x, K/8); } template <class EC> void EC_KeyPair(string &output, int n, const OID &oid) { DL_GroupParameters_EC<EC> params(oid); for (int i=0; i<n; i++) { DL_PrivateKey_EC<EC> priv; DL_PublicKey_EC<EC> pub; priv.Initialize(m_rng, params); priv.MakePublicKey(pub); OutputData(output, "d ", priv.GetPrivateExponent()); OutputData(output, "Qx ", pub.GetPublicElement().x, params.GetCurve().GetField().MaxElementByteLength()); OutputData(output, "Qy ", pub.GetPublicElement().y, params.GetCurve().GetField().MaxElementByteLength()); } } template <class EC> void EC_SigGen(string &output, const OID &oid) { DL_GroupParameters_EC<EC> params(oid); typename ECDSA<EC, SHA1>::PrivateKey priv; typename ECDSA<EC, SHA1>::PublicKey pub; priv.Initialize(m_rng, params); priv.MakePublicKey(pub); typename ECDSA<EC, SHA1>::Signer signer(priv); SecByteBlock sig(signer.SignatureLength()); StringSource(m_data["Msg"], true, new HexDecoder(new SignerFilter(m_rng, signer, new ArraySink(sig, sig.size())))); SecByteBlock R(sig, sig.size()/2), S(sig+sig.size()/2, sig.size()/2); OutputData(output, "Qx ", pub.GetPublicElement().x, params.GetCurve().GetField().MaxElementByteLength()); OutputData(output, "Qy ", pub.GetPublicElement().y, params.GetCurve().GetField().MaxElementByteLength()); OutputData(output, "R ", R); OutputData(output, "S ", S); } template <class EC> void EC_SigVer(string &output, const OID &oid) { SecByteBlock x(DecodeHex(m_data["Qx"])); SecByteBlock y(DecodeHex(m_data["Qy"])); Integer r((m_data["R"]+"h").c_str()); Integer s((m_data["S"]+"h").c_str()); typename EC::FieldElement Qx(x, x.size()); typename EC::FieldElement Qy(y, y.size()); typename EC::Element Q(Qx, Qy); DL_GroupParameters_EC<EC> params(oid); typename ECDSA<EC, SHA1>::PublicKey pub; pub.Initialize(params, Q); typename ECDSA<EC, SHA1>::Verifier verifier(pub); SecByteBlock sig(verifier.SignatureLength()); r.Encode(sig, sig.size()/2); s.Encode(sig+sig.size()/2, sig.size()/2); SignatureVerificationFilter filter(verifier); filter.Put(sig, sig.size()); StringSource(m_data["Msg"], true, new HexDecoder(new Redirector(filter, Redirector::DATA_ONLY))); filter.MessageEnd(); byte b; filter.Get(b); OutputData(output, "Result ", b ? "P" : "F"); } template <class EC> static bool EC_PKV(RandomNumberGenerator &rng, const SecByteBlock &x, const SecByteBlock &y, const OID &oid) { typename EC::FieldElement Qx(x, x.size()); typename EC::FieldElement Qy(y, y.size()); typename EC::Element Q(Qx, Qy); DL_GroupParameters_EC<EC> params(oid); typename ECDSA<EC, SHA1>::PublicKey pub; pub.Initialize(params, Q); return pub.Validate(rng, 3); } template <class H, class Result> Result * CreateRSA2(const std::string &standard) { if (typeid(Result) == typeid(PK_Verifier)) { if (standard == "R") return (Result *) new typename RSASS_ISO<H>::Verifier; else if (standard == "P") return (Result *) new typename RSASS<PSS, H>::Verifier; else if (standard == "1") return (Result *) new typename RSASS<PKCS1v15, H>::Verifier; } else if (typeid(Result) == typeid(PK_Signer)) { if (standard == "R") return (Result *) new typename RSASS_ISO<H>::Signer; else if (standard == "P") return (Result *) new typename RSASS<PSS, H>::Signer; else if (standard == "1") return (Result *) new typename RSASS<PKCS1v15, H>::Signer; } return NULL; } template <class Result> Result * CreateRSA(const std::string &standard, const std::string &hash) { if (hash == "1") return CreateRSA2<SHA1, Result>(standard); else if (hash == "224") return CreateRSA2<SHA224, Result>(standard); else if (hash == "256") return CreateRSA2<SHA256, Result>(standard); else if (hash == "384") return CreateRSA2<SHA384, Result>(standard); else if (hash == "512") return CreateRSA2<SHA512, Result>(standard); else return NULL; } virtual void DoTest() { std::string output; if (m_algorithm == "DSA") { if (m_test == "KeyPair") { DL_GroupParameters_DSA pqg; int modLen = atol(m_bracketString.substr(6).c_str()); pqg.GenerateRandomWithKeySize(m_rng, modLen); OutputData(output, "P ", pqg.GetModulus());
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -